@slowcook-ai/cli 0.6.5 → 0.6.8

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.
Files changed (33) hide show
  1. package/dist/cli.js +6 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/brew/agent.d.ts +34 -0
  4. package/dist/commands/brew/agent.d.ts.map +1 -1
  5. package/dist/commands/brew/agent.js +146 -0
  6. package/dist/commands/brew/agent.js.map +1 -1
  7. package/dist/commands/brew/index.js +3 -3
  8. package/dist/commands/brew/index.js.map +1 -1
  9. package/dist/commands/brew/prompts.d.ts +26 -1
  10. package/dist/commands/brew/prompts.d.ts.map +1 -1
  11. package/dist/commands/brew/prompts.js +63 -4
  12. package/dist/commands/brew/prompts.js.map +1 -1
  13. package/dist/commands/map/index.d.ts +4 -0
  14. package/dist/commands/map/index.d.ts.map +1 -0
  15. package/dist/commands/map/index.js +120 -0
  16. package/dist/commands/map/index.js.map +1 -0
  17. package/dist/commands/map/render.d.ts +18 -0
  18. package/dist/commands/map/render.d.ts.map +1 -0
  19. package/dist/commands/map/render.js +97 -0
  20. package/dist/commands/map/render.js.map +1 -0
  21. package/dist/commands/map/scan.d.ts +71 -0
  22. package/dist/commands/map/scan.d.ts.map +1 -0
  23. package/dist/commands/map/scan.js +368 -0
  24. package/dist/commands/map/scan.js.map +1 -0
  25. package/dist/commands/testgen/agent.d.ts +22 -0
  26. package/dist/commands/testgen/agent.d.ts.map +1 -1
  27. package/dist/commands/testgen/agent.js +112 -0
  28. package/dist/commands/testgen/agent.js.map +1 -1
  29. package/dist/commands/testgen/prompts.d.ts +12 -6
  30. package/dist/commands/testgen/prompts.d.ts.map +1 -1
  31. package/dist/commands/testgen/prompts.js +65 -26
  32. package/dist/commands/testgen/prompts.js.map +1 -1
  33. package/package.json +3 -2
@@ -1,12 +1,18 @@
1
1
  /**
2
2
  * System prompt for the test-gen agent. Takes a frozen spec as input; emits a
3
- * single Vitest integration test file.
3
+ * single Vitest integration test file in the tier-1 shape defined in
4
+ * docs/plans/0.7-testgen-two-tier.md §4.1.
4
5
  *
5
- * The agent does NOT read the consumer's src/. It tests the spec's contract,
6
- * not the implementation. HTTP-style integration tests (fetch the API, assert
7
- * on the response) are preferred because they don't need the implementation
8
- * to exist at test-collection time they fail at runtime if the endpoint is
9
- * missing, which is exactly the "red test" state brewing wants.
6
+ * Tier-1 tests import the route handler directly and mock external services
7
+ * via per-project helper functions (mockSupabase, mockResend, ...). They run
8
+ * in-process with no HTTP server, no real database, no DOM. Every test
9
+ * finishes in <1 s so the brewing ratchet can iterate cheaply.
10
+ *
11
+ * The consumer project is expected to own the helper functions. This prompt
12
+ * tells the LLM to use them; B1 does NOT generate them. If a helper is
13
+ * missing, the generated test will fail at collection time with a clear
14
+ * import error and the operator must hand-author the helper before brewing.
15
+ * Helper auto-generation ships in B2 (0.7.0).
10
16
  */
11
17
  export declare const TESTGEN_SYSTEM: (projectContext: string) => string;
12
18
  //# sourceMappingURL=prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/commands/testgen/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,cAAc,GAAI,gBAAgB,MAAM,WA0CwK,CAAC"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/commands/testgen/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,cAAc,GAAI,gBAAgB,MAAM,WA2E0J,CAAC"}
@@ -1,43 +1,82 @@
1
1
  /**
2
2
  * System prompt for the test-gen agent. Takes a frozen spec as input; emits a
3
- * single Vitest integration test file.
3
+ * single Vitest integration test file in the tier-1 shape defined in
4
+ * docs/plans/0.7-testgen-two-tier.md §4.1.
4
5
  *
5
- * The agent does NOT read the consumer's src/. It tests the spec's contract,
6
- * not the implementation. HTTP-style integration tests (fetch the API, assert
7
- * on the response) are preferred because they don't need the implementation
8
- * to exist at test-collection time they fail at runtime if the endpoint is
9
- * missing, which is exactly the "red test" state brewing wants.
6
+ * Tier-1 tests import the route handler directly and mock external services
7
+ * via per-project helper functions (mockSupabase, mockResend, ...). They run
8
+ * in-process with no HTTP server, no real database, no DOM. Every test
9
+ * finishes in <1 s so the brewing ratchet can iterate cheaply.
10
+ *
11
+ * The consumer project is expected to own the helper functions. This prompt
12
+ * tells the LLM to use them; B1 does NOT generate them. If a helper is
13
+ * missing, the generated test will fail at collection time with a clear
14
+ * import error and the operator must hand-author the helper before brewing.
15
+ * Helper auto-generation ships in B2 (0.7.0).
10
16
  */
11
17
  export const TESTGEN_SYSTEM = (projectContext) => `You are a rigorous test engineer for the slowcook brewing harness.
12
18
 
13
19
  Your job is to turn a frozen spec YAML into ONE Vitest integration test file that covers every acceptance scenario in the spec, plus invariant checks and key API-contract edge cases.
14
20
 
21
+ The test file you produce is **tier-1 integration**: it runs in-process, imports the route handler directly, and mocks external services via per-project helper functions. It does NOT hit HTTP, does NOT require a running server, and does NOT talk to real databases. It's the layer the brewing loop iterates against — every test must complete in well under a second and be fully deterministic.
22
+
15
23
  ## Input
16
24
 
17
- You will receive:
18
25
  - The full spec YAML (already validated, frozen).
19
- - Project context (stack config, existing test style snippets if present).
26
+ - Project context below: \`.brewing/context.md\` conventions, package.json, existing test style references, existing mock helpers.
20
27
 
21
28
  ## Output format
22
29
 
23
- Emit ONLY the TypeScript test file contents. No prose before or after, no code fences. Start with the first line of the file (imports) and end with the last closing brace. The file must:
30
+ Emit ONLY the TypeScript test file contents. No prose before or after, no code fences. Start with the first line (imports) and end with the last closing brace.
31
+
32
+ ## Required shape
33
+
34
+ 1. **Direct import** of the route handler(s) being tested. Example: \`import { POST } from "@/app/api/rewos/route";\`. If the route doesn't exist yet, the test will fail at collection — that's the intended red state brewing starts from.
35
+
36
+ 2. **Mock helpers** for every external service the handler consumes. Helpers live at \`tests/helpers/mocks/<service>.ts\` and expose intent-level options. Example:
37
+
38
+ \`\`\`ts
39
+ import { mockSupabase, resetMocks } from "@/tests/helpers/mocks";
40
+
41
+ const supabase = mockSupabase({
42
+ auth: { user: { id: "u1", verified: false } },
43
+ insert: { table: "rewos", returning: { id: "rewo1" } },
44
+ });
45
+ \`\`\`
46
+
47
+ If the project context below does NOT list a helper you need, emit the test anyway but leave a \`TODO(helper): describe shape\` comment at the top of the file listing the missing helpers. Do not write the helper body yourself — that's out of scope for this prompt. An operator will hand-author it.
48
+
49
+ 3. **beforeEach(resetMocks)** at the top of every describe block to prevent cross-test leakage.
50
+
51
+ 4. **Request objects built in-process**, not fetched. Example:
52
+
53
+ \`\`\`ts
54
+ const req = new Request("http://test/api/rewos", {
55
+ method: "POST",
56
+ headers: { Authorization: "Bearer token", "Content-Type": "application/json" },
57
+ body: JSON.stringify({ title: "hi" }),
58
+ });
59
+ const res = await POST(req);
60
+ expect(res.status).toBe(201);
61
+ \`\`\`
62
+
63
+ 5. **Coverage.** Include:
64
+ - Every acceptance scenario as an \`it\` block (Given/When/Then phrasing preserved in the name).
65
+ - Every error response listed in \`api_contract\` (401, 403, 404, 409, 429, 422, 500, ...).
66
+ - Invariants that are testable at the handler-call level — anything phrased as "handler calls X with Y" or "handler returns Z on condition W".
67
+
68
+ ## Forbidden patterns (mechanically rejected)
24
69
 
25
- - Be valid TypeScript that Vitest can collect (imports resolve or fail at RUNTIME, not at collection prefer HTTP calls over direct function imports).
26
- - Use \`describe\` / \`it\` from Vitest.
27
- - Use \`beforeEach\` / \`afterEach\` for setup/teardown if needed.
28
- - Include ALL acceptance scenarios as \`it\` blocks, named to match the scenario (Given/When/Then phrasing preserved).
29
- - Include invariant checks as separate \`it\` blocks where they can be asserted via HTTP.
30
- - Include negative tests for every error response listed in \`api_contract\` (403, 429, 404, etc.).
31
- - Include edge cases for each invariant (e.g., "exactly at the boundary").
70
+ The test file must NOT contain any of these. Slowcook lints the output after generation and fails the run if detected.
32
71
 
33
- ## Stylistic conventions
72
+ - \`vi.mock(\` — use project helper functions instead.
73
+ - \`vi.fn(\` — helpers encapsulate the fakes; callers supply intent, not function bodies.
74
+ - \`jest.mock(\` or \`jest.fn(\` — wrong framework, also banned for consistency.
75
+ - \`fetch(\` — tier-1 tests do not hit HTTP. Construct \`Request\` and pass to the handler.
76
+ - Mock-library imports: \`from "msw"\`, \`from "nock"\`, \`from "aws-sdk-client-mock"\`, etc.
77
+ - \`test.skip\` / \`test.todo\` / \`it.skip\` / \`it.todo\` — caught by the static scan, fails the manifest.
34
78
 
35
- - One describe block per API endpoint or per cohesive topic.
36
- - Test names use natural language matching acceptance scenarios, e.g. \`it("rejects a self-report with 409", ...)\`.
37
- - Use \`fetch\` (global) for HTTP calls — avoid importing app code. This keeps tests runnable even before implementation exists.
38
- - Prefer environment variables for the API base URL (fall back to \`http://localhost:3000\`). Expose via a local const.
39
- - If the spec references a DB table, DO NOT import the DB client directly. Tests should assert via HTTP + response shape only; schema-level invariants surface as HTTP contract failures.
40
- - Mark deliberately-incomplete assertions with a \`// TODO(story-N): ...\` comment ONLY when the spec explicitly left a detail as non-goal; otherwise assert concretely.
79
+ If a spec genuinely requires an HTTP call (e.g. an invariant about how a handler calls a third-party), express it as "handler calls outboundHttp helper with X". The helper wraps \`fetch\` and is mocked in tier-1.
41
80
 
42
81
  ## Project context (consumer's conventions)
43
82
 
@@ -45,10 +84,10 @@ ${projectContext}
45
84
 
46
85
  ## Do NOT
47
86
 
48
- - Read or reference files outside the spec. Don't import types from the consumer's source code. The spec is the contract.
87
+ - Read or reference files outside the spec and the project context above. If you need a detail not present, emit a \`TODO(spec): ...\` comment rather than inventing it.
49
88
  - Skip an acceptance scenario. Every scenario in the spec must have at least one corresponding \`it\` block.
50
89
  - Write flaky tests. If timing is involved, fake it deterministically (set test time, mock Date, etc.).
51
- - Use \`test.skip\` / \`test.todo\` — these are caught by slowcook's static scan and will fail the manifest check.
90
+ - Use \`test.skip\` / \`test.todo\`.
52
91
 
53
- Produce a complete, parseable file that, when executed against an unimplemented API, fails with clear messages (status code mismatches, response shape mismatches). That is the desired "red" state brewing will turn green.`;
92
+ Produce a complete, parseable tier-1 integration test file. When executed against an unimplemented route handler, it fails with clear assertion messages that brewing's LLM can interpret and fix iteratively.`;
54
93
  //# sourceMappingURL=prompts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/commands/testgen/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,cAAsB,EAAE,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCxD,cAAc;;;;;;;;;6NAS6M,CAAC"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/commands/testgen/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,cAAsB,EAAE,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkExD,cAAc;;;;;;;;;+MAS+L,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slowcook-ai/cli",
3
- "version": "0.6.5",
3
+ "version": "0.6.8",
4
4
  "description": "CLI for the slowcook brewing harness",
5
5
  "license": "MIT",
6
6
  "author": "aminazar",
@@ -35,10 +35,11 @@
35
35
  "dependencies": {
36
36
  "@anthropic-ai/sdk": "^0.32.1",
37
37
  "@octokit/rest": "^21.0.2",
38
+ "ts-morph": "^24.0.0",
38
39
  "yaml": "^2.6.0",
39
40
  "zod": "^3.23.8",
40
- "@slowcook-ai/stack-ts": "^0.6.2",
41
41
  "@slowcook-ai/core": "^0.5.0",
42
+ "@slowcook-ai/stack-ts": "^0.6.2",
42
43
  "@slowcook-ai/forge-github": "^0.5.0"
43
44
  },
44
45
  "publishConfig": {