---
phase: 01-foundation
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - packages/branding/package.json
  - packages/branding/tsconfig.json
  - packages/branding/src/index.ts
  - packages/branding/src/vocab.ts
  - packages/branding/src/vocab.test.ts
  - packages/branding/vitest.config.ts
  - vitest.config.ts
autonomous: true
requirements: [FOUND-01]

must_haves:
  truths:
    - "import { VOCAB } from '@paperclipai/branding' resolves and returns an object with all required vocabulary keys"
    - "VOCAB.company equals 'Workspace', VOCAB.ceo equals 'Project Manager', VOCAB.appName equals 'Nexus'"
    - "Unit tests pass confirming every VOCAB key has the correct string value"
  artifacts:
    - path: "packages/branding/package.json"
      provides: "Workspace package definition"
      contains: "@paperclipai/branding"
    - path: "packages/branding/src/vocab.ts"
      provides: "VOCAB constant with all display strings"
      exports: ["VOCAB", "VocabKey"]
    - path: "packages/branding/src/index.ts"
      provides: "Package barrel export"
      exports: ["VOCAB", "VocabKey"]
    - path: "packages/branding/src/vocab.test.ts"
      provides: "Unit tests for VOCAB shape and values"
      min_lines: 20
  key_links:
    - from: "packages/branding/src/index.ts"
      to: "packages/branding/src/vocab.ts"
      via: "re-export"
      pattern: "export.*from.*vocab"
    - from: "vitest.config.ts"
      to: "packages/branding"
      via: "projects array entry"
      pattern: "packages/branding"
---

<objective>
Create the `packages/branding/` workspace package that centralizes all Nexus fork-specific display strings in a single `VOCAB` constant. This is the string mutation surface that all downstream phases (2, 3, 4) will import from.

Purpose: Isolate all Nexus vocabulary from upstream Paperclip code so that rebase operations never conflict on display strings.
Output: A working, tested `@paperclipai/branding` package importable by any workspace member.
</objective>

<execution_context>
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/01-foundation/01-RESEARCH.md
</context>

<interfaces>
<!-- Reference package pattern from packages/shared/ — executor should replicate this structure -->

From packages/shared/package.json:
```json
{
  "name": "@paperclipai/shared",
  "version": "0.3.1",
  "license": "MIT",
  "type": "module",
  "exports": {
    ".": "./src/index.ts",
    "./*": "./src/*.ts"
  },
  "publishConfig": {
    "access": "public",
    "exports": {
      ".": {
        "types": "./dist/index.d.ts",
        "import": "./dist/index.js"
      },
      "./*": {
        "types": "./dist/*.d.ts",
        "import": "./dist/*.js"
      }
    },
    "main": "./dist/index.js",
    "types": "./dist/index.d.ts"
  },
  "files": ["dist"],
  "scripts": {
    "build": "tsc",
    "clean": "rm -rf dist",
    "typecheck": "tsc --noEmit"
  }
}
```

From packages/shared/tsconfig.json:
```json
{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": "src"
  },
  "include": ["src"]
}
```

From vitest.config.ts (root):
```typescript
import { defineConfig } from "vitest/config";
export default defineConfig({
  test: {
    projects: ["packages/db", "packages/adapters/opencode-local", "server", "ui", "cli"],
  },
});
```

From pnpm-workspace.yaml (confirms packages/* glob):
```yaml
packages:
  - packages/*
  - packages/adapters/*
  - packages/plugins/*
  - packages/plugins/examples/*
  - server
  - ui
  - cli
```
</interfaces>

<tasks>

<task type="auto" tdd="true">
  <name>Task 1: Scaffold branding package and write VOCAB constant with tests</name>
  <files>
    packages/branding/package.json,
    packages/branding/tsconfig.json,
    packages/branding/src/vocab.ts,
    packages/branding/src/vocab.test.ts,
    packages/branding/src/index.ts,
    packages/branding/vitest.config.ts
  </files>
  <read_first>
    /Volumes/UsbNvme/repos/nexus/packages/shared/package.json,
    /Volumes/UsbNvme/repos/nexus/packages/shared/tsconfig.json,
    /Volumes/UsbNvme/repos/nexus/packages/shared/src/index.ts,
    /Volumes/UsbNvme/repos/nexus/pnpm-workspace.yaml
  </read_first>
  <behavior>
    - Test: VOCAB has key "company" with value "Workspace"
    - Test: VOCAB has key "companies" with value "Workspaces"
    - Test: VOCAB has key "ceo" with value "Project Manager"
    - Test: VOCAB has key "board" with value "Owner"
    - Test: VOCAB has key "hire" with value "Add"
    - Test: VOCAB has key "fire" with value "Remove"
    - Test: VOCAB has key "appName" with value "Nexus"
    - Test: VOCAB has key "tagline" with value "Open-source orchestration for your agents"
    - Test: VocabKey type is exported (TypeScript compilation succeeds)
    - Test: All VOCAB values are non-empty strings
  </behavior>
  <action>
    1. Create `packages/branding/package.json` following the `packages/shared/package.json` pattern exactly:
       - `"name": "@paperclipai/branding"` (keep @paperclipai scope per upstream sync constraint)
       - `"version": "0.1.0"`
       - `"license": "MIT"`
       - `"type": "module"`
       - `"exports": { ".": "./src/index.ts", "./*": "./src/*.ts" }`
       - `"publishConfig"` with dist paths matching shared pattern
       - `"files": ["dist"]`
       - `"scripts": { "build": "tsc", "clean": "rm -rf dist", "typecheck": "tsc --noEmit" }`
       - `"devDependencies": { "typescript": "^5.7.3" }` — no runtime dependencies

    2. Create `packages/branding/tsconfig.json`:
       ```json
       {
         "extends": "../../tsconfig.base.json",
         "compilerOptions": {
           "outDir": "dist",
           "rootDir": "src"
         },
         "include": ["src"]
       }
       ```

    3. Create `packages/branding/vitest.config.ts`:
       ```typescript
       import { defineConfig } from "vitest/config";
       export default defineConfig({
         test: {
           include: ["src/**/*.test.ts"],
         },
       });
       ```

    4. Create `packages/branding/src/vocab.ts` with the VOCAB constant:
       ```typescript
       export const VOCAB = {
         // Entity renames (display only — code identifiers unchanged)
         company: "Workspace",
         companies: "Workspaces",
         ceo: "Project Manager",
         board: "Owner",
         hire: "Add",
         fire: "Remove",

         // Brand name
         appName: "Nexus",
         tagline: "Open-source orchestration for your agents",
       } as const;

       export type VocabKey = keyof typeof VOCAB;
       ```

    5. Create `packages/branding/src/index.ts`:
       ```typescript
       export { VOCAB, type VocabKey } from "./vocab.js";
       ```

    6. Create `packages/branding/src/vocab.test.ts` — RED first (write tests before verifying they pass):
       ```typescript
       import { describe, it, expect } from "vitest";
       import { VOCAB } from "./vocab.js";

       describe("VOCAB", () => {
         it("maps company to Workspace", () => {
           expect(VOCAB.company).toBe("Workspace");
         });
         it("maps companies to Workspaces", () => {
           expect(VOCAB.companies).toBe("Workspaces");
         });
         it("maps ceo to Project Manager", () => {
           expect(VOCAB.ceo).toBe("Project Manager");
         });
         it("maps board to Owner", () => {
           expect(VOCAB.board).toBe("Owner");
         });
         it("maps hire to Add", () => {
           expect(VOCAB.hire).toBe("Add");
         });
         it("maps fire to Remove", () => {
           expect(VOCAB.fire).toBe("Remove");
         });
         it("has appName as Nexus", () => {
           expect(VOCAB.appName).toBe("Nexus");
         });
         it("has a non-empty tagline", () => {
           expect(VOCAB.tagline).toBe("Open-source orchestration for your agents");
         });
         it("all values are non-empty strings", () => {
           for (const [key, value] of Object.entries(VOCAB)) {
             expect(typeof value).toBe("string");
             expect(value.length).toBeGreaterThan(0);
           }
         });
       });
       ```

    7. Run `pnpm install` from repo root to link the new workspace package.

    8. Run tests to confirm GREEN: `pnpm vitest run --project packages/branding`
  </action>
  <verify>
    <automated>cd /Volumes/UsbNvme/repos/nexus && pnpm vitest run --project packages/branding</automated>
  </verify>
  <acceptance_criteria>
    - packages/branding/package.json contains `"name": "@paperclipai/branding"`
    - packages/branding/package.json contains `"type": "module"`
    - packages/branding/package.json contains `"exports"`
    - packages/branding/src/vocab.ts contains `export const VOCAB`
    - packages/branding/src/vocab.ts contains `as const`
    - packages/branding/src/vocab.ts contains `company: "Workspace"`
    - packages/branding/src/vocab.ts contains `ceo: "Project Manager"`
    - packages/branding/src/vocab.ts contains `appName: "Nexus"`
    - packages/branding/src/vocab.ts contains `export type VocabKey`
    - packages/branding/src/index.ts contains `export { VOCAB`
    - packages/branding/src/vocab.test.ts contains `describe("VOCAB"`
    - packages/branding/tsconfig.json contains `extends": "../../tsconfig.base.json"`
    - `pnpm vitest run --project packages/branding` exits 0 with all tests passing
  </acceptance_criteria>
  <done>
    All 9 VOCAB tests pass. Package exports VOCAB and VocabKey. Package is linked in pnpm workspace.
  </done>
</task>

<task type="auto">
  <name>Task 2: Register branding package in root vitest config</name>
  <files>vitest.config.ts</files>
  <read_first>
    /Volumes/UsbNvme/repos/nexus/vitest.config.ts
  </read_first>
  <action>
    Edit `vitest.config.ts` at the repo root to add `"packages/branding"` to the `projects` array:

    ```typescript
    import { defineConfig } from "vitest/config";

    export default defineConfig({
      test: {
        projects: ["packages/db", "packages/adapters/opencode-local", "server", "ui", "cli", "packages/branding"],
      },
    });
    ```

    The only change is appending `"packages/branding"` to the end of the existing `projects` array.

    After editing, run `pnpm vitest run --project packages/branding` to confirm the root config picks up the new project.
  </action>
  <verify>
    <automated>cd /Volumes/UsbNvme/repos/nexus && pnpm vitest run --project packages/branding</automated>
  </verify>
  <acceptance_criteria>
    - vitest.config.ts contains `"packages/branding"` in the projects array
    - `pnpm vitest run --project packages/branding` exits 0
  </acceptance_criteria>
  <done>
    Root vitest config includes branding package. Running `pnpm vitest run --project packages/branding` from root succeeds.
  </done>
</task>

</tasks>

<verification>
1. `pnpm vitest run --project packages/branding` — all VOCAB tests pass
2. `node -e "const b = await import('./packages/branding/src/index.ts'); console.log(b.VOCAB.appName)"` — prints "Nexus" (requires tsx or similar TS runner)
3. `test -f packages/branding/package.json && echo OK` — package.json exists
</verification>

<success_criteria>
- `@paperclipai/branding` package exists at `packages/branding/`
- `VOCAB` constant exports 8 keys: company, companies, ceo, board, hire, fire, appName, tagline
- All values are correct Nexus display strings
- Unit tests pass via vitest
- Package is registered in root vitest config
</success_criteria>

<output>
After completion, create `.planning/phases/01-foundation/01-01-SUMMARY.md`
</output>
