cipher-type-planner

작성자: bitwarden

Bitwarden 클라이언트 모노레포 전반에 걸쳐 암호화 유형(볼트 항목 유형)의 생성 또는 수정을 계획합니다. 사용자가 새로운 항목을 추가하려고 할 때 이 스킬을 사용하세요.

npx skills add https://github.com/bitwarden/clients --skill cipher-type-planner

Cipher Type Planner

Workflow

Step 1: Gather Requirements

Ask the user the following questions (use AskUserQuestion). Adapt questions based on what the user has already provided.

Required questions:

  1. Type name and value - What is the cipher type name and integer value? If the user hasn't specified a value, determine the next available integer by reading the CipherType enum definition.
  2. Fields - What are the cipher's properties? Each property must contain:
    • Field name
    • Data type (string, number, boolean)
    • Encryption required?
    • Required
  3. Target client ($0) - Which client should this plan focus on? (web, desktop, browser, cli, or all). Shared library changes (libs/common, libs/vault) are always included; $0 controls which apps/* files appear. Skip if already provided as an argument. Default: all.
  4. Autofill - Should this type participate in browser autofill? (Currently only Login, Card, and Identity support autofill.) Only ask if $0 is browser or all.
  5. Linked fields - Should this type support linked custom fields? If yes, which properties should be linkable?
  6. Feature flag - What is the feature flag name?
  7. Prerequisites - Have all server and SDK prerequisites been completed? Do not proceed with the plan until the user confirms these are done.

Additional questions:

Ask each of the following. If the engineer does not have an answer, accept "N/A" or "not yet decided" and note it as a gap in the plan.

  • Import/export - Should import/export support be included in this plan?
  • UI details - Are there specific UI requirements for the form or view sections (e.g., dropdowns, masked fields, copy buttons)?
  • Subtitle - What value should the subTitle getter on the view model return? This appears in vault list items.
  • Icon - What icon represents this type in the vault? Bitwarden uses bwi- icon classes.
  • Organization policy - Does this type appear in the restricted item types policy UI?

Step 2: Enter Plan Mode

After gathering requirements, enter plan mode using EnterPlanMode. Explore the codebase to verify current patterns and file locations. Use the SshKey cipher type (value 5) as the canonical reference for implementation patterns.

Key files to inspect for patterns:

  • libs/common/src/vault/enums/cipher-type.ts - Enum definition
  • libs/common/src/vault/models/api/ssh-key.api.ts - API model pattern
  • libs/common/src/vault/models/data/ssh-key.data.ts - Data model pattern
  • libs/common/src/vault/models/domain/ssh-key.ts - Domain model pattern
  • libs/common/src/vault/models/view/ssh-key.view.ts - View model pattern
  • libs/common/src/models/export/ssh-key.export.ts - Export model pattern
  • libs/common/src/vault/models/domain/cipher.ts - Container switch patterns
  • libs/vault/src/cipher-form/components/sshkey-section/ - Form component pattern
  • libs/vault/src/cipher-view/sshkey-sections/ - View component pattern

Step 3: Build the Plan

Write a comprehensive plan to the plan file. The plan MUST include all sections below.


Plan Output Format

1. Overview

  • Cipher type name:
  • Integer value:
  • Feature flag:
  • Minimum client version:
  • Fields: Table of all fields with name, type, encrypted (yes/no), required (yes/no)
  • Supports autofill: Yes/No
  • Supports linked fields: Yes/No

2. Clients - New Files to Create

List every file that needs to be created, with the full path and a brief description. Organize by layer:

Model stack:

  • libs/common/src/vault/models/api/<type>.api.ts - API response shape
  • libs/common/src/vault/models/data/<type>.data.ts - Serializable storage format
  • libs/common/src/vault/models/domain/<type>.ts - Encrypted business object
  • libs/common/src/vault/models/domain/<type>.spec.ts - Domain model tests
  • libs/common/src/vault/models/view/<type>.view.ts - Decrypted view for UI

Export (if import/export is included):

  • libs/common/src/models/export/<type>.export.ts - Export model

UI components:

  • libs/vault/src/cipher-form/components/<type>-section/ - Form section component (TS, HTML, spec)
  • libs/vault/src/cipher-view/<type>-sections/ - View section component (TS, HTML)

3. Clients - Existing Files to Modify

List every file that needs modification, organized by concern. For each file, describe the specific change needed.

Core enum:

  • libs/common/src/vault/enums/cipher-type.ts - Add <Type>: <N> to CipherType
  • libs/common/src/vault/enums/cipher-type.spec.ts - Update tests

Container switches (add case for new type):

  • libs/common/src/vault/models/data/cipher.data.ts - Constructor
  • libs/common/src/vault/models/domain/cipher.ts - Constructor, decrypt(), toCipherData(), fromJSON(), toSdkCipher(), fromSdkCipher()
  • libs/common/src/vault/models/view/cipher.view.ts - item getter, fromJSON(), fromSdkCipherView(), getSdkCipherViewType(), toSdkCipherView()
  • libs/common/src/vault/models/request/cipher.request.ts - Constructor
  • libs/common/src/vault/models/response/cipher.response.ts - Constructor
  • libs/common/src/vault/services/cipher.service.ts - encryptCipherData()

Export (if import/export is included):

  • libs/common/src/models/export/cipher.export.ts - toView(), toDomain(), build()

SDK integration:

  • libs/common/src/vault/models/domain/cipher-sdk-mapper.ts - Record mapper
  • Domain and view model SDK methods (toSdk*/fromSdk*)

UI wiring:

  • libs/vault/src/cipher-form/components/cipher-form.component.ts - Import and wire section
  • libs/vault/src/cipher-form/components/cipher-form.component.html - Add section template
  • libs/vault/src/cipher-view/cipher-view.component.ts - Import and wire section
  • libs/vault/src/cipher-view/cipher-view.component.html - Add section template
  • libs/common/src/vault/icon/build-cipher-icon.ts - Add icon case

Vault filters (CRITICAL — without these, ciphers won't appear in the vault list):

All vault filter files must be feature-flag-gated so the new type only appears when the flag is enabled. Use ConfigService.getFeatureFlag$() with combineLatest to filter the type out of arrays when the flag is off.

Always included (shared):

  • libs/vault/src/services/vault-filter.service.ts - CRITICAL: Add type to buildCipherTypeTree() allTypeFilters array. Without this, ciphers of the new type will not appear in the vault sidebar or list.
  • libs/vault/src/models/filter-function.ts - Add filter case for the new type
  • libs/angular/src/vault/components/vault-items.component.ts - Feature-flag-gate empty state type buttons

Include if $0 is web or all:

  • apps/web/src/app/vault/individual-vault/vault-filter/components/vault-filter.component.ts - Add to allTypeFilters, searchPlaceholder, and feature-flag-gate in buildAllFilters()
  • apps/web/src/app/admin-console/organizations/collections/vault-filter/vault-filter.component.ts - Feature-flag-gate in buildAllFilters()

Include if $0 is desktop or all:

  • apps/desktop/src/vault/app/vault-v3/vault-filter/filters/type-filter.component.ts - Add ConfigService, combineLatest with feature flag

Include if $0 is browser or all:

  • apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts - Add ConfigService, feature-flag-gate cipherTypes

New item menus (feature-flag-gated):

Always included (shared):

  • libs/common/src/vault/types/cipher-menu-items.ts - Add menu item entry for new type
  • libs/vault/src/components/new-cipher-menu/new-cipher-menu.component.ts - Add canCreate<Type> = input(false) signal, gate in cipherMenuItems observable

Include if $0 is web or all:

  • apps/web/src/app/vault/individual-vault/vault-header/vault-header.component.ts - Add canCreate<Type>$ observable from feature flag
  • apps/web/src/app/vault/individual-vault/vault-header/vault-header.component.html - Bind [canCreate<Type>] to <vault-new-cipher-menu>

Include if $0 is browser or all:

  • apps/browser/src/vault/popup/components/vault/new-item-dropdown/new-item-dropdown.component.ts - Add ConfigService, combineLatest with feature flag

Localization (add i18n keys):

Include only locale files for $0. If $0 is all, include all three:

  • apps/web/src/locales/en/messages.json (web)
  • apps/desktop/src/locales/en/messages.json (desktop)
  • apps/browser/src/_locales/en/messages.json (browser)

Linked fields (if applicable):

  • libs/common/src/vault/enums/linked-id-type.enum.ts

Autofill (if applicable — only if $0 is browser or all):

  • List relevant autofill files from apps/browser/src/autofill/ only if the type supports autofill

Restricted item types (if applicable):

Restricted item type enforcement is used across all clients. Include files for $0:

Always included (shared):

  • libs/common/src/vault/services/vault-settings/vault-settings.service.ts - Restricted types service

Include if $0 is web or all:

  • apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/restricted-item-types.component.ts - Policy configuration UI
  • apps/web/src/app/admin-console/organizations/policies/policy-edit-definitions/restricted-item-types.component.html

Include if $0 is browser or all:

  • apps/browser/src/vault/popup/components/vault/item-more-options/item-more-options.component.ts - Restricted type checks

Include if $0 is cli or all:

  • apps/cli/src/vault/create.command.ts - Restricted type checks
  • apps/cli/src/commands/list.command.ts - Restricted type checks
  • apps/cli/src/commands/get.command.ts - Restricted type checks

4. Localization Keys

List all i18n keys that need to be added. At minimum:

  • Type label
  • Field labels for each type-specific field

5. Tests

List all test files that need to be created or updated:

  • libs/common/src/vault/enums/cipher-type.spec.ts
  • libs/common/src/vault/models/domain/cipher.spec.ts
  • libs/common/src/vault/models/domain/<type>.spec.ts (new)
  • libs/common/src/vault/models/view/cipher.view.spec.ts
  • libs/common/src/vault/services/cipher.service.spec.ts
  • libs/common/src/vault/services/cipher-sdk.service.spec.ts
  • libs/common/src/vault/icon/build-cipher-icon.spec.ts
  • libs/common/src/models/export/cipher.export.spec.ts
  • libs/vault/src/cipher-form/components/cipher-form.component.spec.ts
  • libs/vault/src/cipher-view/cipher-view.component.spec.ts
  • Form section component spec (new)

6. Recommended Implementation Order

Recommended implementation order, customized for this specific type. Only include steps relevant to $0 (shared steps are always included):

  1. Core enum addition (shared)
  2. Feature flag registration (shared)
  3. Model stack (API, Data, Domain, View, Export if applicable) (shared)
  4. Container switch updates (shared)
  5. SDK bindings (toSdk*/fromSdk*) (shared)
  6. Localization keys ($0)
  7. Shared UI (icon, menu items) (shared)
  8. Vault filters with feature flag gating — CRITICAL for ciphers to appear (shared + $0)
  9. New item menus with feature flag gating (shared + $0)
  10. Per-app UI (form section, view section) (shared)
  11. Context menu / copy actions — see Section 8 (shared + $0)
  12. CLI (only if $0 is cli or all)
  13. Autofill (only if $0 is browser or all)
  14. Tests (shared + $0)

7. Risks and Considerations

  • Cross-repo coordination requirements
  • Feature flag rollout strategy
  • Backward compatibility concerns
  • Any fields that need special encryption handling (reminder: no new encryption logic in clients)
  • Performance considerations for large vaults
  • i18n key reuse - Before adding new locale keys, check whether existing keys already have the desired display value. If an existing key has the same message text, reuse it instead of creating a duplicate. Only create new keys when no existing key matches.

8. Context Menu / Copy Actions

Each cipher type can expose copiable fields in the vault list item context menus (right-click / more menu). Include only the sections relevant to $0.

Core Infrastructure (always included)

FileWhat to add
libs/vault/src/services/copy-cipher-field.service.tsAdd field names to the CopyAction type union. Add entries to the CopyActions record with typeI18nKey (i18n key for the toast message), protected (whether it requires password re-prompt), and optional event (for event collection).
libs/common/src/vault/utils/cipher-view-like-utils.tsAdd cases to hasCopyableValue() that check whether the cipher has a non-empty value for each copiable field.

Browser (include if $0 is browser or all)

FileWhat to add
apps/browser/src/vault/popup/components/vault/item-copy-action/item-copy-actions.component.tsAdd a singleCopyable<Type> getter (for single-field quick copy button), a has<Type>Values getter, and a getNumberOf<Type>Values() method. Follow the Card pattern.
apps/browser/src/vault/popup/components/vault/item-copy-action/item-copy-actions.component.htmlAdd a section using @if syntax (NOT *ngIf) with the single/multi field pattern.

Web (include if $0 is web or all)

FileWhat to add
apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.tsAdd is<Type>Cipher and hasVisible<Type>Options getters. Add hasVisible<Type>Options to the showMenuDivider check.
apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.htmlAdd copy buttons using @if syntax with appCopyField directive.

Desktop (include if $0 is desktop or all)

FileWhat to add
apps/desktop/src/vault/app/vault-v3/vault-items/vault-cipher-row.component.tsAdd a CipherType.<Type> case to the copyFields computed signal, returning CopyFieldConfig[] entries. This is the most modern pattern — uses a computed signal rather than getters.

Critical Warnings

  • CLI has no copy menu UI — do not add copy-related i18n keys to the CLI locale.
  • Only expose fields that should be copiable — not every cipher field needs a copy action. Check with product requirements for which fields get copy buttons.

bitwarden의 다른 스킬

analyzing-git-sessions
bitwarden
특정 기간이나 커밋 범위 내의 Git 커밋과 변경 사항을 분석하여 코드 리뷰, 회고, 작업 로그 또는 세션을 위한 구조화된 요약을 제공합니다.
official
figma-to-angular
bitwarden
이 스킬은 Figma 디자인 스펙을 Bitwarden Clients 모노레포 내에서 Storybook 스토리와 함께 완전히 구현된 Angular 컴포넌트로 변환합니다. 출력물은 모든 코드베이스 규칙을 따르면서 시각적으로 디자인과 일치해야 합니다.
official
agent-access
bitwarden
Retrieve login credentials, API keys, and secrets (username, password, TOTP) from the user's Bitwarden vault via aac. Use when you need credentials to sign…
official
action-audit
bitwarden
조직 전반의 GitHub Actions 사용을 감사합니다. 특정 액션을 검색하거나(인시던트 모드) 모든 워크플로 파일을 스캔하여 비준수 액션을 찾습니다…
official
action-remediate
bitwarden
Remediate GitHub Actions action findings identified by the action-audit skill. Applies the appropriate fix per action type — `@main` ref for internal…
official
analyzing-code-security
bitwarden
이 스킬은 사용자가 "코드의 보안 문제를 분석"하거나, "OWASP 취약점을 확인"하거나, "CWE Top 25에 대해 코드를 검토"하도록 요청할 때 사용해야 합니다. "찾…
official
applying-bitwarden-branding
bitwarden
Apply Bitwarden brand standards — logo usage, color palette, typography, iconography, and capitalization rules — grounded in bitwarden.com/brand and the…
official
architecting-solutions
bitwarden
Architecting solutions at the team level while staying coherent with Bitwarden's holistic architecture. Covers security mindset, architectural judgment,…
official