@bastani/atomic 0.5.22-0 → 0.5.23-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.
Files changed (33) hide show
  1. package/.agents/skills/workflow-creator/SKILL.md +2 -2
  2. package/.agents/skills/workflow-creator/references/agent-sessions.md +21 -26
  3. package/.agents/skills/workflow-creator/references/discovery-and-verification.md +1 -1
  4. package/.agents/skills/workflow-creator/references/failure-modes.md +16 -9
  5. package/.agents/skills/workflow-creator/references/getting-started.md +0 -1
  6. package/.agents/skills/workflow-creator/references/session-config.md +5 -12
  7. package/.agents/skills/workflow-creator/references/workflow-inputs.md +2 -2
  8. package/.claude/agents/reviewer.md +2 -2
  9. package/.github/agents/reviewer.md +2 -2
  10. package/.opencode/agents/reviewer.md +2 -2
  11. package/dist/commands/cli/claude-stop-hook.d.ts +1 -0
  12. package/dist/commands/cli/claude-stop-hook.d.ts.map +1 -1
  13. package/dist/sdk/providers/claude.d.ts +9 -47
  14. package/dist/sdk/providers/claude.d.ts.map +1 -1
  15. package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts.map +1 -1
  16. package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts.map +1 -1
  17. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts +0 -6
  18. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts.map +1 -1
  19. package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts.map +1 -1
  20. package/dist/sdk/workflows/builtin/ralph/helpers/prompts.d.ts +4 -4
  21. package/dist/sdk/workflows/builtin/ralph/helpers/prompts.d.ts.map +1 -1
  22. package/package.json +1 -1
  23. package/src/cli.ts +17 -1
  24. package/src/commands/cli/claude-ask-hook.test.ts +128 -0
  25. package/src/commands/cli/claude-ask-hook.ts +84 -0
  26. package/src/commands/cli/claude-stop-hook.ts +2 -1
  27. package/src/sdk/providers/claude.ts +126 -160
  28. package/src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts +1 -6
  29. package/src/sdk/workflows/builtin/deep-research-codebase/copilot/index.ts +1 -6
  30. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.ts +30 -47
  31. package/src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts +0 -6
  32. package/src/sdk/workflows/builtin/ralph/copilot/index.ts +2 -2
  33. package/src/sdk/workflows/builtin/ralph/helpers/prompts.ts +7 -7
@@ -158,7 +158,7 @@ export default defineWorkflow({
158
158
  { agent: "codebase-research-locator" },
159
159
  async (s) => {
160
160
  await s.session.send({
161
- prompt: buildHistoryLocatorPrompt({ question: prompt, root }),
161
+ prompt: buildHistoryLocatorPrompt({ question: prompt }),
162
162
  });
163
163
  const messages = await s.session.getMessages();
164
164
  s.save(messages);
@@ -179,7 +179,6 @@ export default defineWorkflow({
179
179
  prompt: buildHistoryAnalyzerPrompt({
180
180
  question: prompt,
181
181
  locatorOutput: historyLocator.result,
182
- root,
183
182
  }),
184
183
  });
185
184
  const messages = await s.session.getMessages();
@@ -218,7 +217,6 @@ export default defineWorkflow({
218
217
  prompt: buildLocatorPrompt({
219
218
  question: prompt,
220
219
  partition,
221
- root,
222
220
  scoutOverview,
223
221
  index: i,
224
222
  total: explorerCount,
@@ -242,7 +240,6 @@ export default defineWorkflow({
242
240
  prompt: buildPatternFinderPrompt({
243
241
  question: prompt,
244
242
  partition,
245
- root,
246
243
  scoutOverview,
247
244
  index: i,
248
245
  total: explorerCount,
@@ -274,7 +271,6 @@ export default defineWorkflow({
274
271
  question: prompt,
275
272
  partition,
276
273
  locatorOutput,
277
- root,
278
274
  scoutOverview,
279
275
  index: i,
280
276
  total: explorerCount,
@@ -299,7 +295,6 @@ export default defineWorkflow({
299
295
  question: prompt,
300
296
  partition,
301
297
  locatorOutput,
302
- root,
303
298
  index: i,
304
299
  total: explorerCount,
305
300
  }),
@@ -37,7 +37,6 @@
37
37
  * LLM "synthesizer" stage) and the aggregator reads them by path.
38
38
  */
39
39
 
40
- import path from "node:path";
41
40
  import type { PartitionUnit } from "./scout.ts";
42
41
 
43
42
  const DOCUMENTARIAN_DISCLAIMER =
@@ -63,27 +62,19 @@ export function slugifyPrompt(prompt: string): string {
63
62
  return slug || "research";
64
63
  }
65
64
 
66
- /** Render a partition's directory list as absolute paths with file/LOC counts. */
67
- function renderPartitionAssignment(
68
- partition: PartitionUnit[],
69
- root: string,
70
- ): string {
65
+ /** Render a partition's directory list as repo-relative paths with file/LOC counts. */
66
+ function renderPartitionAssignment(partition: PartitionUnit[]): string {
71
67
  return partition
72
- .map((u) => {
73
- const abs = path.join(root, u.path);
74
- return ` - \`${abs}/\` (${u.fileCount} files, ${u.loc.toLocaleString()} LOC)`;
75
- })
68
+ .map(
69
+ (u) =>
70
+ ` - \`${u.path}/\` (${u.fileCount} files, ${u.loc.toLocaleString()} LOC)`,
71
+ )
76
72
  .join("\n");
77
73
  }
78
74
 
79
- /** Comma-separated absolute directory list (for inline grep/glob scope hints). */
80
- function renderPartitionDirsAbs(
81
- partition: PartitionUnit[],
82
- root: string,
83
- ): string {
84
- return partition
85
- .map((u) => `\`${path.join(root, u.path)}\``)
86
- .join(", ");
75
+ /** Comma-separated repo-relative directory list (for inline grep/glob scope hints). */
76
+ function renderPartitionDirs(partition: PartitionUnit[]): string {
77
+ return partition.map((u) => `\`${u.path}/\``).join(", ");
87
78
  }
88
79
 
89
80
  // ─────────────────────────────────────────────────────────────────────────────
@@ -173,13 +164,12 @@ export function buildScoutPrompt(opts: {
173
164
  export function buildLocatorPrompt(opts: {
174
165
  question: string;
175
166
  partition: PartitionUnit[];
176
- root: string;
177
167
  scoutOverview: string;
178
168
  index: number;
179
169
  total: number;
180
170
  }): string {
181
- const assignment = renderPartitionAssignment(opts.partition, opts.root);
182
- const dirsAbs = renderPartitionDirsAbs(opts.partition, opts.root);
171
+ const assignment = renderPartitionAssignment(opts.partition);
172
+ const dirs = renderPartitionDirs(opts.partition);
183
173
  const orientation =
184
174
  opts.scoutOverview.trim().length > 0
185
175
  ? opts.scoutOverview.trim()
@@ -206,14 +196,14 @@ export function buildLocatorPrompt(opts: {
206
196
  ``,
207
197
  assignment,
208
198
  ``,
209
- `(Quick comma-separated form for tool args: ${dirsAbs})`,
199
+ `(Quick comma-separated form for tool args: ${dirs})`,
210
200
  `</SCOPE>`,
211
201
  ``,
212
202
  `<OUTPUT_FORMAT>`,
213
203
  `Return a markdown report with this exact structure:`,
214
204
  ``,
215
205
  `### Implementation`,
216
- `- \`<absolute path>\` — 1-line note on relevance`,
206
+ `- \`<repo-relative path>\` — 1-line note on relevance`,
217
207
  ``,
218
208
  `### Tests`,
219
209
  `- ...`,
@@ -231,10 +221,10 @@ export function buildLocatorPrompt(opts: {
231
221
  `- ...`,
232
222
  ``,
233
223
  `### Notable Clusters`,
234
- `- \`<absolute dir>/\` — N files, why it's a cluster`,
224
+ `- \`<repo-relative dir>/\` — N files, why it's a cluster`,
235
225
  ``,
236
226
  `Omit any section that has no entries (do not write "(none)" placeholders).`,
237
- `Use ABSOLUTE paths. Do NOT read file contents — your job is location only.`,
227
+ `Use repo-relative paths. Do NOT read file contents — your job is location only.`,
238
228
  `</OUTPUT_FORMAT>`,
239
229
  ``,
240
230
  `<CONSTRAINTS>`,
@@ -254,13 +244,12 @@ export function buildLocatorPrompt(opts: {
254
244
  export function buildPatternFinderPrompt(opts: {
255
245
  question: string;
256
246
  partition: PartitionUnit[];
257
- root: string;
258
247
  scoutOverview: string;
259
248
  index: number;
260
249
  total: number;
261
250
  }): string {
262
- const assignment = renderPartitionAssignment(opts.partition, opts.root);
263
- const dirsAbs = renderPartitionDirsAbs(opts.partition, opts.root);
251
+ const assignment = renderPartitionAssignment(opts.partition);
252
+ const dirs = renderPartitionDirs(opts.partition);
264
253
  const orientation =
265
254
  opts.scoutOverview.trim().length > 0
266
255
  ? opts.scoutOverview.trim()
@@ -285,14 +274,14 @@ export function buildPatternFinderPrompt(opts: {
285
274
  `<SCOPE>`,
286
275
  assignment,
287
276
  ``,
288
- `(Quick comma-separated form for tool args: ${dirsAbs})`,
277
+ `(Quick comma-separated form for tool args: ${dirs})`,
289
278
  `</SCOPE>`,
290
279
  ``,
291
280
  `<OUTPUT_FORMAT>`,
292
281
  `For each distinct pattern you find, output:`,
293
282
  ``,
294
283
  `#### Pattern: <short name>`,
295
- `**Where:** \`<absolute path>:<line>\``,
284
+ `**Where:** \`<repo-relative path>:<line>\``,
296
285
  `**What:** 1-sentence description.`,
297
286
  "```<language>",
298
287
  `<5-30 lines of actual code from the file>`,
@@ -321,12 +310,11 @@ export function buildAnalyzerPrompt(opts: {
321
310
  question: string;
322
311
  partition: PartitionUnit[];
323
312
  locatorOutput: string;
324
- root: string;
325
313
  scoutOverview: string;
326
314
  index: number;
327
315
  total: number;
328
316
  }): string {
329
- const assignment = renderPartitionAssignment(opts.partition, opts.root);
317
+ const assignment = renderPartitionAssignment(opts.partition);
330
318
  const orientation =
331
319
  opts.scoutOverview.trim().length > 0
332
320
  ? opts.scoutOverview.trim()
@@ -379,17 +367,17 @@ export function buildAnalyzerPrompt(opts: {
379
367
  ` (≤200 words) describing how these files compose to address the topic.`,
380
368
  `5. List any files OUTSIDE this partition that you noticed are referenced`,
381
369
  ` from your reads (so the aggregator can stitch findings across`,
382
- ` partitions). One file per line: \`<absolute path>\` — 1-line reason.`,
370
+ ` partitions). One file per line: \`<repo-relative path>\` — 1-line reason.`,
383
371
  `</METHOD>`,
384
372
  ``,
385
373
  `<OUTPUT_FORMAT>`,
386
374
  `Use this structure (omit empty sections):`,
387
375
  ``,
388
376
  `### Files Analysed`,
389
- `<bullet list of the 5-10 files you read, absolute paths>`,
377
+ `<bullet list of the 5-10 files you read, repo-relative paths>`,
390
378
  ``,
391
379
  `### Per-File Notes`,
392
- `#### \`<absolute path>\``,
380
+ `#### \`<repo-relative path>\``,
393
381
  `- **Role:** ...`,
394
382
  `- **Key symbols:** \`name\` (\`file.ts:line\`), ...`,
395
383
  `- **Control flow:** ...`,
@@ -400,7 +388,7 @@ export function buildAnalyzerPrompt(opts: {
400
388
  `<≤200 words on how these files compose to address the topic>`,
401
389
  ``,
402
390
  `### Out-of-Partition References`,
403
- `- \`<absolute path>\` — 1-line note on why it matters`,
391
+ `- \`<repo-relative path>\` — 1-line note on why it matters`,
404
392
  `</OUTPUT_FORMAT>`,
405
393
  ``,
406
394
  `<CONSTRAINTS>`,
@@ -422,11 +410,10 @@ export function buildOnlineResearcherPrompt(opts: {
422
410
  question: string;
423
411
  partition: PartitionUnit[];
424
412
  locatorOutput: string;
425
- root: string;
426
413
  index: number;
427
414
  total: number;
428
415
  }): string {
429
- const assignment = renderPartitionAssignment(opts.partition, opts.root);
416
+ const assignment = renderPartitionAssignment(opts.partition);
430
417
  const locator =
431
418
  opts.locatorOutput.trim().length > 0
432
419
  ? opts.locatorOutput.trim()
@@ -485,7 +472,7 @@ export function buildOnlineResearcherPrompt(opts: {
485
472
  `#### <Library> (vX.Y)`,
486
473
  `**Docs:** <url>, <url>`,
487
474
  `**Relevant behaviour:** ...`,
488
- `**Where used:** \`<absolute path>:<line>\` — 1-line note`,
475
+ `**Where used:** \`<repo-relative path>:<line>\` — 1-line note`,
489
476
  `</OUTPUT_FORMAT>`,
490
477
  ``,
491
478
  `<CONSTRAINTS>`,
@@ -509,10 +496,7 @@ export function buildOnlineResearcherPrompt(opts: {
509
496
  /** codebase-research-locator — find prior research docs about the topic. */
510
497
  export function buildHistoryLocatorPrompt(opts: {
511
498
  question: string;
512
- root: string;
513
499
  }): string {
514
- const researchDir = path.join(opts.root, "research");
515
-
516
500
  return [
517
501
  `<RESEARCH_QUESTION>`,
518
502
  opts.question,
@@ -525,8 +509,8 @@ export function buildHistoryLocatorPrompt(opts: {
525
509
  `</MISSION>`,
526
510
  ``,
527
511
  `<SCOPE>`,
528
- `Primary: \`${researchDir}/\` (and standard subdirs: docs/, tickets/, notes/).`,
529
- `Secondary: any sibling research directories under \`${opts.root}\` that match`,
512
+ `Primary: \`research/\` (and standard subdirs: docs/, tickets/, notes/).`,
513
+ `Secondary: any sibling research directories at the repository root that match`,
530
514
  `\`*research*\`, \`*adr*\`, \`*rfc*\`, or \`specs\`.`,
531
515
  ``,
532
516
  `If no research directory exists at all, return a single section:`,
@@ -539,7 +523,7 @@ export function buildHistoryLocatorPrompt(opts: {
539
523
  `Group by document type. Within each group, sort newest first by filename.`,
540
524
  ``,
541
525
  `### Docs`,
542
- `- \`<absolute path>\` — 1-line title-derived summary`,
526
+ `- \`<repo-relative path>\` — 1-line title-derived summary`,
543
527
  ``,
544
528
  `### Tickets`,
545
529
  `- ...`,
@@ -570,7 +554,6 @@ export function buildHistoryLocatorPrompt(opts: {
570
554
  export function buildHistoryAnalyzerPrompt(opts: {
571
555
  question: string;
572
556
  locatorOutput: string;
573
- root: string;
574
557
  }): string {
575
558
  const locator =
576
559
  opts.locatorOutput.trim().length > 0
@@ -605,7 +588,7 @@ export function buildHistoryAnalyzerPrompt(opts: {
605
588
  ``,
606
589
  `<OUTPUT_FORMAT>`,
607
590
  `### Documents Reviewed`,
608
- `- \`<absolute path>\` — 1-line takeaway`,
591
+ `- \`<repo-relative path>\` — 1-line takeaway`,
609
592
  ``,
610
593
  `### Synthesis`,
611
594
  `<≤400 words covering decisions, conclusions, and open questions, with`,
@@ -163,7 +163,6 @@ export default defineWorkflow({
163
163
  type: "text",
164
164
  text: buildHistoryLocatorPrompt({
165
165
  question: prompt,
166
- root,
167
166
  }),
168
167
  },
169
168
  ],
@@ -191,7 +190,6 @@ export default defineWorkflow({
191
190
  text: buildHistoryAnalyzerPrompt({
192
191
  question: prompt,
193
192
  locatorOutput: historyLocator.result,
194
- root,
195
193
  }),
196
194
  },
197
195
  ],
@@ -236,7 +234,6 @@ export default defineWorkflow({
236
234
  text: buildLocatorPrompt({
237
235
  question: prompt,
238
236
  partition,
239
- root,
240
237
  scoutOverview,
241
238
  index: i,
242
239
  total: explorerCount,
@@ -266,7 +263,6 @@ export default defineWorkflow({
266
263
  text: buildPatternFinderPrompt({
267
264
  question: prompt,
268
265
  partition,
269
- root,
270
266
  scoutOverview,
271
267
  index: i,
272
268
  total: explorerCount,
@@ -304,7 +300,6 @@ export default defineWorkflow({
304
300
  question: prompt,
305
301
  partition,
306
302
  locatorOutput,
307
- root,
308
303
  scoutOverview,
309
304
  index: i,
310
305
  total: explorerCount,
@@ -335,7 +330,6 @@ export default defineWorkflow({
335
330
  question: prompt,
336
331
  partition,
337
332
  locatorOutput,
338
- root,
339
333
  index: i,
340
334
  total: explorerCount,
341
335
  }),
@@ -214,7 +214,7 @@ export default defineWorkflow({
214
214
  {},
215
215
  { agent: "reviewer", tools: [toolA] },
216
216
  async (s) => {
217
- await s.session.sendAndWait({ prompt: reviewPrompt });
217
+ await s.session.send({ prompt: reviewPrompt });
218
218
  const messages = await s.session.getMessages();
219
219
  s.save(messages);
220
220
  return {
@@ -228,7 +228,7 @@ export default defineWorkflow({
228
228
  {},
229
229
  { agent: "reviewer", tools: [toolB] },
230
230
  async (s) => {
231
- await s.session.sendAndWait({ prompt: reviewPrompt });
231
+ await s.session.send({ prompt: reviewPrompt });
232
232
  const messages = await s.session.getMessages();
233
233
  s.save(messages);
234
234
  return {
@@ -47,9 +47,9 @@ export const ReviewFindingSchema = z.object({
47
47
  ),
48
48
  code_location: z
49
49
  .object({
50
- absolute_file_path: z
50
+ file_path: z
51
51
  .string()
52
- .describe("Absolute path to the file containing the issue"),
52
+ .describe("Repo-relative path to the file containing the issue"),
53
53
  line_range: z.object({
54
54
  start: z.number().int().describe("Start line number"),
55
55
  end: z.number().int().describe("End line number"),
@@ -583,7 +583,7 @@ export interface ReviewFinding {
583
583
  confidence_score?: number;
584
584
  priority?: number;
585
585
  code_location?: {
586
- absolute_file_path: string;
586
+ file_path: string;
587
587
  line_range: { start: number; end: number };
588
588
  };
589
589
  }
@@ -817,7 +817,7 @@ ${outputSection}
817
817
  - \`body\`: What's wrong, why it matters, and how to fix it
818
818
  - \`priority\`: 0 = P0 critical, 1 = P1 important, 2 = P2 moderate, 3 = P3 minor
819
819
  - \`confidence_score\`: 0.0 – 1.0, how confident you are this is a real issue
820
- - \`code_location\`: absolute file path and line range (when applicable)
820
+ - \`code_location\`: repo-relative file path and line range (when applicable)
821
821
 
822
822
  - **overall_correctness**: Set to \`"patch is incorrect"\` whenever there is at
823
823
  least one P0 or P1 finding (including incomplete tasks). Use
@@ -869,7 +869,7 @@ export function buildDebuggerReportPrompt(
869
869
  .map((f, i) => {
870
870
  const pri = f.priority !== undefined ? `P${f.priority}` : "P2";
871
871
  const loc = f.code_location
872
- ? `${f.code_location.absolute_file_path}:${f.code_location.line_range.start}-${f.code_location.line_range.end}`
872
+ ? `${f.code_location.file_path}:${f.code_location.line_range.start}-${f.code_location.line_range.end}`
873
873
  : "unspecified";
874
874
  return `### Finding ${i + 1}: [${pri}] ${f.title}
875
875
  - **Location:** ${loc}
@@ -947,7 +947,7 @@ ${changesetSection}
947
947
  For each finding:
948
948
  1. Locate the relevant code (LSP / grep / Read).
949
949
  2. Identify the **root cause**, not just the symptom.
950
- 3. List the absolute file paths that must change.
950
+ 3. List the repo-relative file paths that must change.
951
951
  4. Note constraints, pitfalls, or invariants the next planner must respect.
952
952
 
953
953
  ## Output Format
@@ -961,7 +961,7 @@ No prose before or after the block. Use this exact section structure:
961
961
  ## Issues Identified
962
962
  - [P<priority>] <one-line issue summary>
963
963
  - **Root cause:** <one or two sentences>
964
- - **Files:** <abs/path/file.ext, abs/path/other.ext>
964
+ - **Files:** <path/to/file.ext, path/to/other.ext>
965
965
  - **Fix approach:** <imperative description>
966
966
 
967
967
  ## Suggested Plan Adjustments