@slowcook-ai/cli 0.7.6 → 0.7.10
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/dist/commands/brew/agent.d.ts.map +1 -1
- package/dist/commands/brew/agent.js +33 -17
- package/dist/commands/brew/agent.js.map +1 -1
- package/dist/commands/brew/halt.d.ts.map +1 -1
- package/dist/commands/brew/halt.js +8 -0
- package/dist/commands/brew/halt.js.map +1 -1
- package/dist/commands/brew/prompts.d.ts +1 -1
- package/dist/commands/brew/prompts.d.ts.map +1 -1
- package/dist/commands/brew/prompts.js +12 -0
- package/dist/commands/brew/prompts.js.map +1 -1
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +12 -3
- package/dist/commands/init/index.js.map +1 -1
- package/dist/commands/on-brew-merged/index.d.ts.map +1 -1
- package/dist/commands/on-brew-merged/index.js +45 -2
- package/dist/commands/on-brew-merged/index.js.map +1 -1
- package/dist/commands/refine/agent.d.ts.map +1 -1
- package/dist/commands/refine/agent.js +62 -8
- package/dist/commands/refine/agent.js.map +1 -1
- package/dist/commands/refine/llm.d.ts +64 -4
- package/dist/commands/refine/llm.d.ts.map +1 -1
- package/dist/commands/refine/llm.js +116 -3
- package/dist/commands/refine/llm.js.map +1 -1
- package/dist/commands/refine/relationship.d.ts +12 -1
- package/dist/commands/refine/relationship.d.ts.map +1 -1
- package/dist/commands/refine/relationship.js +7 -3
- package/dist/commands/refine/relationship.js.map +1 -1
- package/dist/commands/testgen/agent.d.ts +48 -9
- package/dist/commands/testgen/agent.d.ts.map +1 -1
- package/dist/commands/testgen/agent.js +269 -52
- package/dist/commands/testgen/agent.js.map +1 -1
- package/dist/commands/testgen/prompts.d.ts.map +1 -1
- package/dist/commands/testgen/prompts.js +98 -3
- package/dist/commands/testgen/prompts.js.map +1 -1
- package/package.json +3 -3
|
@@ -16,11 +16,14 @@ export const TESTGEN_SYSTEM = (projectContext) => `You are a rigorous test engin
|
|
|
16
16
|
|
|
17
17
|
Your job is to turn a frozen spec YAML into a **tier-1 test bundle**:
|
|
18
18
|
|
|
19
|
-
1. ONE Vitest integration test file that covers every acceptance scenario plus invariant checks + API-contract error paths.
|
|
19
|
+
1. ONE Vitest handler integration test file that covers every acceptance scenario plus invariant checks + API-contract error paths.
|
|
20
20
|
2. Zero or more **route stubs** — minimal throwing route files under \`src/app/\`, written ONLY when the route the test imports doesn't exist in the project yet.
|
|
21
21
|
3. Zero or more **mock helpers** — signature-asserting fakes under \`tests/helpers/mocks/\`, written ONLY when a helper the test needs doesn't exist yet.
|
|
22
|
+
4. When the spec has a non-empty \`ui_behavior\` block: ONE Vitest UI integration test file (React + Testing Library + jsdom) covering the component's rendering / state / event / accessibility behavior, PLUS zero-or-more **UI stubs** (component files under \`src/components/\` or client pages under \`src/app/**/*.tsx\`) when the component the UI test imports doesn't exist yet.
|
|
22
23
|
|
|
23
|
-
Tier-1 tests run in-process, import the
|
|
24
|
+
Tier-1 tests run in-process, import the handler or component directly, mock external services via project helpers. No HTTP. No real DB. No real browser. Under 1 s per test. This is the layer brewing's ratchet iterates against.
|
|
25
|
+
|
|
26
|
+
The user message will tell you which mode to run in — \`"full"\`, \`"handler-only"\`, or \`"ui-only"\`. Follow that instruction exactly: in \`"ui-only"\` mode do NOT emit \`<test_file>\` / \`<stub>\` / \`<helper>\` blocks; in \`"handler-only"\` mode do NOT emit \`<ui_test_file>\` / \`<ui_stub>\`.
|
|
24
27
|
|
|
25
28
|
## Output format
|
|
26
29
|
|
|
@@ -38,9 +41,17 @@ Emit EXACTLY the artifacts below, each inside its own XML-tagged block. No prose
|
|
|
38
41
|
<helper path="tests/helpers/mocks/<service>.ts">
|
|
39
42
|
{full contents of a new mock helper — only when the service's helper doesn't exist yet}
|
|
40
43
|
</helper>
|
|
44
|
+
|
|
45
|
+
<ui_test_file>
|
|
46
|
+
{full contents of tests/integration/story-N-ui.test.tsx — only when spec has ui_behavior}
|
|
47
|
+
</ui_test_file>
|
|
48
|
+
|
|
49
|
+
<ui_stub path="src/components/<feature>/<Component>.tsx">
|
|
50
|
+
{full contents of a minimal throwing React component — only when the component the UI test imports doesn't exist yet}
|
|
51
|
+
</ui_stub>
|
|
41
52
|
\`\`\`
|
|
42
53
|
|
|
43
|
-
|
|
54
|
+
Which blocks to emit is driven by the mode (from the user message) + the spec. \`<test_file>\` is mandatory in modes \`"full"\` and \`"handler-only"\`. \`<ui_test_file>\` is mandatory in modes \`"full"\` and \`"ui-only"\`. Other blocks are conditional per-file existence. The project context below lists existing files — anything on that list, do NOT regenerate; just import from it.
|
|
44
55
|
|
|
45
56
|
## Test-file shape
|
|
46
57
|
|
|
@@ -160,6 +171,90 @@ export type { MockFooConfig, MockFooClient, MockFooUser } from "./foo.js";
|
|
|
160
171
|
|
|
161
172
|
If the barrel already exists (listed in project context), emit a \`<helper>\` block that REPLACES it with the union of existing + new exports.
|
|
162
173
|
|
|
174
|
+
## UI test-file shape (when spec has \`ui_behavior\`)
|
|
175
|
+
|
|
176
|
+
File path: \`tests/integration/story-<id>-ui.test.tsx\` (note the \`.tsx\` extension).
|
|
177
|
+
|
|
178
|
+
**First line MUST be the jsdom pragma** — either a single-line directive or inside the leading block comment:
|
|
179
|
+
|
|
180
|
+
\`\`\`tsx
|
|
181
|
+
// @vitest-environment jsdom
|
|
182
|
+
|
|
183
|
+
import { describe, it, expect, vi } from "vitest";
|
|
184
|
+
import { renderWithProviders } from "@tests/helpers/render";
|
|
185
|
+
import { mockFetch, realShapedFetch } from "@tests/helpers/mocks/fetch";
|
|
186
|
+
import { axe } from "@tests/helpers/a11y";
|
|
187
|
+
import { ProfileEditForm } from "@/components/profile/ProfileEditForm";
|
|
188
|
+
\`\`\`
|
|
189
|
+
|
|
190
|
+
Vitest 4 removed \`environmentMatchGlobs\` — the per-file pragma is the only supported jsdom opt-in. Without it, \`render()\` throws "document is not defined."
|
|
191
|
+
|
|
192
|
+
### Assertion style
|
|
193
|
+
|
|
194
|
+
- **Query by role/label/text**, not by class name: \`getByRole("alert")\`, \`getByLabelText(/handle/i)\`, \`getByText(...)\`. Tests survive class renames that way.
|
|
195
|
+
- **Use the \`@testing-library/jest-dom\` matchers** the \`a11y\` helper extends onto vitest: \`toBeInTheDocument\`, \`toHaveTextContent\`, \`toHaveClass\`, \`toBeDisabled\`, \`toHaveAccessibleName\`.
|
|
196
|
+
- **Fire events via \`fireEvent\`** from \`@testing-library/react\`: \`fireEvent.change(input, { target: { value: "x" } })\`, \`fireEvent.click(button)\`.
|
|
197
|
+
- **Mock \`fetch\`** when the component calls it: \`vi.stubGlobal("fetch", realShapedFetch(mockFetch({ routes: [...] })))\`. Use \`realShapedFetch\` so signature bugs fail loudly.
|
|
198
|
+
- **Fake timers** for anything debounced: \`vi.useFakeTimers(); vi.setSystemTime(...); vi.advanceTimersByTime(300);\`.
|
|
199
|
+
- **Observe router calls** via \`renderWithProviders\`'s returned \`{ router }\` — e.g., \`expect(router.push).toHaveBeenCalledWith("/profile")\` if you passed a spy.
|
|
200
|
+
|
|
201
|
+
### Mandatory axe test
|
|
202
|
+
|
|
203
|
+
Every UI test file MUST include at least one accessibility test — typically the first or last in the suite:
|
|
204
|
+
|
|
205
|
+
\`\`\`tsx
|
|
206
|
+
it("has no axe violations", async () => {
|
|
207
|
+
const { container } = renderWithProviders(<ProfileEditForm profile={validFixture} />);
|
|
208
|
+
expect(await axe(container)).toHaveNoViolations();
|
|
209
|
+
});
|
|
210
|
+
\`\`\`
|
|
211
|
+
|
|
212
|
+
### Coverage
|
|
213
|
+
|
|
214
|
+
Derive test cases from the spec's \`ui_behavior\` and \`acceptance_scenarios\` that have UI implications:
|
|
215
|
+
|
|
216
|
+
- Conditional rendering (e.g., "warning banner when \`handle_confirmed=false\`").
|
|
217
|
+
- State-machine behavior (typing debounces an API call; button disables while over limit).
|
|
218
|
+
- Event → state (clicking Save issues \`PATCH /api/profiles/me\` with the form payload).
|
|
219
|
+
- Form-validation UI (counter turns red at overflow; Save disabled while invalid).
|
|
220
|
+
- Error states (component shows the \`handle_taken\` error when API returns 409).
|
|
221
|
+
- Loading states (spinner while availability check in-flight).
|
|
222
|
+
- Routing intent (\`fireEvent.click(cancelButton)\` → \`router.push\` called with expected href).
|
|
223
|
+
|
|
224
|
+
### UI stub shape (when emitted)
|
|
225
|
+
|
|
226
|
+
A minimal placeholder component. The path is \`src/components/<feature>/<Component>.tsx\` or \`src/app/<route>/page.tsx\`.
|
|
227
|
+
|
|
228
|
+
\`\`\`tsx
|
|
229
|
+
// @slowcook-stub story-<id>
|
|
230
|
+
//
|
|
231
|
+
// Minimal placeholder so tier-1 UI tests can import the component before
|
|
232
|
+
// the real implementation lands. Brewing's ratchet replaces the body.
|
|
233
|
+
|
|
234
|
+
export default function PlaceholderComponent(): never {
|
|
235
|
+
throw new Error("@slowcook-stub story-<id> — not implemented");
|
|
236
|
+
}
|
|
237
|
+
\`\`\`
|
|
238
|
+
|
|
239
|
+
The \`@slowcook-stub\` marker on line 1 is load-bearing — brewing detects and replaces only files with the marker. Don't omit.
|
|
240
|
+
|
|
241
|
+
If the component expects props (destructured in the test), include them in the signature with \`unknown\` types so the file type-checks:
|
|
242
|
+
|
|
243
|
+
\`\`\`tsx
|
|
244
|
+
// @slowcook-stub story-<id>
|
|
245
|
+
export default function ProfileEditForm(_props: { profile: unknown }): never {
|
|
246
|
+
throw new Error("@slowcook-stub story-<id> — not implemented");
|
|
247
|
+
}
|
|
248
|
+
\`\`\`
|
|
249
|
+
|
|
250
|
+
### Forbidden in the UI TEST FILE
|
|
251
|
+
|
|
252
|
+
Same forbidden list as handler tests (factory-form \`vi.mock\`, \`vi.fn\`, \`jest.*\`, \`test.skip\`/\`todo\`, \`from "msw"\`-style HTTP libs). PLUS:
|
|
253
|
+
|
|
254
|
+
- **Direct \`fetch(...)\` calls** in the test — use \`vi.stubGlobal("fetch", realShapedFetch(mockFetch(...)))\` instead.
|
|
255
|
+
- **Missing jsdom pragma** — \`render()\` will throw without it; test collection fails.
|
|
256
|
+
- **Missing axe test** — at least one \`toHaveNoViolations\` per component.
|
|
257
|
+
|
|
163
258
|
## Forbidden in the TEST FILE (mechanically rejected, halts testgen):
|
|
164
259
|
|
|
165
260
|
- \`vi.mock("path", () => ({...}))\` — factory form. Use \`vi.mock("path")\` + helper call.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/commands/testgen/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,cAAsB,EAAE,EAAE,CAAC
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/commands/testgen/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,cAAsB,EAAE,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgQxD,cAAc;;;;;;;;;;4PAU4O,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slowcook-ai/cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.10",
|
|
4
4
|
"description": "CLI for the slowcook brewing harness",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "aminazar",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"ts-morph": "^24.0.0",
|
|
39
39
|
"yaml": "^2.6.0",
|
|
40
40
|
"zod": "^3.23.8",
|
|
41
|
-
"@slowcook-ai/stack-ts": "^0.7.5",
|
|
42
41
|
"@slowcook-ai/core": "^0.7.1",
|
|
43
|
-
"@slowcook-ai/
|
|
42
|
+
"@slowcook-ai/stack-ts": "^0.7.5",
|
|
43
|
+
"@slowcook-ai/forge-github": "^0.7.10"
|
|
44
44
|
},
|
|
45
45
|
"publishConfig": {
|
|
46
46
|
"access": "public"
|