@slowcook-ai/cli 0.12.0 → 0.12.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/commands/testgen/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,cAAc,GAAI,gBAAgB,MAAM,WA0SuM,CAAC"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/commands/testgen/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,cAAc,GAAI,gBAAgB,MAAM,WAmXuM,CAAC"}
@@ -175,6 +175,79 @@ export function resetMocks(): void {
175
175
  - The fluent chain returned by \`mockFoo\` must support the operators the test actually calls (\`.from(t).select(...).eq(...).order(...).single()\` etc.). Include \`.then\` so bare \`await\` works.
176
176
  - Call recording: every chained method pushes to \`calls\`; tests assert \`expect(client.calls).toContainEqual({ table: "...", op: "...", args: [...] })\`.
177
177
 
178
+ ### CRITICAL: setting up "check-then-insert" handlers (0.12.1+)
179
+
180
+ A whole class of handlers does:
181
+
182
+ 1. Query: "is X already in the table?"
183
+ 2. If not, INSERT X
184
+ 3. Return 201 with the inserted row
185
+
186
+ Test-authoring bug pattern observed across rewo's brew-007 runs: the
187
+ test description says "with NO existing X" but the test seeds
188
+ \`tables.X.data = { ...full row... }\`, treating the seed as "the row
189
+ the handler will return." That's wrong — the seed is what the
190
+ PRE-INSERT QUERY will see, NOT the post-insert state.
191
+
192
+ When the handler does the pre-insert "is X already there?" check, the
193
+ mock returns the seeded row → handler thinks X exists → returns
194
+ \`200 { already_saved: true }\` instead of \`201 { ...inserted... }\`.
195
+
196
+ **Correct pattern for "Given NO existing X" tests:**
197
+
198
+ \`\`\`ts
199
+ it("Given NO existing bookmark, When POST, Then inserts and returns 201", async () => {
200
+ const supabase = mockSupabase({
201
+ user: { id: "member-a" },
202
+ tables: {
203
+ rewos: { data: { id: "rewo-abc", slug: "abc123" } },
204
+ bookmarks: { data: null }, // ← NULL: no existing row
205
+ },
206
+ });
207
+ vi.mocked(createClient).mockImplementation(realShapedCreateClient(supabase));
208
+
209
+ const res = await POST(buildReq("POST", { rewoSlug: "abc123" }));
210
+ expect(res.status).toBe(201);
211
+
212
+ // Assert the handler actually issued the INSERT — that's the contract,
213
+ // not whatever the response body claims.
214
+ expect(supabase.calls).toContainEqual(
215
+ expect.objectContaining({ table: "bookmarks", op: "insert" })
216
+ );
217
+
218
+ // If asserting the response body, only assert FIELDS THE HANDLER COMPUTES,
219
+ // not literal seeded ids — the mock can't return the inserted row's
220
+ // generated id without stateful response handling.
221
+ const json = (await res.json()) as { bookmark: { rewo_id: string } };
222
+ expect(json.bookmark).toMatchObject({ rewo_id: "rewo-abc" });
223
+ });
224
+ \`\`\`
225
+
226
+ **Correct pattern for "Given EXISTING X" tests:**
227
+
228
+ \`\`\`ts
229
+ it("Given existing bookmark, When POST, Then returns 200 already_saved", async () => {
230
+ const supabase = mockSupabase({
231
+ user: { id: "member-a" },
232
+ tables: {
233
+ rewos: { data: { id: "rewo-abc", slug: "abc123" } },
234
+ bookmarks: { data: { id: "bm-1", rewo_id: "rewo-abc" } }, // ← seeded existing row
235
+ },
236
+ });
237
+ // ...
238
+ expect(res.status).toBe(200);
239
+ expect(json).toEqual({ already_saved: true });
240
+ });
241
+ \`\`\`
242
+
243
+ **Rules:**
244
+
245
+ - For "Given NO X" tests, seed \`tables.<X>.data = null\` (or absent).
246
+ - For "Given EXISTING X" tests, seed the row's CURRENT-STATE shape.
247
+ - For "INSERT then RETURN" assertions, prefer asserting the INSERT \`call\` arg shape over the response body's id (the mock can't generate ids).
248
+ - If you need the response to have a specific id, assert ONLY the fields the handler synthesizes from input (e.g., rewo_id from the request body), not generated ids.
249
+ - NEVER seed a "post-insert state" row when the description says the row doesn't yet exist. Read the test's "Given" clause; it's the source of truth.
250
+
178
251
  Also add a barrel file when creating the first helper:
179
252
 
180
253
  \`\`\`
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgSxD,cAAc;;;;;;;;;;4PAU4O,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyWxD,cAAc;;;;;;;;;;4PAU4O,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slowcook-ai/cli",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "CLI for the slowcook brewing harness",
5
5
  "license": "MIT",
6
6
  "author": "aminazar",
@@ -39,9 +39,9 @@
39
39
  "yaml": "^2.6.0",
40
40
  "zod": "^3.23.8",
41
41
  "@slowcook-ai/core": "^0.11.12",
42
- "@slowcook-ai/forge-github": "^0.9.7",
43
42
  "@slowcook-ai/stack-ts": "^0.9.6",
44
43
  "@slowcook-ai/llm-anthropic": "^0.8.1",
44
+ "@slowcook-ai/forge-github": "^0.9.7",
45
45
  "@slowcook-ai/recorder": "^0.9.1"
46
46
  },
47
47
  "publishConfig": {