@apogeelabs/the-agency 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apogeelabs/the-agency",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Centralized Claude Code agents, commands, and workflows",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,9 +10,9 @@ Before generating any tests, complete these steps in order:
10
10
 
11
11
  1. **Branch analysis** (Coverage-Driven Test Planning): Read the source, enumerate every branch, map each to a test scenario.
12
12
  2. **Superfluous test check** (Superfluous Test Prevention): Verify each planned scenario covers a distinct branch, not the same branch with different values.
13
- 3. **Execution location check** (CRITICAL RULE #1): Execute methods under test in `beforeEach()`, not in `it()` blocks.
14
- 4. **Mock configuration check** (CRITICAL RULE #2): Configure mock behavior in `beforeEach`, not at module level.
15
- 5. **Callback invocation check** (CRITICAL RULE #3): Use `mockImplementation` for callbacks, not `mock.calls[N][M]()`.
13
+ 3. **Execution location check** (CRITICAL RULE 1): Execute methods under test in `beforeEach()`, not in `it()` blocks.
14
+ 4. **Mock configuration check** (CRITICAL RULE 2): Configure mock behavior in `beforeEach`, not at module level.
15
+ 5. **Callback invocation check** (CRITICAL RULE 3): Use `mockImplementation` for callbacks, not `mock.calls[N][M]()`.
16
16
 
17
17
  Once tests are generated:
18
18
 
@@ -21,7 +21,7 @@ Once tests are generated:
21
21
 
22
22
  ---
23
23
 
24
- ## CRITICAL RULE #1: Test Execution Location
24
+ ## CRITICAL RULE 1: Test Execution Location
25
25
 
26
26
  ⚠️ **NON-NEGOTIABLE RULE** ⚠️
27
27
 
@@ -97,7 +97,7 @@ Before writing any test suite, verify:
97
97
 
98
98
  ---
99
99
 
100
- ## CRITICAL RULE #2: Mock Configuration Location
100
+ ## CRITICAL RULE 2: Mock Configuration Location
101
101
 
102
102
  ⚠️ **NON-NEGOTIABLE RULE** ⚠️
103
103
 
@@ -152,7 +152,7 @@ const mockLuxon = {
152
152
 
153
153
  ---
154
154
 
155
- ## CRITICAL RULE #3: Callback Invocation via mockImplementation
155
+ ## CRITICAL RULE 3: Callback Invocation via mockImplementation
156
156
 
157
157
  ⚠️ **NON-NEGOTIABLE RULE** ⚠️
158
158
 
@@ -329,7 +329,7 @@ describe("when status is inactive", () => {
329
329
  - Inner `describe` blocks handle specific scenarios ("when X condition")
330
330
  - **Test descriptions**:
331
331
  - `describe` blocks handle the "when" conditions/scenarios
332
- - `it` blocks focus purely on "should" assertions (no conditions). See **CRITICAL RULE #1** above.
332
+ - `it` blocks focus purely on "should" assertions (no conditions). See **CRITICAL RULE 1** above.
333
333
  - Avoid redundancy - don't repeat conditions in both `describe` and `it`
334
334
  - **Grouping logic**:
335
335
  - Group related test cases under shared setup scenarios
@@ -366,7 +366,7 @@ describe("when status is inactive", () => {
366
366
  - **State initialization**: Variables initialized in `beforeEach`
367
367
  - **Fresh state guarantee**:
368
368
  - Call `jest.clearAllMocks()` and `jest.resetModules()` in outer `beforeEach`
369
- - **Do NOT use `jest.resetAllMocks()`** in the outer `beforeEach` — it wipes implementations, which breaks module-level `mockReturnThis()` chains (see CRITICAL RULE #2 exception)
369
+ - **Do NOT use `jest.resetAllMocks()`** in the outer `beforeEach` — it wipes implementations, which breaks module-level `mockReturnThis()` chains (see CRITICAL RULE 2 exception)
370
370
  - Use `mockReset()` on **individual mocks** when a nested `beforeEach` needs to replace behavior already configured by an outer `beforeEach`
371
371
  - **Never use `mockRestore()`** — it only applies to `jest.spyOn`, which this codebase does not use
372
372
 
@@ -385,14 +385,14 @@ Am I in the **outer** `beforeEach`?
385
385
 
386
386
  ## Mocking Strategy
387
387
 
388
- - **Module-level mock declarations**: Dependencies mocked above test suites with bare `jest.fn()` — see **CRITICAL RULE #2** for configuration rules
388
+ - **Module-level mock declarations**: Dependencies mocked above test suites with bare `jest.fn()` — see **CRITICAL RULE 2** for configuration rules
389
389
  - **Mock behavior configuration**: Configured per scenario in `beforeEach` blocks
390
390
  - **Mock naming**: Consistent mock prefix (e.g., `mockLogger`, `mockGetMessageBroker`)
391
391
  - **Selective mocking**: Mock only the methods being used unless it significantly raises complexity
392
392
  - **Mock verification**: Always verify mock calls when behavior depends on them
393
393
  - **Mock realism**: Ensure mocks behave like real implementations (same async patterns, error types)
394
394
  - **Mock methods**:
395
- - Use `mockImplementation` when invoking callbacks passed to the mocked function — see **CRITICAL RULE #3**
395
+ - Use `mockImplementation` when invoking callbacks passed to the mocked function — see **CRITICAL RULE 3**
396
396
  - Use `mockResolvedValue` for async returns
397
397
  - Use `mockReturnValue` for sync returns
398
398
  - Prefer "Once" versions when appropriate (`mockResolvedValueOnce`, etc.)
@@ -11,6 +11,27 @@ Make this code bulletproof by writing the tests the developer didn't think of. A
11
11
 
12
12
  You have NO knowledge of how this code was written. You are seeing it for the first time. You are NOT rewriting the developer's tests — you're adding what's missing.
13
13
 
14
+ ## Tooling — Non-Negotiable
15
+
16
+ **Use ONLY the repo's established tooling to run and verify tests.** You must discover the repo's conventions before writing or running anything.
17
+
18
+ ### Discovery (do this FIRST, before writing any tests)
19
+
20
+ 1. Read `package.json` (root and any relevant workspace package). Identify the test script — it will be one of `npm test`, `pnpm test`, `yarn test`, or similar. That is your test runner. Period.
21
+ 2. If the repo is a monorepo, identify the workspace tool (`pnpm --filter`, `npm -w`, `yarn workspace`, `turbo run`, `nx run`, etc.) and use that to scope test runs to the relevant package.
22
+ 3. Read the test framework config (e.g., `jest.config.ts`, `vitest.config.ts`, `.mocharc.*`) to understand module resolution, transforms, and path aliases.
23
+ 4. Read `.ai/UnitTestGeneration.md` and `.ai/UnitTestExamples.md` if they exist. These are your style guide. Follow them exactly.
24
+
25
+ ### The Rules
26
+
27
+ - **Run tests with the repo's test script.** `npm test`, `pnpm test`, `pnpm --filter <pkg> test`, etc. Whatever `package.json` says.
28
+ - **DO NOT use `node -e`, `npx tsx`, `npx jest`, `ts-node`, or any ad-hoc command to run, compile, or verify code.** Ever. No exceptions. The repo has a test runner. Use it.
29
+ - **DO NOT improvise test runners or verification methods.** If you're tempted to run something outside the repo's scripts to "quickly check" something, stop. Use the test script.
30
+ - **DO NOT install packages, add dependencies, or modify package.json.** You write tests using what's already available.
31
+ - **When running tests, scope them.** Don't run the entire test suite when you only need to verify one file. Use the test runner's built-in filtering (e.g., `pnpm test -- --testPathPattern=path/to/file` for Jest, or equivalent).
32
+
33
+ If you catch yourself about to type `node -e` or `npx tsx` or anything that isn't the repo's test script, you are doing it wrong. Back away from the keyboard.
34
+
14
35
  ## Input
15
36
 
16
37
  1. Read the build plan from `docs/build-plans/` to understand intended behavior.
@@ -97,12 +118,14 @@ Map every branch (`if`/`else`, `try`/`catch`, `switch`, early returns) in the so
97
118
 
98
119
  ## Process
99
120
 
100
- 1. Audit existing tests. Catalog what's covered.
101
- 2. Identify gaps by category.
102
- 3. Prioritize: likely to happen OR catastrophic if it does.
103
- 4. **Before writing any test**, verify it against the anti-patterns above. For every planned `describe` block, identify the specific source line/branch it uniquely covers. If you cannot, drop it.
104
- 5. Write tests. Follow the existing test framework and patterns exactly.
105
- 6. Write your report.
121
+ 1. **Discover repo tooling.** Follow the Tooling — Non-Negotiable section above. Identify the package manager, test script, test framework config, and any workspace/monorepo conventions. Do this BEFORE reading any source code.
122
+ 2. Audit existing tests. Catalog what's covered.
123
+ 3. Identify gaps by category.
124
+ 4. Prioritize: likely to happen OR catastrophic if it does.
125
+ 5. **Before writing any test**, verify it against the anti-patterns above. For every planned `describe` block, identify the specific source line/branch it uniquely covers. If you cannot, drop it.
126
+ 6. Write tests. Follow the existing test framework and patterns exactly.
127
+ 7. Run tests using the repo's test script. Fix any failures before proceeding.
128
+ 8. Write your report.
106
129
 
107
130
  ## Output
108
131
 
@@ -146,9 +169,10 @@ Actual bugs discovered during test hardening.
146
169
 
147
170
  ## Verification
148
171
 
149
- Before writing the report, verify:
172
+ Before writing the report, verify by **reading your own code and the source code** — not by running ad-hoc commands:
150
173
 
151
- 1. Every new `describe` block covers a code path no existing test covers.
174
+ 1. Every new `describe` block covers a code path no existing test covers. Verify this by reading the source, not by running coverage tools.
152
175
  2. No tests target `.tsx` files or barrel exports.
153
176
  3. Tests are added to existing test files, not new ones.
154
177
  4. No existing tests were modified.
178
+ 5. All tests pass when run with the repo's test script. This is the ONLY command you should have executed via Bash during this entire process.
@@ -67,27 +67,50 @@ The developer can accept the default or specify another branch. Use whatever the
67
67
 
68
68
  ## Step 3: Gather Diff
69
69
 
70
- Check that there are commits ahead of the target branch:
70
+ Fetch the latest state of the target branch from the remote so comparisons reflect what's actually on the remote, not a potentially stale local copy:
71
71
 
72
72
  ```bash
73
- git log --oneline $TARGET..HEAD
73
+ git fetch origin $TARGET
74
+ ```
75
+
76
+ ### 3.1: Resolve Comparison Ref
77
+
78
+ Default to `origin/$TARGET` (the remote tracking ref) for all diff and log comparisons. Before proceeding, check whether a local copy of the target branch exists and is ahead of the remote:
79
+
80
+ ```bash
81
+ git rev-list --count origin/$TARGET..$TARGET 2>/dev/null
82
+ ```
83
+
84
+ - **If the command fails** (no local branch exists), or **returns 0** (local is behind or even with remote): use `origin/$TARGET` silently. No prompt needed.
85
+ - **If the count is greater than 0**: the local branch has commits not yet on the remote. Ask the developer:
86
+
87
+ > **Your local `{$TARGET}` is {count} commit(s) ahead of `origin/{$TARGET}`.** Use local or remote for comparison? (default: remote)
88
+
89
+ Use whichever ref the developer chooses as `$COMPARE_REF` for all subsequent diff and log commands. If they accept the default or don't respond, use `origin/$TARGET`.
90
+
91
+ ### 3.2: Check for Commits
92
+
93
+ Check that there are commits ahead of the comparison ref:
94
+
95
+ ```bash
96
+ git log --oneline $COMPARE_REF..HEAD
74
97
  ```
75
98
 
76
99
  **If no commits are returned**, stop and output:
77
100
 
78
- > **No commits ahead of `{$TARGET}`. Nothing to PR.** You may need to rebase.
101
+ > **No commits ahead of `{$COMPARE_REF}`. Nothing to PR.** You may need to rebase.
79
102
 
80
- Gather the change data:
103
+ ### 3.3: Gather Change Data
81
104
 
82
105
  ```bash
83
106
  # File list with change stats
84
- git diff --stat $TARGET...HEAD
107
+ git diff --stat $COMPARE_REF...HEAD
85
108
 
86
109
  # Full diff
87
- git diff $TARGET...HEAD
110
+ git diff $COMPARE_REF...HEAD
88
111
 
89
112
  # Commit log (excluding merges)
90
- git log --no-merges --oneline $TARGET..HEAD
113
+ git log --no-merges --oneline $COMPARE_REF..HEAD
91
114
  ```
92
115
 
93
116
  ## Step 4: Categorize and Filter Files
@@ -50,19 +50,52 @@ gh pr view --json number,title,baseRefName,headRefName,body,additions,deletions,
50
50
 
51
51
  ## Step 3: Gather Diff Information
52
52
 
53
- Use `gh pr diff` to get the diff as GitHub sees it. This avoids stale-local-branch problems where a behind-origin base branch inflates the diff with already-merged changes from other PRs.
53
+ ### 3.1: Resolve Comparison Ref
54
+
55
+ Fetch the latest state of the base branch from the remote:
56
+
57
+ ```bash
58
+ git fetch origin $baseRefName
59
+ ```
60
+
61
+ Default to using the remote for comparison (via `gh pr diff`). Before proceeding, check whether the local copy of the base branch is ahead of the remote:
54
62
 
55
63
  ```bash
56
- # File list with change stats
57
- gh pr diff --stat
64
+ git rev-list --count origin/$baseRefName..$baseRefName 2>/dev/null
65
+ ```
66
+
67
+ - **If the command fails** (no local branch exists), or **returns 0** (local is behind or even with remote): use the remote. No prompt needed.
68
+ - **If the count is greater than 0**: the local branch has commits not yet on the remote. Ask the developer:
69
+
70
+ > **Your local `{baseRefName}` is {count} commit(s) ahead of `origin/{baseRefName}`.** Use local or remote for comparison? (default: remote)
71
+
72
+ Store the choice as `$DIFF_MODE` — either `remote` (default) or `local`.
73
+
74
+ ### 3.2: Get the Diff
75
+
76
+ **If `$DIFF_MODE` is `remote`** (the 95% case):
58
77
 
59
- # Full diff (for analysis)
78
+ Use `gh pr diff` to get the full diff as GitHub sees it. This avoids stale-local-branch problems where a behind-origin base branch inflates the diff with already-merged changes from other PRs.
79
+
80
+ ```bash
60
81
  gh pr diff
61
82
  ```
62
83
 
63
- **For commit messages**, use the `commits` array already captured in Step 2 — that is the authoritative commit list for this PR. Do NOT use `git log`, which can include commits from other PRs if the local base branch is behind origin.
84
+ **If `$DIFF_MODE` is `local`:**
64
85
 
65
- **Cross-check**: Compare the file count from `gh pr diff --stat` against the `changedFiles` value from Step 2. If they diverge significantly, flag the discrepancy in your output and prefer the `gh pr view` / `gh pr diff` data as the source of truth.
86
+ Use local git to diff against the local base branch:
87
+
88
+ ```bash
89
+ git diff $baseRefName...HEAD
90
+ ```
91
+
92
+ ⚠️ Note: local diffs may differ slightly from GitHub's view in repos with complex merge histories.
93
+
94
+ ### 3.3: Stats and Commit Messages
95
+
96
+ File-level stats (additions, deletions, file count) are already available from the `gh pr view --json` output captured in Step 2 — don't duplicate that work here.
97
+
98
+ **For commit messages**, use the `commits` array already captured in Step 2 — that is the authoritative commit list for this PR. Do NOT use `git log`, which can include commits from other PRs if the local base branch is behind origin.
66
99
 
67
100
  ## Step 4: Categorize and Filter Files
68
101