@slowcook-ai/cli 0.19.0-alpha.1 → 0.19.0-alpha.11

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 (49) hide show
  1. package/dist/cli.js +27 -1
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/brew/agent.d.ts +129 -0
  4. package/dist/commands/brew/agent.d.ts.map +1 -1
  5. package/dist/commands/brew/agent.js +132 -0
  6. package/dist/commands/brew/agent.js.map +1 -1
  7. package/dist/commands/brew/index.d.ts.map +1 -1
  8. package/dist/commands/brew/index.js +72 -0
  9. package/dist/commands/brew/index.js.map +1 -1
  10. package/dist/commands/brew/pair-navigator.d.ts +112 -0
  11. package/dist/commands/brew/pair-navigator.d.ts.map +1 -0
  12. package/dist/commands/brew/pair-navigator.js +183 -0
  13. package/dist/commands/brew/pair-navigator.js.map +1 -0
  14. package/dist/commands/chef/orchestrate.d.ts +34 -0
  15. package/dist/commands/chef/orchestrate.d.ts.map +1 -0
  16. package/dist/commands/chef/orchestrate.js +385 -0
  17. package/dist/commands/chef/orchestrate.js.map +1 -0
  18. package/dist/commands/init/mock.d.ts +46 -0
  19. package/dist/commands/init/mock.d.ts.map +1 -1
  20. package/dist/commands/init/mock.js +142 -2
  21. package/dist/commands/init/mock.js.map +1 -1
  22. package/dist/commands/recon/index.d.ts.map +1 -1
  23. package/dist/commands/recon/index.js +288 -5
  24. package/dist/commands/recon/index.js.map +1 -1
  25. package/dist/commands/recon/reuse.d.ts +150 -0
  26. package/dist/commands/recon/reuse.d.ts.map +1 -0
  27. package/dist/commands/recon/reuse.js +335 -0
  28. package/dist/commands/recon/reuse.js.map +1 -0
  29. package/dist/commands/recon/shape-preserve.d.ts +46 -0
  30. package/dist/commands/recon/shape-preserve.d.ts.map +1 -1
  31. package/dist/commands/recon/shape-preserve.js +126 -0
  32. package/dist/commands/recon/shape-preserve.js.map +1 -1
  33. package/dist/commands/recon/stale-stubs.d.ts +62 -0
  34. package/dist/commands/recon/stale-stubs.d.ts.map +1 -0
  35. package/dist/commands/recon/stale-stubs.js +79 -0
  36. package/dist/commands/recon/stale-stubs.js.map +1 -0
  37. package/dist/commands/refactor/index.d.ts +15 -0
  38. package/dist/commands/refactor/index.d.ts.map +1 -0
  39. package/dist/commands/refactor/index.js +126 -0
  40. package/dist/commands/refactor/index.js.map +1 -0
  41. package/dist/commands/refactor/score.d.ts +38 -0
  42. package/dist/commands/refactor/score.d.ts.map +1 -0
  43. package/dist/commands/refactor/score.js +79 -0
  44. package/dist/commands/refactor/score.js.map +1 -0
  45. package/dist/commands/refactor/types.d.ts +64 -0
  46. package/dist/commands/refactor/types.d.ts.map +1 -0
  47. package/dist/commands/refactor/types.js +26 -0
  48. package/dist/commands/refactor/types.js.map +1 -0
  49. package/package.json +4 -4
@@ -31,6 +31,52 @@ interface FileToWrite {
31
31
  export declare function parseMockInitArgs(argv: string[], runtimeVersion: string): MockInitArgs;
32
32
  export declare function planMockFiles(args: MockInitArgs): FileToWrite[];
33
33
  export declare function initMock(argv: string[], cliVersion: string): Promise<void>;
34
+ /**
35
+ * Detect the consumer's package manager from lockfile presence.
36
+ * Pure: takes an `exists` predicate so it can be unit-tested without IO.
37
+ */
38
+ export declare function detectPackageManager(cwd: string, exists: (p: string) => boolean): "pnpm" | "npm" | "yarn" | "unknown";
39
+ /**
40
+ * Detect whether `mock` is already declared in the consumer's
41
+ * pnpm-workspace.yaml `packages` list. Pure parser — handles the
42
+ * common YAML shapes: flow array (`packages: [mock]`) + block list
43
+ * (`packages:\n - mock`). Returns true on any literal "mock" entry.
44
+ */
45
+ export declare function isMockInPnpmWorkspace(yamlContent: string): boolean;
46
+ /**
47
+ * Result of ensurePnpmWorkspace — what the cli did (if anything) so the
48
+ * caller can print accurate "Next steps" text.
49
+ */
50
+ export type EnsureWorkspaceResult = {
51
+ kind: "added-to-existing";
52
+ path: string;
53
+ } | {
54
+ kind: "already-listed";
55
+ path: string;
56
+ } | {
57
+ kind: "created";
58
+ path: string;
59
+ } | {
60
+ kind: "not-pnpm";
61
+ pkgManager: "npm" | "yarn" | "unknown";
62
+ };
63
+ /**
64
+ * Make sure `mock` is a pnpm-workspace member when the consumer is on
65
+ * pnpm. Three paths:
66
+ * - pnpm-workspace.yaml exists + lists "mock" → already-listed
67
+ * - pnpm-workspace.yaml exists + missing "mock" → added-to-existing
68
+ * - pnpm-lock.yaml present + no workspace.yaml → created (block-list shape)
69
+ * - npm/yarn/unknown (no pnpm signal) → not-pnpm
70
+ *
71
+ * We DON'T auto-migrate npm/yarn consumers — that requires re-resolving
72
+ * the lockfile and is too invasive for an `init mock` step. Caller
73
+ * prints a one-line recommendation in that case.
74
+ *
75
+ * Conservative writes: when adding to an existing block-list workspace,
76
+ * we append a new `- mock` line preserving prior content; we never
77
+ * rewrite the whole file.
78
+ */
79
+ export declare function ensurePnpmWorkspace(cwd: string): EnsureWorkspaceResult;
34
80
  /**
35
81
  * Patch the consumer's tsconfig.json so `mock` is in the `exclude`
36
82
  * array. Idempotent — returns false when nothing changed.
@@ -1 +1 @@
1
- {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../../src/commands/init/mock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,UAAU,YAAY;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,gEAAgE;IAChE,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,MAAM,GAAG,YAAY,CAoBtF;AAsDD,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,WAAW,EAAE,CAmC/D;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmEhF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAmBzE"}
1
+ {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../../src/commands/init/mock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,UAAU,YAAY;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,gEAAgE;IAChE,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,MAAM,GAAG,YAAY,CAoBtF;AAsDD,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,WAAW,EAAE,CAmC/D;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmGhF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GAC7B,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAKrC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAYlE;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,qBAAqB,CAiDtE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAmBzE"}
@@ -186,16 +186,156 @@ export async function initMock(argv, cliVersion) {
186
186
  console.log(` SKIP tsconfig.json (mock already in exclude or no exclude field)`);
187
187
  }
188
188
  }
189
+ // Wire mock as a pnpm-workspace member when the consumer is on pnpm
190
+ // so its node_modules dedupes against the prod tree (Next/React/
191
+ // Vitest/Tailwind are typically the same versions both sides). Two
192
+ // separate node_modules costs ~200-500MB on a typical Next 16 + RTL
193
+ // setup. Discovered post-rewo (2026-05-06) — by which time the rewo
194
+ // mock had its own node_modules + lockfile.
195
+ const wsResult = ensurePnpmWorkspace(args.cwd);
196
+ switch (wsResult.kind) {
197
+ case "added-to-existing":
198
+ console.log(` PATCH ${wsResult.path} (appended mock to packages list)`);
199
+ break;
200
+ case "already-listed":
201
+ console.log(` SKIP ${wsResult.path} (mock already a workspace member)`);
202
+ break;
203
+ case "created":
204
+ console.log(` WRITE ${wsResult.path} (created — pnpm workspace lists [mock])`);
205
+ break;
206
+ case "not-pnpm":
207
+ console.log(` SKIP pnpm-workspace.yaml (consumer uses ${wsResult.pkgManager}; recommend pnpm to share node_modules)`);
208
+ break;
209
+ }
189
210
  console.log(`Done. Wrote ${written} file(s); skipped ${skipped}.`);
190
211
  console.log();
191
212
  console.log("Next steps:");
192
- console.log(" 1. cd mock && npm install");
193
- console.log(" 2. npm run dev # http://localhost:3100");
213
+ if (wsResult.kind === "not-pnpm") {
214
+ console.log(" 1. cd mock && npm install # (or yarn install — separate node_modules)");
215
+ console.log(" 2. cd mock && npm run dev # http://localhost:3100");
216
+ console.log(" TIP: pnpm + a workspace would let mock + prod share node_modules");
217
+ console.log(" (saves ~200-500MB). Migrate later via:");
218
+ console.log(" echo 'packages:\\n - mock' > pnpm-workspace.yaml");
219
+ console.log(" rm -rf node_modules mock/node_modules package-lock.json mock/package-lock.json");
220
+ console.log(" pnpm install");
221
+ }
222
+ else {
223
+ console.log(" 1. pnpm install # at repo root — installs both halves");
224
+ console.log(" 2. pnpm --filter mock dev # http://localhost:3100");
225
+ }
194
226
  console.log(" 3. Verify the empty scenario picker renders");
195
227
  console.log(" 4. Commit + push the mock/ directory");
196
228
  console.log(" 5. Future vibe runs (slowcook 0.16-α.3+) populate mock/scenarios/ +");
197
229
  console.log(" extend mock/src/lib/scenario-registry.ts");
198
230
  }
231
+ /**
232
+ * Detect the consumer's package manager from lockfile presence.
233
+ * Pure: takes an `exists` predicate so it can be unit-tested without IO.
234
+ */
235
+ export function detectPackageManager(cwd, exists) {
236
+ if (exists(join(cwd, "pnpm-lock.yaml")) || exists(join(cwd, "pnpm-workspace.yaml")))
237
+ return "pnpm";
238
+ if (exists(join(cwd, "yarn.lock")))
239
+ return "yarn";
240
+ if (exists(join(cwd, "package-lock.json")))
241
+ return "npm";
242
+ return "unknown";
243
+ }
244
+ /**
245
+ * Detect whether `mock` is already declared in the consumer's
246
+ * pnpm-workspace.yaml `packages` list. Pure parser — handles the
247
+ * common YAML shapes: flow array (`packages: [mock]`) + block list
248
+ * (`packages:\n - mock`). Returns true on any literal "mock" entry.
249
+ */
250
+ export function isMockInPnpmWorkspace(yamlContent) {
251
+ // Strip comments to keep the regex simple.
252
+ const stripped = yamlContent.replace(/#[^\n]*/g, "");
253
+ // Block-list entries: `- mock` or `- "mock"` or `- 'mock'`
254
+ if (/^\s*-\s*["']?mock["']?\s*$/m.test(stripped))
255
+ return true;
256
+ // Flow-array form: `packages: [..., mock, ...]`
257
+ const flowMatch = stripped.match(/packages\s*:\s*\[([^\]]*)\]/);
258
+ if (flowMatch) {
259
+ const items = flowMatch[1].split(",").map((s) => s.trim().replace(/^["']|["']$/g, ""));
260
+ if (items.includes("mock"))
261
+ return true;
262
+ }
263
+ return false;
264
+ }
265
+ /**
266
+ * Make sure `mock` is a pnpm-workspace member when the consumer is on
267
+ * pnpm. Three paths:
268
+ * - pnpm-workspace.yaml exists + lists "mock" → already-listed
269
+ * - pnpm-workspace.yaml exists + missing "mock" → added-to-existing
270
+ * - pnpm-lock.yaml present + no workspace.yaml → created (block-list shape)
271
+ * - npm/yarn/unknown (no pnpm signal) → not-pnpm
272
+ *
273
+ * We DON'T auto-migrate npm/yarn consumers — that requires re-resolving
274
+ * the lockfile and is too invasive for an `init mock` step. Caller
275
+ * prints a one-line recommendation in that case.
276
+ *
277
+ * Conservative writes: when adding to an existing block-list workspace,
278
+ * we append a new `- mock` line preserving prior content; we never
279
+ * rewrite the whole file.
280
+ */
281
+ export function ensurePnpmWorkspace(cwd) {
282
+ const pkgMgr = detectPackageManager(cwd, existsSync);
283
+ if (pkgMgr !== "pnpm") {
284
+ return { kind: "not-pnpm", pkgManager: pkgMgr };
285
+ }
286
+ const workspacePath = join(cwd, "pnpm-workspace.yaml");
287
+ const relPath = "pnpm-workspace.yaml";
288
+ if (existsSync(workspacePath)) {
289
+ const original = readFileSync(workspacePath, "utf8");
290
+ if (isMockInPnpmWorkspace(original)) {
291
+ return { kind: "already-listed", path: relPath };
292
+ }
293
+ // Append a `- mock` entry to the existing packages list. If we can't
294
+ // find a `packages:` block, fall through to create it.
295
+ let updated;
296
+ if (/^packages\s*:/m.test(original)) {
297
+ // Existing block-list — append at the end of the list.
298
+ // Heuristic: find the last `-` line under packages: and add after.
299
+ // Simplest correct: append `\n - mock\n` after `packages:`'s last
300
+ // child (we accept slight indentation imperfection over parser risk).
301
+ const lines = original.split("\n");
302
+ let lastBlockIdx = -1;
303
+ let inPackages = false;
304
+ for (let i = 0; i < lines.length; i++) {
305
+ if (/^packages\s*:/.test(lines[i])) {
306
+ inPackages = true;
307
+ continue;
308
+ }
309
+ if (!inPackages)
310
+ continue;
311
+ if (/^\s*-\s+/.test(lines[i]))
312
+ lastBlockIdx = i;
313
+ else if (/^\S/.test(lines[i]) && lines[i].trim() !== "")
314
+ break;
315
+ }
316
+ if (lastBlockIdx === -1) {
317
+ // packages: is empty or flow form; append a fresh block-list line.
318
+ updated = original.replace(/(^packages\s*:.*$)/m, `$1\n - mock`);
319
+ }
320
+ else {
321
+ // Preserve the indent of the prior list item.
322
+ const priorIndent = lines[lastBlockIdx].match(/^(\s*)-/)[1] ?? " ";
323
+ lines.splice(lastBlockIdx + 1, 0, `${priorIndent}- mock`);
324
+ updated = lines.join("\n");
325
+ }
326
+ }
327
+ else {
328
+ updated = original.trimEnd() + `\npackages:\n - mock\n`;
329
+ }
330
+ writeFileSync(workspacePath, updated, "utf8");
331
+ return { kind: "added-to-existing", path: relPath };
332
+ }
333
+ // No workspace.yaml — create a minimal one. Block-list form is more
334
+ // approachable than flow-array for downstream edits.
335
+ const fresh = `# pnpm workspace — auto-created by 'slowcook init mock' so the\n# mock app shares node_modules with the prod tree (no duplicate installs).\npackages:\n - mock\n`;
336
+ writeFileSync(workspacePath, fresh, "utf8");
337
+ return { kind: "created", path: relPath };
338
+ }
199
339
  /**
200
340
  * Patch the consumer's tsconfig.json so `mock` is in the `exclude`
201
341
  * array. Idempotent — returns false when nothing changed.
@@ -1 +1 @@
1
- {"version":3,"file":"mock.js","sourceRoot":"","sources":["../../../src/commands/init/mock.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mock.js","sourceRoot":"","sources":["../../../src/commands/init/mock.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/recon/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAclF,UAAU,cAAc;IACtB,IAAI,EAAE,WAAW,GAAG,aAAa,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,SAAS;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,mBAAmB,GAAG,eAAe,GAAG,qBAAqB,GAAG,wBAAwB,CAAC;IAC/F,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,uBAAuB,CAAC;IACnC,MAAM,EAAE,OAAO,GAAG,eAAe,GAAG,UAAU,CAAC;IAC/C,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,eAAe,EAAE,aAAa,EAAE,CAAC;IACjC,wBAAwB,EAAE,MAAM,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAqDD,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgJ9E;AAID,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAU5E;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAMrD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAYrD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoB1E;AAyBD,YAAY,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/recon/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAyClF,UAAU,cAAc;IACtB,IAAI,EAAE,WAAW,GAAG,aAAa,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,SAAS;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,mBAAmB,GAAG,eAAe,GAAG,qBAAqB,GAAG,wBAAwB,CAAC;IAC/F,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,uBAAuB,CAAC;IACnC,MAAM,EAAE,OAAO,GAAG,eAAe,GAAG,UAAU,CAAC;IAC/C,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,eAAe,EAAE,aAAa,EAAE,CAAC;IACjC,wBAAwB,EAAE,MAAM,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA0FD,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0J9E;AAID,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAU5E;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAMrD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAYrD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoB1E;AAyBD,YAAY,EAAE,YAAY,EAAE,CAAC"}
@@ -31,6 +31,16 @@ function parseArgs(argv) {
31
31
  repoRoot: process.cwd(),
32
32
  outPath: "",
33
33
  verbose: false,
34
+ reuseScan: false,
35
+ reuseThreshold: 0.7,
36
+ reuseRoot: "src",
37
+ reuseWriteProposals: false,
38
+ reuseExcludes: [],
39
+ reuseSkipAutoTemplates: true,
40
+ stubScan: false,
41
+ stubMaxAgeDays: 14,
42
+ stubEscalate: false,
43
+ stubRoot: "src",
34
44
  };
35
45
  for (let i = 0; i < argv.length; i++) {
36
46
  const a = argv[i];
@@ -50,13 +60,48 @@ function parseArgs(argv) {
50
60
  else if (a === "--verbose" || a === "-v") {
51
61
  args.verbose = true;
52
62
  }
63
+ else if (a === "--reuse-scan") {
64
+ args.reuseScan = true;
65
+ }
66
+ else if (a === "--reuse-threshold" && next) {
67
+ args.reuseThreshold = parseFloat(next);
68
+ i++;
69
+ }
70
+ else if (a === "--reuse-root" && next) {
71
+ args.reuseRoot = next;
72
+ i++;
73
+ }
74
+ else if (a === "--write-proposals") {
75
+ args.reuseWriteProposals = true;
76
+ }
77
+ else if (a === "--exclude" && next) {
78
+ args.reuseExcludes.push(next);
79
+ i++;
80
+ }
81
+ else if (a === "--no-skip-auto-templates") {
82
+ args.reuseSkipAutoTemplates = false;
83
+ }
84
+ else if (a === "--stub-scan") {
85
+ args.stubScan = true;
86
+ }
87
+ else if (a === "--stub-max-age-days" && next) {
88
+ args.stubMaxAgeDays = parseInt(next, 10);
89
+ i++;
90
+ }
91
+ else if (a === "--stub-escalate") {
92
+ args.stubEscalate = true;
93
+ }
94
+ else if (a === "--stub-root" && next) {
95
+ args.stubRoot = next;
96
+ i++;
97
+ }
53
98
  else if (a === "--help" || a === "-h") {
54
99
  printHelp();
55
100
  process.exit(0);
56
101
  }
57
102
  }
58
- if (!args.story) {
59
- console.error("--story <id> is required.");
103
+ if (!args.reuseScan && !args.stubScan && !args.story) {
104
+ console.error("--story <id> is required (or pass --reuse-scan / --stub-scan for the story-agnostic modes).");
60
105
  printHelp();
61
106
  process.exit(64);
62
107
  }
@@ -77,19 +122,44 @@ Compares the story's test files against the mock + src/ tree. Detects:
77
122
  Usage:
78
123
  slowcook recon --story <id> [--cwd <path>] [--out <path>] [--verbose]
79
124
 
80
- Options:
81
- --story <id> Story id (e.g. 017). Required.
125
+ Options (story mode — default):
126
+ --story <id> Story id (e.g. 017). Required unless --reuse-scan.
82
127
  --cwd <path> Repo root (default: cwd).
83
128
  --out <path> Output JSON path (default: .brewing/recon-result.json).
84
129
  --verbose Print detailed breakdown to stdout.
85
130
 
131
+ Options (reuse-scan mode — 0.19.0-α.8+):
132
+ --reuse-scan Story-agnostic; flag near-duplicate components +
133
+ API handlers + utility modules across the codebase.
134
+ --reuse-root <path> Subtree to scan (default: src).
135
+ --reuse-threshold <n> Similarity threshold 0-1 (default: 0.7).
136
+ --write-proposals Append synthesized RefactorProposal entries to
137
+ .brewing/refactor/proposals.json so the refactor
138
+ command ranks them.
139
+ --exclude <glob> (α.10) Repeatable. Skip files matching the glob.
140
+ Supports: exact / "src/dir/" / "src/dir/*" /
141
+ "src/dir/**" / "*.mock.ts".
142
+ --no-skip-auto-templates (α.10) By default, recon skips files marked with
143
+ @slowcook-template / @slowcook-stub / @generated /
144
+ "AUTO-GENERATED" / "do not edit by hand". This
145
+ disables that filter (you'll see template-vs-template
146
+ duplicates again).
147
+
86
148
  Exit codes:
87
- 0 status=clean OR status=rename_needed (recommendations only)
149
+ 0 status=clean OR status=rename_needed OR --reuse-scan completed
88
150
  2 status=escalate (STORY_HISTORY_CONFLICT or VIBE_RECIPE_NAME_DRIFT)
89
151
  `);
90
152
  }
91
153
  export async function recon(argv, _cliVersion) {
92
154
  const args = parseArgs(argv);
155
+ if (args.reuseScan) {
156
+ await runReuseScan(args);
157
+ return;
158
+ }
159
+ if (args.stubScan) {
160
+ await runStubScan(args);
161
+ return;
162
+ }
93
163
  console.log(`slowcook recon · story-${args.story} · cwd: ${relative(process.cwd(), args.repoRoot) || "."}`);
94
164
  const idx = buildHistoryIndex({ repoRoot: args.repoRoot });
95
165
  const result = {
@@ -304,4 +374,217 @@ function walkAndGrep(dir, needle) {
304
374
  }
305
375
  return false;
306
376
  }
377
+ /**
378
+ * 0.19.0-α.8 — story-agnostic reuse-scan mode. Walks args.reuseRoot,
379
+ * extracts a structural signature per .ts(x) file, runs pairwise
380
+ * similarity, prints the duplicates, and (when --write-proposals)
381
+ * appends RefactorProposal entries to .brewing/refactor/proposals.json.
382
+ */
383
+ async function runReuseScan(args) {
384
+ const { extractStructuralSignature, scanForDuplicates, pairToRefactorProposal, isAutoTemplateFile, matchesExcludePattern, } = await import("./reuse.js");
385
+ console.log(`slowcook recon --reuse-scan · root: ${args.reuseRoot} · threshold: ${args.reuseThreshold} · cwd: ${relative(process.cwd(), args.repoRoot) || "."}`);
386
+ if (args.reuseExcludes.length > 0) {
387
+ console.log(` excludes: ${args.reuseExcludes.join(", ")}`);
388
+ }
389
+ if (args.reuseSkipAutoTemplates) {
390
+ console.log(` auto-template skip: ENABLED (--no-skip-auto-templates to disable)`);
391
+ }
392
+ const rootAbs = join(args.repoRoot, args.reuseRoot);
393
+ if (!existsSync(rootAbs)) {
394
+ console.error(`Reuse-scan root does not exist: ${rootAbs}`);
395
+ process.exit(2);
396
+ }
397
+ const allFiles = [];
398
+ walkTsFiles(rootAbs, allFiles);
399
+ // Apply --exclude patterns first (cheap filename match), then read
400
+ // file content + apply auto-template skip (more expensive — needs
401
+ // file read).
402
+ const files = [];
403
+ let excludedByPattern = 0;
404
+ let excludedAsTemplate = 0;
405
+ for (const abs of allFiles) {
406
+ const rel = relative(args.repoRoot, abs).replace(/\\/g, "/");
407
+ if (args.reuseExcludes.some((p) => matchesExcludePattern(rel, p))) {
408
+ excludedByPattern++;
409
+ continue;
410
+ }
411
+ if (args.reuseSkipAutoTemplates) {
412
+ const head = readFileSync(abs, "utf8");
413
+ if (isAutoTemplateFile(head)) {
414
+ excludedAsTemplate++;
415
+ continue;
416
+ }
417
+ }
418
+ files.push(abs);
419
+ }
420
+ console.log(` scanning ${files.length} .ts/.tsx files under ${args.reuseRoot}/ (excluded: ${excludedByPattern} by pattern, ${excludedAsTemplate} as auto-template)`);
421
+ const sigs = files.map((abs) => {
422
+ const rel = relative(args.repoRoot, abs).replace(/\\/g, "/");
423
+ return extractStructuralSignature(rel, readFileSync(abs, "utf8"));
424
+ });
425
+ const pairs = scanForDuplicates(sigs, args.reuseThreshold);
426
+ console.log(` found ${pairs.length} pair(s) at similarity >= ${args.reuseThreshold}`);
427
+ console.log("");
428
+ if (pairs.length === 0) {
429
+ console.log("(no duplicates flagged — codebase looks clean for the configured threshold)");
430
+ return;
431
+ }
432
+ for (const p of pairs) {
433
+ const pct = (p.similarity * 100).toFixed(0);
434
+ console.log(` ${pct}% similar [${p.category}]`);
435
+ console.log(` A: ${p.a}`);
436
+ console.log(` B: ${p.b}`);
437
+ console.log(` axes: jsx=${p.axes.jsx.toFixed(2)} props=${p.axes.props.toFixed(2)} calls=${p.axes.calls.toFixed(2)} imports=${p.axes.imports.toFixed(2)}`);
438
+ console.log("");
439
+ }
440
+ if (args.reuseWriteProposals) {
441
+ const proposalsPath = join(args.repoRoot, ".brewing/refactor/proposals.json");
442
+ const existing = existsSync(proposalsPath)
443
+ ? JSON.parse(readFileSync(proposalsPath, "utf8"))
444
+ : [];
445
+ const byId = new Map();
446
+ for (const p of existing)
447
+ byId.set(p.id, p);
448
+ let appended = 0;
449
+ for (const pair of pairs) {
450
+ const proposal = pairToRefactorProposal(pair);
451
+ if (!byId.has(proposal.id)) {
452
+ byId.set(proposal.id, proposal);
453
+ appended++;
454
+ }
455
+ }
456
+ const merged = [...byId.values()];
457
+ mkdirSync(dirname(proposalsPath), { recursive: true });
458
+ writeFileSync(proposalsPath, JSON.stringify(merged, null, 2), "utf8");
459
+ console.log(` wrote ${proposalsPath.replace(args.repoRoot + "/", "")} (+${appended} new of ${merged.length} total)`);
460
+ }
461
+ }
462
+ function walkTsFiles(root, out) {
463
+ for (const name of readdirSync(root)) {
464
+ if (name === "node_modules" || name === ".next" || name === ".git")
465
+ continue;
466
+ const abs = join(root, name);
467
+ const st = statSync(abs);
468
+ if (st.isDirectory()) {
469
+ walkTsFiles(abs, out);
470
+ }
471
+ else if (/\.(ts|tsx)$/.test(name) && !/\.test\.(ts|tsx)$/.test(name) && !/\.d\.ts$/.test(name)) {
472
+ out.push(abs);
473
+ }
474
+ }
475
+ }
476
+ /**
477
+ * 0.19.0-α.11 (#84) — story-agnostic stub-scan mode. Walks args.stubRoot,
478
+ * finds @slowcook-stub markers, ages each via git log --diff-filter=A,
479
+ * reports stale ones + (when --stub-escalate) posts PM comment on each
480
+ * stub's source issue.
481
+ */
482
+ async function runStubScan(args) {
483
+ const { execSync } = await import("node:child_process");
484
+ const { detectStubMarker, daysBetween, classifyStubAge, buildStaleStubComment, } = await import("./stale-stubs.js");
485
+ console.log(`slowcook recon --stub-scan · root: ${args.stubRoot} · grace: ${args.stubMaxAgeDays} days · cwd: ${relative(process.cwd(), args.repoRoot) || "."}`);
486
+ const rootAbs = join(args.repoRoot, args.stubRoot);
487
+ if (!existsSync(rootAbs)) {
488
+ console.error(`Stub-scan root does not exist: ${rootAbs}`);
489
+ process.exit(2);
490
+ }
491
+ const allFiles = [];
492
+ walkTsFiles(rootAbs, allFiles);
493
+ const nowIso = new Date().toISOString();
494
+ const stubs = [];
495
+ for (const abs of allFiles) {
496
+ const rel = relative(args.repoRoot, abs).replace(/\\/g, "/");
497
+ const content = readFileSync(abs, "utf8");
498
+ const detect = detectStubMarker(content);
499
+ if (!detect.isStub)
500
+ continue;
501
+ let firstAddedAt = null;
502
+ try {
503
+ // First-add date: oldest commit that added this file. --diff-filter=A
504
+ // only matches the addition; --reverse + head puts the earliest first.
505
+ const out = execSync(`git -C "${args.repoRoot}" log --diff-filter=A --follow --format=%cI --reverse -- "${rel}" 2>/dev/null | head -n 1`, { encoding: "utf8" }).trim();
506
+ if (out)
507
+ firstAddedAt = out;
508
+ }
509
+ catch {
510
+ // git log failed — leave firstAddedAt null
511
+ }
512
+ const ageDays = firstAddedAt ? daysBetween(firstAddedAt, nowIso) : null;
513
+ const classification = classifyStubAge(ageDays, args.stubMaxAgeDays);
514
+ stubs.push({
515
+ path: rel,
516
+ storyId: detect.storyId,
517
+ firstAddedAt,
518
+ ageDays,
519
+ classification,
520
+ });
521
+ }
522
+ console.log(` found ${stubs.length} @slowcook-stub file(s)`);
523
+ const stale = stubs.filter((s) => s.classification === "stale");
524
+ const fresh = stubs.filter((s) => s.classification === "fresh");
525
+ const unknown = stubs.filter((s) => s.classification === "unknown");
526
+ console.log(` ${stale.length} stale (≥ ${args.stubMaxAgeDays} days), ${fresh.length} fresh, ${unknown.length} unknown-age`);
527
+ console.log("");
528
+ if (stubs.length === 0) {
529
+ console.log("(no stubs found — pipeline is clean)");
530
+ return;
531
+ }
532
+ for (const s of [...stale, ...unknown, ...fresh]) {
533
+ const tag = s.classification === "stale"
534
+ ? "STALE"
535
+ : s.classification === "unknown"
536
+ ? "? "
537
+ : "fresh";
538
+ const ageStr = s.ageDays !== null ? `${s.ageDays.toString().padStart(5)}d` : " ? ";
539
+ const story = s.storyId ? `story-${s.storyId}` : "(no story id)";
540
+ console.log(` ${tag} ${ageStr} ${story.padEnd(14)} ${s.path}`);
541
+ }
542
+ if (args.stubEscalate && stale.length > 0) {
543
+ console.log("\n --stub-escalate set; posting PM comments on source issues...");
544
+ let repoSlug = "";
545
+ try {
546
+ repoSlug = execSync(`git -C "${args.repoRoot}" remote get-url origin | sed -E 's|^.*github\\.com[:/]||; s|\\.git$||'`, { encoding: "utf8" }).trim();
547
+ }
548
+ catch {
549
+ // leave repoSlug empty
550
+ }
551
+ if (!repoSlug) {
552
+ console.warn(" warn: could not detect repo slug; skipping escalations.");
553
+ }
554
+ else {
555
+ for (const s of stale) {
556
+ if (!s.storyId) {
557
+ console.warn(` skip: ${s.path} has no story id (can't find source issue).`);
558
+ continue;
559
+ }
560
+ // Look up source issue from spec yaml (specs/story-NNN.yaml).
561
+ const specPath = join(args.repoRoot, `specs/story-${s.storyId}.yaml`);
562
+ if (!existsSync(specPath)) {
563
+ console.warn(` skip: ${s.path} — no spec at ${specPath} to read source_issue from.`);
564
+ continue;
565
+ }
566
+ const specYaml = readFileSync(specPath, "utf8");
567
+ const issueMatch = specYaml.match(/source_issue:\s*"#?(\d+)"/);
568
+ if (!issueMatch) {
569
+ console.warn(` skip: ${s.path} — spec has no source_issue field.`);
570
+ continue;
571
+ }
572
+ const issueNumber = parseInt(issueMatch[1], 10);
573
+ const body = buildStaleStubComment(s, args.stubMaxAgeDays);
574
+ const tmp = "/tmp/slowcook-stale-stub-comment.md";
575
+ writeFileSync(tmp, body, "utf8");
576
+ try {
577
+ execSync(`gh issue comment ${issueNumber} --repo "${repoSlug}" --body-file ${tmp}`, { stdio: "inherit" });
578
+ console.log(` posted on issue #${issueNumber} for ${s.path}`);
579
+ }
580
+ catch (e) {
581
+ console.warn(` failed to post on issue #${issueNumber}: ${e.message.slice(0, 200)}`);
582
+ }
583
+ }
584
+ }
585
+ }
586
+ else if (stale.length > 0) {
587
+ console.log(`\n ${stale.length} stale stub(s) — re-run with --stub-escalate to post PM comments on source issues.`);
588
+ }
589
+ }
307
590
  //# sourceMappingURL=index.js.map