Skip to content
Draft
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d0710d1
Initial commit starting fullstack dev & align plugins with Anthropic …
theMickster Dec 11, 2025
9b8de8b
Fix version boo-boo
theMickster Dec 11, 2025
60f5594
Version mismatch
theMickster Dec 11, 2025
d847042
Refine the C# skill aligning to what is in the market
theMickster Dec 11, 2025
61812c3
Minor refactor of C# skill and added typescript skill
theMickster Dec 12, 2025
edff708
Craft a Rust and a SQL developer skill
theMickster Dec 13, 2025
2ce853e
Merge branch 'main' into ai/bitwarden-software-engineer-agent
theMickster Dec 17, 2025
42ddf68
Complete rewrite of the agent
theMickster Dec 17, 2025
7c4f463
Overhaul other portions to target only Bitwarden specific topics.
theMickster Dec 17, 2025
b55f3fa
Cut the fluffy-McFluffin outta the README.md
theMickster Dec 17, 2025
1485e81
Implement a few Claude + Copilot recommendations in wording. Ran Pret…
theMickster Dec 17, 2025
7651203
Remove architecture wording from skill description
theMickster Dec 17, 2025
22b9a4e
Update plugins/bitwarden-software-engineer/skills/writing-database-qu…
theMickster Dec 29, 2025
355194d
Merge branch 'main' into ai/bitwarden-software-engineer-agent
theMickster Dec 29, 2025
da5f71d
Revert plugin.json changes
theMickster Dec 29, 2025
d764a3f
Remove nx command
theMickster Dec 29, 2025
5321dea
Merge branch 'main' into ai/bitwarden-software-engineer-agent
withinfocus Jan 6, 2026
68898b2
Merge branch 'main' into ai/bitwarden-software-engineer-agent
withinfocus Jan 6, 2026
adfb364
Merge branch 'main' into ai/bitwarden-software-engineer-agent
withinfocus Jan 6, 2026
4647eea
Merge branch 'main' into ai/bitwarden-software-engineer-agent
withinfocus Jan 6, 2026
9e9d061
Merge branch 'main' into ai/bitwarden-software-engineer-agent
withinfocus Jan 6, 2026
8bfd4b6
Merge branch 'main' into ai/bitwarden-software-engineer-agent
withinfocus Jan 6, 2026
1b6070b
Merge branch 'main' into ai/bitwarden-software-engineer-agent
withinfocus Jan 6, 2026
dab205f
Merge branch 'main' into ai/bitwarden-software-engineer-agent
withinfocus Jan 6, 2026
023990f
Merge branch 'main' into ai/bitwarden-software-engineer-agent
withinfocus Jan 7, 2026
aa35c87
Merge branch 'main' into ai/bitwarden-software-engineer-agent
withinfocus Jan 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions plugins/bitwarden-software-engineer/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "bitwarden-software-engineer",
"version": "0.1.0",
"description": "Comprehensive full-stack software engineering assistant proficient in modern software development at Bitwarden.",
"author": {
"name": "Bitwarden",
"url": "https://github.com/bitwarden"
},
"homepage": "https://github.com/bitwarden/ai-plugins/tree/main/plugins/bitwarden-software-engineer",
"repository": "https://github.com/bitwarden/ai-plugins",
"keywords": [
"typescript",
"csharp",
"rust",
"sql",
"fullstack"
],
"agents": ["./agents/bitwarden-software-engineer.md"]
}
3 changes: 3 additions & 0 deletions plugins/bitwarden-software-engineer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Bitwarden Software Engineer Plugin

Claude Code skills for Bitwarden development patterns. Generic AI coding assistance doesn't know our conventions, architecture decisions, or anti-patterns we've learned the hard way. These skills keep Claude focused on how we build software here.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Just found out while experimenting that this should be named AGENT.md.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not technically required. I'm for making it a Bitwarden practice though. We just need to document it somewhere. By default, when using Claude Code to generate a new agent it does not name the file AGENT.md. It uses a descriptive name like pr-knowledge-extractor.md or test-forge-engineer.md, so devs would have to manually rename them when created this way.

name: bitwarden-software-engineer
description: Full-stack software engineer specializing in C#, JavaScript, TypeScript, Rust, and SQL. Coordinates complex development tasks across languages. Use for feature implementation, and cross-language refactoring.
model: sonnet
tools: Read, Write, Edit, Bash, Glob, Grep
color: blue
---

You are a senior full-stack software engineer with expertise across C#, JavaScript, TypeScript, Rust, and SQL. You're an engineer working with the team, not just executing commands. Focus intently on code quality **over** code quantity. You avoid over-engineering because you focus on what's needed, not what might be needed.

## Purpose

Coordinate complex software development tasks that span multiple languages, architectural concerns, or require full-stack reasoning.

## Working Approach

1. **Understand context:** Before creating or modifying code, read the relevant existing files to understand current patterns. Don't assume β€” verify.
2. **Clarify, don't invent.** If requirements are ambiguous or incomplete, ask the human rather than making assumptions. State what you're uncertain about.
3. **Stay in scope.** Implement what was asked. Don't add features, abstractions, or "nice-to-haves" that weren't requested. If you see an improvement opportunity, mention it β€” don't just build it.
4. **Build incrementally, validate continuously.** Start with core functionality, run tests, check for regressions, and confirm the implementation meets requirements before declaring done.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
name: writing-client-code
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ We must be mindful of what's in the various repos instructing and defining these approaches, and eliminate that content in favor of this one at the right time. Have to have one single source of truth, as a skill, here.

description: Bitwarden client code conventions for Angular and TypeScript. Use when working in the clients mono-repo, creating components, services, or modifying web/browser/desktop apps.
tools: Read, Write, Edit, Bash, Glob, Grep
---

## Repository Structure

The `clients` mono-repo contains:

- `apps/web`, `apps/browser`, `apps/desktop`, `apps/cli` β€” client applications
- `libs/common` β€” shared code for ALL clients including CLI (no Angular dependencies)
- `libs/angular` β€” Angular-specific code for visual clients only
- `libs/components` β€” Angular Component Library

## Angular Requirements

**New components** must use:

- OnPush change detection
- New control flow syntax (`@if`, `@for`, `@switch`)
- Standalone components
- `inject()` function for dependency injection
- Reactive Forms

**Existing components:** Follow the patterns already in the file. Don't migrate `*ngIf` β†’ `@if`, `@Input()` decorators β†’ `input()` signals, or other modernizations unless explicitly asked. Keep changes focused on the task.

**If asked to refactor/migrate:** Then apply modern patterns to the files in scope β€” but don't expand to "while we're here" refactors in other files.

## Component Patterns

**Thin components:** Components contain only view logic. Business logic belongs in services.

**Composition over inheritance:** Avoid extending components across clients. Compose using shared child components.

**Cross-client services** (in `libs/common`): Use abstract classes as interfaces β€” CLI uses Node, not Angular DI. Implementation prefixes: `Default*`, `Web*`, `Browser*`, `Desktop*`, `Cli*`.

## File Naming

Dashes for words, dots for types:

- `folder.service.ts` β†’ `FolderService`
- `folder-list.component.ts` β†’ `FolderListComponent`
- `folder.view.ts` β†’ `FolderView`
- `cipher-type.enum.ts` β†’ `CipherType` (const object, not enum)

## TypeScript Rules

**No enums.** Use frozen const objects with `Object.freeze()` and `as const`. Always explicitly type variables using the derived type.

**Imports:**

- Within same package (`@bitwarden/common`): relative imports
- Across packages: absolute imports (`@bitwarden/common/platform/...`)

## State Management

| Context | Use |
| ----------------------------------- | ------- |
| Component local state | Signals |
| Angular-only services | Signals |
| Cross-client services (libs/common) | RxJS |

**Avoid manual subscriptions.** Prefer `| async` pipe. When subscriptions are necessary, pipe through `takeUntilDestroyed()` β€” enforced by `prefer-takeUntil` lint rule.

## Styling

All Tailwind classes require **`tw-` prefix**:

```html
<div class="tw-bg-background-alt2 tw-p-4">
<!-- βœ… -->
<div class="bg-background-alt2 p-4"><!-- ❌ --></div>
</div>
```

Use Component Library (`libs/components/`) for common UI patterns.

## Testing

Use Jest with `jest-mock-extended`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
name: writing-database-queries
description: Bitwarden database queries, stored procedures, and migrations. Use when working with .sql files, stored procedures, EF migrations, or database schema changes.
tools: Read, Write, Edit, Bash, Glob, Grep
---

## Repository Architecture
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Same comment again, but the docs site or in-repo code should have these things. The two monorepos for frontend and backend do take on a lot of what a "Bitwarden software engineer" does on many days and something like a migration is specific to the latter, so it should be there. Generally though, such as literally" writing database queries" is more open-ended and could apply to many repositories.


MSSQL uses Dapper with stored procedures. All other databases (PostgreSQL, MySQL, SQLite) use Entity Framework Core. Every database change requires both implementations.

- Dapper: `Repository Method β†’ Stored Procedure β†’ View (for reads)`
- EF: `Repository Method β†’ DbContext β†’ Generated SQL`

Repository interfaces abstract both. When a stored procedure performs specific operations, the EF implementation must replicate identical behavior.

## Migration Workflow (Evolutionary Database Design)

Zero-downtime deployments require three-phase migrations:

**Phase 1 β€” Initial** (`util/Migrator/DbScripts`): Runs before code deployment. Must be fast, backwards-compatible. Adds support for new features without breaking current release.

**Phase 2 β€” Transition** (`util/Migrator/DbScripts_transition`): Runs after deployment as background task. Handles slow data migrations. Must be batched. NO schema changes.

**Phase 3 β€” Finalization** (`util/Migrator/DbScripts_finalization`): Runs at next release. Removes backwards-compatibility scaffolding.

Other locations:

- `src/Sql/dbo` β€” Master schema source of truth
- `src/Sql/dbo_finalization` β€” Future schema state
- `util/Migrator/DbScripts_manual` β€” Exceptional cases (index rebuilds)

## Migration Naming

MSSQL: `YYYY-MM-DD_##_MigrationName.sql` (e.g., `2024-01-15_00_AddUserColumn.sql`)

Finalization: `YYYY-0M-FinalizationMigration.sql`

EF migration class names must exactly match the MSSQL migration name portion.

Generate EF migrations: `pwsh ef_migrate.ps1 <MigrationName>`

Apply migrations: `pwsh migrate.ps1 -all` (all databases) or `pwsh migrate.ps1` (MSSQL only)

## All Migrations Must Be Idempotent

```sql
-- Tables
IF OBJECT_ID('[dbo].[TableName]') IS NULL
BEGIN
CREATE TABLE [dbo].[TableName] (...)
END
GO

-- Columns
IF COL_LENGTH('[dbo].[TableName]', 'ColumnName') IS NULL
BEGIN
ALTER TABLE [dbo].[TableName]
ADD [ColumnName] INT NOT NULL CONSTRAINT DF_Table_Column DEFAULT 0
END
GO

-- Procedures: always use CREATE OR ALTER
CREATE OR ALTER PROCEDURE [dbo].[Entity_Action]
```

## Testing

Use `[DatabaseData]` attribute to run tests against all configured databases:

```csharp
[Theory, DatabaseData]
public async Task TestMethod(IOrganizationRepository repo)
{
// Runs for MSSQL/Dapper, Postgres/EF, MySQL/EF, SQLite/EF
}
```

For migration testing, use `MigrationName` parameter matching both SQL file suffix and EF class name.

Use separate test databases (`vault_test`) from development (`vault_dev`).

## Database-Specific Guidance

For T-SQL patterns (MSSQL, stored procedures, Dapper), read [guides/tsql.md](guides/tsql.md).

For Entity Framework patterns (PostgreSQL, MySQL, SQLite, EF migrations), read [guides/entity-framework.md](guides/entity-framework.md).
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Entity Framework Guide

Entity Framework (EF) is used for PostgreSQL, MySQL, MariaDB, and SQLite. The Dapper ORM is used for MSSQL.

## Generating Migrations

```powershell
pwsh ef_migrate.ps1 <MigrationName>
```

Creates migrations for all EF targets simultaneously.

## Key Differences from MSSQL

- Queries working against MySQL may fail against Postgres (e.g., Postgres doesn't support `Min` on boolean values)
- Always run integration tests with `[DatabaseData]` rather than manually testing each database
- EF implementation must replicate exact behavior of corresponding stored procedures

## Testing

```csharp
[Theory, DatabaseData]
public async Task TestMethod(IOrganizationRepository repo)
{
// Automatically runs against all configured EF databases
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# T-SQL Guide
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎨 Per your other guide, this is meant to be ORM-focused right? So we'd write this with a Dapper mindset, but still include the T-SQL references which it uses.


## Stored Procedure Naming
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ In the case of SQL at least we have some really good coverage of this at https://contributing.bitwarden.com/contributing/code-style/sql. This plus any other skills / guides here would benefit from reaching out to the relevant page to get the implementation details, as we need the style guides there for engineering in general. Will that be an issue? I don't want to duplicate content.

This comment applies in several other places. My understanding is these guides document approach and rationale, but we should have the actual "how" in close-to-code or the docs site; traditionally I'd want just the former but these are company-wide and can't be just in individual repos.


Use `{Entity}_{Action}[_Descriptor]` pattern:

| Operation | Pattern | Example |
| ---------------- | ----------------------------- | ------------------------------ |
| Create | `Entity_Create` | `User_Create` |
| Read single | `Entity_ReadById` | `Organization_ReadById` |
| Read by criteria | `Entity_ReadBy{Criteria}` | `User_ReadByEmail` |
| Read many | `Entity_ReadManyBy{Criteria}` | `Cipher_ReadManyByUserId` |
| Update | `Entity_Update` | `User_Update` |
| Delete | `Entity_DeleteById` | `Cipher_Delete` |
| Soft delete | `Entity_SoftDelete` | `Cipher_SoftDelete` |
| Special | `Entity_{ActionDescription}` | `User_BumpAccountRevisionDate` |

## Procedure Structure

```sql
CREATE OR ALTER PROCEDURE [dbo].[Entity_Action]
@Id UNIQUEIDENTIFIER,
@OptionalParam NVARCHAR(50) = NULL -- Nullable default for backwards compatibility
AS
BEGIN
SET NOCOUNT ON
-- Logic here
END
GO
```

## Code Style

- Keywords: `UPPERCASE`
- Objects: Square brackets β€” `[dbo].[TableName]`, `[ColumnName]`
- Tables/Columns: PascalCase
- Parameters: `@PascalCase`
- Constraints: `PK_{Table}`, `FK_{Table}_{RefTable}`, `DF_{Table}_{Column}`, `IX_{Table}_{Columns}`

Standard columns:

```sql
[Id] UNIQUEIDENTIFIER NOT NULL
[CreationDate] DATETIME2(7) NOT NULL
[RevisionDate] DATETIME2(7) NOT NULL
```

## Anti-Patterns to Avoid

### Index creation on large tables

Creating indexes on `dbo.Cipher`, `dbo.OrganizationUser`, or other large tables can cause outages. Never specify `ONLINE = ON` in scripts β€” production handles this automatically, and the option fails on unsupported SQL Server editions.

### NOT NULL columns done wrong

```sql
-- BAD: Full table scan
ALTER TABLE [dbo].[Table] ADD [Column] INT NULL
UPDATE [dbo].[Table] SET [Column] = 0
ALTER TABLE [dbo].[Table] ALTER COLUMN [Column] INT NOT NULL

-- GOOD: Metadata-only operation
ALTER TABLE [dbo].[Table]
ADD [Column] INT NOT NULL CONSTRAINT DF_Table_Column DEFAULT 0
```

### Defaults on string types

Use defaults only for numeric types (`BIT`, `TINYINT`, `INT`, `BIGINT`). Never use defaults for `VARCHAR`, `NVARCHAR`, or MAX types.

### Missing view metadata refresh

After modifying tables, refresh views:

```sql
EXECUTE sp_refreshview N'[dbo].[ViewName]'
GO
```

After altering views, refresh dependent procedures:

```sql
IF OBJECT_ID('[dbo].[ProcName]') IS NOT NULL
EXECUTE sp_refreshsqlmodule N'[dbo].[ProcName]'
GO
```

## Backwards Compatibility

New parameters must have nullable defaults:

```sql
@NewParameter DATATYPE = NULL
```

When renaming columns during EDD transition:

```sql
SET @FirstName = COALESCE(@FirstName, @FName);
```
Loading