@bastani/atomic 0.8.26-alpha.1 → 0.8.26-alpha.3
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/CHANGELOG.md +13 -0
- package/dist/builtin/intercom/CHANGELOG.md +12 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/CHANGELOG.md +12 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +13 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +8 -3
- package/dist/builtin/subagents/src/runs/foreground/execution.ts +42 -4
- package/dist/builtin/subagents/src/runs/shared/acceptance.ts +2 -1
- package/dist/builtin/subagents/src/runs/shared/worktree.ts +2 -2
- package/dist/builtin/web-access/CHANGELOG.md +12 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +19 -0
- package/dist/builtin/workflows/README.md +10 -8
- package/dist/builtin/workflows/builtin/index.d.ts +2 -0
- package/dist/builtin/workflows/builtin/ralph.d.ts +2 -0
- package/dist/builtin/workflows/builtin/ralph.ts +299 -89
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/skills/create-spec/SKILL.md +14 -0
- package/dist/builtin/workflows/skills/research-codebase/SKILL.md +28 -9
- package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +6 -1
- package/dist/builtin/workflows/src/runs/shared/worktree.ts +2 -2
- package/dist/builtin/workflows/src/shared/store.ts +61 -7
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +37 -2
- package/dist/core/atomic-guide-command.d.ts.map +1 -1
- package/dist/core/atomic-guide-command.js +10 -8
- package/dist/core/atomic-guide-command.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +3 -0
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +14 -7
- package/dist/core/package-manager.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +4 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +3 -2
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/utils/git-env.d.ts +10 -0
- package/dist/utils/git-env.d.ts.map +1 -0
- package/dist/utils/git-env.js +33 -0
- package/dist/utils/git-env.js.map +1 -0
- package/docs/quickstart.md +4 -4
- package/docs/workflows.md +16 -14
- package/package.json +1 -1
|
@@ -24,14 +24,24 @@ The user's research question/request is: **$ARGUMENTS**
|
|
|
24
24
|
- **CRITICAL**: Read these files yourself in the main context before spawning any sub-tasks
|
|
25
25
|
- This ensures you have full context before decomposing the research
|
|
26
26
|
|
|
27
|
-
2. **
|
|
27
|
+
2. **Determine the compatibility posture:**
|
|
28
|
+
- Before decomposing the research request, identify whether this project must preserve backward compatibility for real downstream users.
|
|
29
|
+
- If the user explicitly allows breaking changes, public API changes, cleanup, or says there are no real users/downstream dependencies, set `breaking_changes_allowed: true`.
|
|
30
|
+
- If the user mentions production users, published APIs, downstream consumers, migration safety, or compatibility requirements, set `breaking_changes_allowed: false`.
|
|
31
|
+
- If the posture is not inferable from the request, ask the user once before continuing, using the available structured question tool when possible.
|
|
32
|
+
- Carry this posture into the research plan, every sub-agent prompt, the final research document frontmatter, and the `## Compatibility Context` section.
|
|
33
|
+
- When `breaking_changes_allowed: true`, document existing legacy behavior, compatibility shims, optional flags, and public APIs as current state, not as constraints future specs must preserve unless the user explicitly asks for preservation.
|
|
34
|
+
- When `breaking_changes_allowed: false`, document public APIs, compatibility-sensitive surfaces, downstream callers, migration constraints, and behavior that future work must preserve.
|
|
35
|
+
|
|
36
|
+
3. **Analyze and decompose the research question:**
|
|
28
37
|
- Break the research question down into composable research areas
|
|
29
38
|
- Take time to ultrathink about the underlying patterns, connections, and architectural implications the user might be seeking
|
|
30
39
|
- Identify specific components, patterns, or concepts to investigate
|
|
31
40
|
- Create a research plan using TodoWrite to track all subtasks
|
|
41
|
+
- Include the compatibility posture in the plan so later synthesis and spec creation inherit the same constraint.
|
|
32
42
|
- Consider which directories, files, or architectural patterns are relevant
|
|
33
43
|
|
|
34
|
-
|
|
44
|
+
4. **Spawn parallel sub-agent tasks:**
|
|
35
45
|
- Create multiple Task agents to research different aspects concurrently
|
|
36
46
|
- We now have specialized agents that know how to do specific research tasks:
|
|
37
47
|
|
|
@@ -67,8 +77,9 @@ The user's research question/request is: **$ARGUMENTS**
|
|
|
67
77
|
- Each agent knows its job - just tell it what you're looking for
|
|
68
78
|
- Don't write detailed prompts about HOW to search - the agents already know
|
|
69
79
|
- Remind agents they are documenting, not evaluating or improving
|
|
80
|
+
- Include `breaking_changes_allowed: true` or `breaking_changes_allowed: false` in each sub-agent prompt so compatibility-sensitive findings are documented with the right posture.
|
|
70
81
|
|
|
71
|
-
|
|
82
|
+
5. **Wait for all sub-agents to complete and synthesize:**
|
|
72
83
|
- IMPORTANT: Wait for ALL sub-agent tasks to complete before proceeding
|
|
73
84
|
- Compile all sub-agent results (both codebase and research findings)
|
|
74
85
|
- Prioritize live codebase findings as primary source of truth
|
|
@@ -79,7 +90,7 @@ The user's research question/request is: **$ARGUMENTS**
|
|
|
79
90
|
- Answer the user's research question with concrete evidence
|
|
80
91
|
- **If findings reveal the original question was misframed** (e.g., the system works differently than assumed, or the components don't exist where expected), flag this to the user before finalizing the document. This is valuable signal — don't bury it.
|
|
81
92
|
|
|
82
|
-
|
|
93
|
+
6. **Generate research document:**
|
|
83
94
|
- Follow the directory structure for research documents:
|
|
84
95
|
|
|
85
96
|
```
|
|
@@ -117,6 +128,8 @@ research/
|
|
|
117
128
|
status: complete
|
|
118
129
|
last_updated: !`date '+%Y-%m-%d'`
|
|
119
130
|
last_updated_by: [Researcher name]
|
|
131
|
+
breaking_changes_allowed: [true or false]
|
|
132
|
+
compatibility_context: "[Short explanation of downstream-user/API compatibility posture]"
|
|
120
133
|
---
|
|
121
134
|
|
|
122
135
|
# Research
|
|
@@ -125,6 +138,10 @@ research/
|
|
|
125
138
|
|
|
126
139
|
[Original user query]
|
|
127
140
|
|
|
141
|
+
## Compatibility Context
|
|
142
|
+
|
|
143
|
+
[State whether breaking changes are allowed. If true, note that existing compatibility shims, optional flags, legacy APIs, and public APIs are documented as current state rather than preservation constraints. If false, summarize compatibility-sensitive surfaces, downstream users/callers, migration constraints, and behavior future work must preserve.]
|
|
144
|
+
|
|
128
145
|
## Summary
|
|
129
146
|
|
|
130
147
|
[High-level documentation of what was found, answering the user's question by describing what exists]
|
|
@@ -167,19 +184,19 @@ research/
|
|
|
167
184
|
[Any areas that need further investigation]
|
|
168
185
|
```
|
|
169
186
|
|
|
170
|
-
|
|
187
|
+
7. **Add GitHub permalinks (if applicable):**
|
|
171
188
|
- Check if on main branch or if commit is pushed: `git branch --show-current` and `git status`
|
|
172
189
|
- If on main/master or pushed, generate GitHub permalinks:
|
|
173
190
|
- Get repo info: `gh repo view --json owner,name`
|
|
174
191
|
- Create permalinks: `https://github.com/{owner}/{repo}/blob/{commit}/{file}#L{line}`
|
|
175
192
|
- Replace local file references with permalinks in the document
|
|
176
193
|
|
|
177
|
-
|
|
194
|
+
8. **Present findings:**
|
|
178
195
|
- Present a concise summary of findings to the user
|
|
179
196
|
- Include key file references for easy navigation
|
|
180
197
|
- Ask if they have follow-up questions or need clarification
|
|
181
198
|
|
|
182
|
-
|
|
199
|
+
9. **Handle follow-up questions:**
|
|
183
200
|
|
|
184
201
|
- If the user has follow-up questions, append to the same research document
|
|
185
202
|
- Update the frontmatter fields `last_updated` and `last_updated_by` to reflect the update
|
|
@@ -207,10 +224,12 @@ research/
|
|
|
207
224
|
- **REMEMBER**: Document what IS, not what SHOULD BE
|
|
208
225
|
- **NO RECOMMENDATIONS**: Only describe the current state of the codebase
|
|
209
226
|
- **File reading**: Always read mentioned files FULLY (no limit/offset) before spawning sub-tasks
|
|
227
|
+
- **Compatibility posture**: Always determine `breaking_changes_allowed` before decomposing the question. This is a single project/research posture, not a request to add compatibility flags. Use it to document whether old APIs and shims are constraints for future work.
|
|
210
228
|
- **Critical ordering**: Follow the numbered steps exactly
|
|
211
229
|
- ALWAYS read mentioned files first before spawning sub-tasks (step 1)
|
|
212
|
-
- ALWAYS
|
|
213
|
-
- ALWAYS
|
|
230
|
+
- ALWAYS determine compatibility posture before decomposing the question (step 2)
|
|
231
|
+
- ALWAYS wait for all sub-agents to complete before synthesizing (step 5)
|
|
232
|
+
- ALWAYS gather metadata before writing the document (as part of step 6)
|
|
214
233
|
- NEVER write the research document with placeholder values
|
|
215
234
|
|
|
216
235
|
- **Frontmatter consistency**:
|
|
@@ -586,6 +586,7 @@ export function createStageContext(opts: StageRunnerOpts): InternalStageContext
|
|
|
586
586
|
let selectedModel: string | undefined;
|
|
587
587
|
const modelAttempts: WorkflowModelAttempt[] = [];
|
|
588
588
|
const modelWarnings: string[] = [];
|
|
589
|
+
const pendingFallbackWarnings: string[] = [];
|
|
589
590
|
const modelCatalog = opts.models === undefined
|
|
590
591
|
? undefined
|
|
591
592
|
: {
|
|
@@ -796,15 +797,19 @@ export function createStageContext(opts: StageRunnerOpts): InternalStageContext
|
|
|
796
797
|
try {
|
|
797
798
|
await promptWithPauseResume(activeSession, text, sdkOptions);
|
|
798
799
|
modelAttempts.push({ model: candidate.id, success: true, ...modelAttemptReasoning(candidate) });
|
|
800
|
+
pendingFallbackWarnings.length = 0;
|
|
799
801
|
return;
|
|
800
802
|
} catch (err) {
|
|
801
803
|
const message = errorMessage(err);
|
|
802
804
|
modelAttempts.push({ model: candidate.id, success: false, ...modelAttemptReasoning(candidate), error: message });
|
|
803
805
|
if (signal?.aborted || !isRetryableModelFailure(message) || index === candidates.length - 1) {
|
|
806
|
+
modelWarnings.push(...pendingFallbackWarnings);
|
|
807
|
+
pendingFallbackWarnings.length = 0;
|
|
808
|
+
notifyModelFallbackMetaChange();
|
|
804
809
|
throw err;
|
|
805
810
|
}
|
|
806
811
|
const nextCandidate = candidates[index + 1]!;
|
|
807
|
-
|
|
812
|
+
pendingFallbackWarnings.push(`[fallback] ${candidateLabel(candidate)} failed: ${message}. Retrying with ${candidateLabel(nextCandidate)}.`);
|
|
808
813
|
await disposeCurrentSession();
|
|
809
814
|
index += 1;
|
|
810
815
|
}
|
|
@@ -2,7 +2,7 @@ import { spawnSync } from "node:child_process";
|
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as os from "node:os";
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
-
import { APP_NAME } from "@bastani/atomic";
|
|
5
|
+
import { APP_NAME, createGitEnvironment } from "@bastani/atomic";
|
|
6
6
|
|
|
7
7
|
export interface WorktreeSetup {
|
|
8
8
|
cwd: string;
|
|
@@ -110,7 +110,7 @@ function runGit(cwd: string, args: string[]): GitResult {
|
|
|
110
110
|
], {
|
|
111
111
|
cwd,
|
|
112
112
|
encoding: "utf-8",
|
|
113
|
-
env: {
|
|
113
|
+
env: createGitEnvironment({ GIT_OPTIONAL_LOCKS: "0" }),
|
|
114
114
|
timeout: 5000,
|
|
115
115
|
});
|
|
116
116
|
return {
|
|
@@ -151,6 +151,16 @@ export interface Store {
|
|
|
151
151
|
): boolean;
|
|
152
152
|
/** Wait for a stage/node-scoped HIL prompt to resolve. */
|
|
153
153
|
awaitStagePendingPrompt(runId: string, stageId: string, promptId: string): Promise<unknown>;
|
|
154
|
+
/**
|
|
155
|
+
* Record a live-only draft for an active stage-local input/editor prompt.
|
|
156
|
+
* Draft text may contain secrets and must never be copied into snapshots,
|
|
157
|
+
* status output, logs, notifications, or persisted metadata.
|
|
158
|
+
*/
|
|
159
|
+
recordStagePromptDraft(runId: string, stageId: string, promptId: string, text: string): boolean;
|
|
160
|
+
/** Return a live-only draft for an active stage-local input/editor prompt, if present. */
|
|
161
|
+
getStagePromptDraft(runId: string, stageId: string, promptId: string): string | undefined;
|
|
162
|
+
/** Clear a live-only draft for a stage-local prompt. */
|
|
163
|
+
clearStagePromptDraft(runId: string, stageId: string, promptId: string): boolean;
|
|
154
164
|
/**
|
|
155
165
|
* Return the live-only prompt answer record for a completed prompt stage, if
|
|
156
166
|
* still available. The returned value may contain secrets and must never be
|
|
@@ -239,6 +249,7 @@ export function createStore(): Store {
|
|
|
239
249
|
const _notices: WorkflowNotice[] = [];
|
|
240
250
|
const _listeners: Set<(snap: StoreSnapshot) => void> = new Set();
|
|
241
251
|
const _stagePromptAnswers = new Map<string, PromptAnswerRecord>();
|
|
252
|
+
const _stagePromptDrafts = new Map<string, string>();
|
|
242
253
|
let _version = 0;
|
|
243
254
|
|
|
244
255
|
/**
|
|
@@ -285,16 +296,36 @@ export function createStore(): Store {
|
|
|
285
296
|
return JSON.stringify([runId, stageId]);
|
|
286
297
|
}
|
|
287
298
|
|
|
288
|
-
function
|
|
299
|
+
function stagePromptDraftKey(runId: string, stageId: string, promptId: string): string {
|
|
300
|
+
return JSON.stringify([runId, stageId, promptId]);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function stageHasActiveTextPrompt(
|
|
304
|
+
runId: string,
|
|
305
|
+
stageId: string,
|
|
306
|
+
promptId: string,
|
|
307
|
+
): { prompt: PendingPrompt } | undefined {
|
|
308
|
+
const run = findRun(runId);
|
|
309
|
+
if (!run || TERMINAL_STATUSES.has(run.status)) return undefined;
|
|
310
|
+
const stage = findStage(run, stageId);
|
|
311
|
+
if (!stage || isTerminalStageStatus(stage.status)) return undefined;
|
|
312
|
+
const prompt = stage.pendingPrompt;
|
|
313
|
+
if (!prompt || prompt.id !== promptId) return undefined;
|
|
314
|
+
if (prompt.kind !== "input" && prompt.kind !== "editor") return undefined;
|
|
315
|
+
return { prompt };
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function rejectStagePrompt(runId: string, stage: StageSnapshot, reason: string): void {
|
|
289
319
|
const prompt = stage.pendingPrompt;
|
|
290
320
|
if (!prompt) return;
|
|
291
321
|
stage.pendingPrompt = undefined;
|
|
322
|
+
_stagePromptDrafts.delete(stagePromptDraftKey(runId, stage.id, prompt.id));
|
|
292
323
|
rejectPrompt(prompt.id, reason);
|
|
293
324
|
}
|
|
294
325
|
|
|
295
|
-
function rejectAllStagePrompts(run: RunSnapshot, reason: string): void {
|
|
326
|
+
function rejectAllStagePrompts(runId: string, run: RunSnapshot, reason: string): void {
|
|
296
327
|
for (const stage of run.stages) {
|
|
297
|
-
rejectStagePrompt(stage, reason);
|
|
328
|
+
rejectStagePrompt(runId, stage, reason);
|
|
298
329
|
}
|
|
299
330
|
}
|
|
300
331
|
|
|
@@ -427,7 +458,7 @@ export function createStore(): Store {
|
|
|
427
458
|
if (stage.workflowChild !== undefined) existing.workflowChild = structuredClone(stage.workflowChild);
|
|
428
459
|
delete existing.awaitingInputSince;
|
|
429
460
|
delete existing.inputRequest;
|
|
430
|
-
rejectStagePrompt(existing, `atomic-workflows: stage ${stage.id} ended before prompt resolved`);
|
|
461
|
+
rejectStagePrompt(runId, existing, `atomic-workflows: stage ${stage.id} ended before prompt resolved`);
|
|
431
462
|
_version++;
|
|
432
463
|
notify();
|
|
433
464
|
},
|
|
@@ -474,7 +505,7 @@ export function createStore(): Store {
|
|
|
474
505
|
run.pendingPrompt = undefined;
|
|
475
506
|
rejectPrompt(pending.id, `atomic-workflows: run ${runId} ended before prompt resolved`);
|
|
476
507
|
}
|
|
477
|
-
rejectAllStagePrompts(run, `atomic-workflows: run ${runId} ended before prompt resolved`);
|
|
508
|
+
rejectAllStagePrompts(runId, run, `atomic-workflows: run ${runId} ended before prompt resolved`);
|
|
478
509
|
_version++;
|
|
479
510
|
notify();
|
|
480
511
|
return true;
|
|
@@ -488,7 +519,7 @@ export function createStore(): Store {
|
|
|
488
519
|
if (pending) {
|
|
489
520
|
rejectPrompt(pending.id, `atomic-workflows: run ${runId} was removed before prompt resolved`);
|
|
490
521
|
}
|
|
491
|
-
rejectAllStagePrompts(run, `atomic-workflows: run ${runId} was removed before prompt resolved`);
|
|
522
|
+
rejectAllStagePrompts(runId, run, `atomic-workflows: run ${runId} was removed before prompt resolved`);
|
|
492
523
|
for (const stage of run.stages) {
|
|
493
524
|
_stagePromptAnswers.delete(stagePromptAnswerKey(runId, stage.id));
|
|
494
525
|
}
|
|
@@ -599,6 +630,7 @@ export function createStore(): Store {
|
|
|
599
630
|
if (!stage) return false;
|
|
600
631
|
const pending = stage.pendingPrompt;
|
|
601
632
|
if (!pending || pending.id !== promptId) return false;
|
|
633
|
+
_stagePromptDrafts.delete(stagePromptDraftKey(runId, stageId, promptId));
|
|
602
634
|
if (options.recordAnswer !== false) {
|
|
603
635
|
_stagePromptAnswers.set(stagePromptAnswerKey(runId, stageId), {
|
|
604
636
|
runId,
|
|
@@ -654,6 +686,21 @@ export function createStore(): Store {
|
|
|
654
686
|
});
|
|
655
687
|
},
|
|
656
688
|
|
|
689
|
+
recordStagePromptDraft(runId: string, stageId: string, promptId: string, text: string): boolean {
|
|
690
|
+
if (stageHasActiveTextPrompt(runId, stageId, promptId) === undefined) return false;
|
|
691
|
+
_stagePromptDrafts.set(stagePromptDraftKey(runId, stageId, promptId), text);
|
|
692
|
+
return true;
|
|
693
|
+
},
|
|
694
|
+
|
|
695
|
+
getStagePromptDraft(runId: string, stageId: string, promptId: string): string | undefined {
|
|
696
|
+
if (stageHasActiveTextPrompt(runId, stageId, promptId) === undefined) return undefined;
|
|
697
|
+
return _stagePromptDrafts.get(stagePromptDraftKey(runId, stageId, promptId));
|
|
698
|
+
},
|
|
699
|
+
|
|
700
|
+
clearStagePromptDraft(runId: string, stageId: string, promptId: string): boolean {
|
|
701
|
+
return _stagePromptDrafts.delete(stagePromptDraftKey(runId, stageId, promptId));
|
|
702
|
+
},
|
|
703
|
+
|
|
657
704
|
getStagePromptAnswer(runId: string, stageId: string): PromptAnswerRecord | undefined {
|
|
658
705
|
return _stagePromptAnswers.get(stagePromptAnswerKey(runId, stageId));
|
|
659
706
|
},
|
|
@@ -896,7 +943,13 @@ export function createStore(): Store {
|
|
|
896
943
|
},
|
|
897
944
|
|
|
898
945
|
clear(): void {
|
|
899
|
-
if (
|
|
946
|
+
if (
|
|
947
|
+
_runs.length === 0 &&
|
|
948
|
+
_notices.length === 0 &&
|
|
949
|
+
_resolvers.size === 0 &&
|
|
950
|
+
_stagePromptAnswers.size === 0 &&
|
|
951
|
+
_stagePromptDrafts.size === 0
|
|
952
|
+
) return;
|
|
900
953
|
_runs.length = 0;
|
|
901
954
|
_notices.length = 0;
|
|
902
955
|
// Reject any outstanding HIL waiters so background promises terminate
|
|
@@ -907,6 +960,7 @@ export function createStore(): Store {
|
|
|
907
960
|
}
|
|
908
961
|
_resolvers.clear();
|
|
909
962
|
_stagePromptAnswers.clear();
|
|
963
|
+
_stagePromptDrafts.clear();
|
|
910
964
|
_version++;
|
|
911
965
|
notify();
|
|
912
966
|
},
|
|
@@ -521,6 +521,7 @@ export class StageChatView implements Component, Focusable {
|
|
|
521
521
|
}
|
|
522
522
|
if (!this.promptState || this.promptState.prompt.id !== prompt.id) {
|
|
523
523
|
this.promptState = createPromptCardState(prompt);
|
|
524
|
+
this._seedPromptTextState(prompt);
|
|
524
525
|
this._resetPromptEditor(prompt);
|
|
525
526
|
this._resetPromptScroll();
|
|
526
527
|
return true;
|
|
@@ -533,19 +534,49 @@ export class StageChatView implements Component, Focusable {
|
|
|
533
534
|
this.promptMaxScroll = 0;
|
|
534
535
|
}
|
|
535
536
|
|
|
537
|
+
private _promptSeedText(prompt: PendingPrompt): string {
|
|
538
|
+
const draft = this.store.getStagePromptDraft(this.runId, this.stageId, prompt.id);
|
|
539
|
+
if (draft !== undefined) return draft;
|
|
540
|
+
return typeof prompt.initial === "string" ? prompt.initial : "";
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
private _seedPromptTextState(prompt: PendingPrompt): void {
|
|
544
|
+
if (prompt.kind !== "input" && prompt.kind !== "editor") return;
|
|
545
|
+
if (!this.promptState || this.promptState.prompt.id !== prompt.id) return;
|
|
546
|
+
const seed = this._promptSeedText(prompt);
|
|
547
|
+
this.promptState.rawText = seed;
|
|
548
|
+
this.promptState.caret = seed.length;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
private _recordPromptDraft(promptId: string, text: string): void {
|
|
552
|
+
this.store.recordStagePromptDraft(this.runId, this.stageId, promptId, text);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
private _recordCurrentPromptDraft(): void {
|
|
556
|
+
const state = this.promptState;
|
|
557
|
+
if (!state) return;
|
|
558
|
+
const prompt = state.prompt;
|
|
559
|
+
if (prompt.kind !== "input" && prompt.kind !== "editor") return;
|
|
560
|
+
const text = this.promptEditor && this.promptEditorPromptId === prompt.id
|
|
561
|
+
? this.promptEditor.getText()
|
|
562
|
+
: state.rawText;
|
|
563
|
+
this._recordPromptDraft(prompt.id, text);
|
|
564
|
+
}
|
|
565
|
+
|
|
536
566
|
private _resetPromptEditor(prompt: PendingPrompt): void {
|
|
537
567
|
this._disposePromptEditor();
|
|
538
568
|
if ((prompt.kind !== "input" && prompt.kind !== "editor") || !this.piTui) return;
|
|
539
569
|
const editor = this.piEditorFactory
|
|
540
570
|
? this.piEditorFactory(this.piTui, editorThemeFromGraphTheme(this.theme), this.piKeybindings)
|
|
541
571
|
: new Editor(this.piTui, editorThemeFromGraphTheme(this.theme), { paddingX: 0 });
|
|
542
|
-
editor.setText(
|
|
572
|
+
editor.setText(this.promptState?.prompt.id === prompt.id ? this.promptState.rawText : this._promptSeedText(prompt));
|
|
543
573
|
setEditorPlaceholder(editor, "Type your response…");
|
|
544
574
|
setEditorBorderColor(editor, (text) => hexToAnsi(this.theme.accent) + text + RESET);
|
|
545
575
|
editor.onChange = (text: string) => {
|
|
546
576
|
if (this.promptState?.prompt.id !== prompt.id) return;
|
|
547
577
|
this.promptState.rawText = text;
|
|
548
578
|
this.promptState.caret = text.length;
|
|
579
|
+
this._recordPromptDraft(prompt.id, text);
|
|
549
580
|
this.requestRender?.();
|
|
550
581
|
};
|
|
551
582
|
editor.onSubmit = (text: string) => {
|
|
@@ -1248,11 +1279,14 @@ export class StageChatView implements Component, Focusable {
|
|
|
1248
1279
|
return;
|
|
1249
1280
|
}
|
|
1250
1281
|
const action = handlePromptCardInput(data, state, this._promptKeybindings());
|
|
1282
|
+
const prompt = state.prompt;
|
|
1283
|
+
if (prompt.kind === "input" || prompt.kind === "editor") {
|
|
1284
|
+
this._recordPromptDraft(prompt.id, state.rawText);
|
|
1285
|
+
}
|
|
1251
1286
|
if (action.kind === "noop") {
|
|
1252
1287
|
this.requestRender?.();
|
|
1253
1288
|
return;
|
|
1254
1289
|
}
|
|
1255
|
-
const prompt = state.prompt;
|
|
1256
1290
|
const response = action.kind === "submit"
|
|
1257
1291
|
? action.response
|
|
1258
1292
|
: defaultResponseFor(prompt);
|
|
@@ -1306,6 +1340,7 @@ export class StageChatView implements Component, Focusable {
|
|
|
1306
1340
|
const readOnlyPromptArchive = readOnlyArchive && stage?.promptFootprint !== undefined;
|
|
1307
1341
|
if (matchesKey(data, Key.ctrl("d"))) {
|
|
1308
1342
|
if (!this.promptState && this.chatHost.hasInputText()) return this.chatHost.handleInput(data);
|
|
1343
|
+
this._recordCurrentPromptDraft();
|
|
1309
1344
|
this.onDetach();
|
|
1310
1345
|
return true;
|
|
1311
1346
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atomic-guide-command.d.ts","sourceRoot":"","sources":["../../src/core/atomic-guide-command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG/D,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,eAAO,MAAM,gCAAgC,qCACT,CAAC;AAqNrC,QAAA,MAAM,cAAc;mBAEV,UAAU;;oBAET,UAAU;0BACJ,oBAAoB;;;mBAI3B,WAAW;;oBAEV,WAAW;0BACL,iBAAiB;;;mBAIxB,SAAS;;oBAER,SAAS;0BACH,0BAA0B;;;mBAIjC,WAAW;;oBAEV,YAAY;0BACN,sBAAsB;;EASpC,CAAC;AAEJ,KAAK,kBAAkB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAC1D,KAAK,sBAAsB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAEzD,MAAM,MAAM,qBAAqB,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAEhE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,sBAAsB,CAAC;AAE9D,eAAO,MAAM,yBAAyB,EAAE,SAAS,qBAAqB,EACtB,CAAC;AAiBjD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,GACb,MAAM,IAAI,qBAAqB,CAEjC;AAoCD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAOtE;AAED,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,MAAM,GACb,gBAAgB,EAAE,GAAG,IAAI,CAa3B;AAED,iBAAS,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CActD;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,eAAe,EACrB,GAAG,EAAE,MAAM,GACV,MAAM,CAGR;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,qBAAqB,GAC5B,eAAe,CAEjB","sourcesContent":["import * as path from \"node:path\";\nimport type { AutocompleteItem } from \"@earendil-works/pi-tui\";\nimport { getChangelogPath, parseChangelog } from \"../utils/changelog.ts\";\n\nexport const ATOMIC_GUIDE_COMMAND_NAME = \"atomic\";\nexport const ATOMIC_GUIDE_COMMAND_DESCRIPTION =\n \"Atomic onboarding and help guide\";\n\nconst OVERVIEW = `# Atomic overview\n\nAtomic turns one-off prompts into developer workflows: on-call debugging, repo research that turns into implementation, testing and review loops, and larger multi-stage automation. Use \\`/workflow goal\\` for small-to-medium changes with a clear work surface, exact outcome, and named validation; keep \\`/workflow ralph\\` for larger migrations, broad refactors, and spec-to-PR work. Start Atomic in a project with \\`atomic\\`, then talk to it normally. Use \\`@file\\` to attach files, \\`!command\\` to run shell output through the model, and \\`!!command\\` to run shell output without adding it to context.\n\n## Core session commands\n\n| Command | Use |\n|---|---|\n| \\`/login\\` | configure auth |\n| \\`/model\\` | switch model |\n| \\`/settings\\` | thinking level, theme, message delivery, transport |\n| \\`/new\\`, \\`/resume\\` | start or resume sessions |\n| \\`/tree\\`, \\`/fork\\`, \\`/clone\\` | branch or navigate session history |\n| \\`/compact\\` | summarize older context |\n| \\`/hotkeys\\`, \\`/changelog\\` | local help and release notes |\n\n## Examples of using Atomic\n\n| Goal | How to use |\n|---|---|\n| On-call / broken behavior | Run \\`/run debugger \"Reproduce the failure, patch the root cause, and validate it\"\\` for a focused fix loop, or ask Atomic in chat to build a reusable workflow that does the same |\n| Research → spec → implementation | Chain \\`/skill:research-codebase\\` → \\`/skill:create-spec\\` → \\`/workflow goal objective=\"...\"\\` for bounded scoped work with explicit validation; use \\`/workflow ralph ...\\` when the work needs planning, broad refactoring, or PR prep |\n| Testing / regression hardening | Run \\`/skill:tdd\\` for test-first work, then \\`/parallel-review current diff\\`, then land the change |\n| Large repo discovery | Run \\`/parallel codebase-locator \"map the area\" -> codebase-analyzer \"trace the current flow\" -> codebase-pattern-finder \"find patterns\" --bg\\`, or \\`/workflow deep-research-codebase\\` for whole-repo synthesis |\n| UI / product polish | Run \\`/skill:impeccable\\` for interface critique and refinement, or \\`/workflow open-claude-design\\` for generation + refinement loops |\n\n## Built-in workflows\n\n| Workflow | When to use | How to run |\n|---|---|---|\n| \\`deep-research-codebase\\` | broad repo or cross-cutting research before you decide what to change (for one area, use \\`/skill:research-codebase\\`; this indexes the whole repo) | \\`/workflow deep-research-codebase prompt=\"How do payment retries work end to end?\"\\` |\n| \\`goal\\` | small-to-medium scoped changes when you can name the work surface, outcome, and validation; keeps receipts in a ledger and stops as \\`complete\\`, \\`blocked\\`, or \\`needs_human\\` | \\`/workflow goal objective=\"Implement specs/<date>-<topic>.md, run focused tests, and validate the changed behavior\"\\` |\n| \\`ralph\\` | larger migrations, broad refactors, multi-package changes, and spec-to-PR work where you want Atomic to plan, delegate, simplify, review, iterate, and prepare a PR report | \\`/workflow ralph prompt=\"Plan and implement specs/<date>-<topic>.md, then prepare the PR\"\\` |\n| \\`open-claude-design\\` | UI and design-system work that benefits from generation and refinement loops | \\`/workflow open-claude-design prompt=\"Refresh the settings page hierarchy\"\\` |\n\nUse \\`/workflow list\\` to see what is available and \\`/workflow inputs <name>\\` to inspect inputs in your environment.\n\n## Top skills\n\n| Skill | When to use | How to run |\n|---|---|---|\n| \\`research-codebase\\` | write a grounded research artifact for one subsystem or question | \\`/skill:research-codebase how the rate limiter works in src/middleware/\\` |\n| \\`create-spec\\` | turn research into an implementation-ready plan | \\`/skill:create-spec from research/docs/<date>-<topic>.md\\` |\n| \\`tdd\\` | do test-first feature or bug work | \\`/skill:tdd\\` |\n| \\`prompt-engineer\\` | tighten a vague prompt before a long run | \\`/skill:prompt-engineer Draft a sharper implementation prompt for ...\\` |\n| \\`subagent\\` | learn delegation patterns and exact \\`/run\\`, \\`/parallel\\`, and \\`/chain\\` usage | \\`/skill:subagent\\` |\n| \\`impeccable\\` | critique or refine frontend and product UI | \\`/skill:impeccable\\` |\n\n## Subagents\n\nSubagents are focused child Atomic sessions you can point at one job inside the repo.\n\n| Built-in subagent | Use |\n|---|---|\n| \\`codebase-locator\\` | find relevant files, tests, entrypoints, and configs |\n| \\`codebase-analyzer\\` | explain current behavior with file:line refs |\n| \\`codebase-pattern-finder\\` | find existing code to model after |\n| \\`debugger\\` | reproduce, diagnose, and fix broken behavior |\n\nHow the direct commands map to repo work:\n- \\`/run\\` = one specialist on one job, for example \\`/run codebase-locator \"Map the webhook retry flow\"\\`\n- \\`/parallel\\` = several independent specialists at once, for example \\`/parallel codebase-locator \"map retry files\" -> codebase-pattern-finder \"find existing retry/backoff patterns\" -> codebase-online-researcher \"research current retry guidance\" --bg\\`\n- \\`/chain\\` = ordered handoffs, for example \\`/chain codebase-locator \"find the auth files\" -> codebase-analyzer \"trace the auth flow\" -> debugger \"patch the failing auth edge case\"\\`\n\n─────────────────────────────────────────────────────────────────\n\nWhere to next:\n\n\\`/atomic example\\` — see the pieces used on a code task\n\\`/atomic workflows\\` — learn when to use workflows`;\n\nconst EXAMPLE = `# Practical example\n\nThis is an example of a spec-driven development process using Atomic workflows. Use it when you are new to a repo or the task has non-trivial scope. Type the examples below into the Atomic TUI chat after starting \\`atomic\\` in your project.\n\n## 1. Research what exists\n\nUse \\`/skill:research-codebase\\` for a scoped area, subsystem, or directory:\n\n\\`/skill:research-codebase how the rate limiter works in src/middleware/\\`\n\nUse \\`deep-research-codebase\\` when the answer spans the whole repo or a cross-cutting implementation path:\n\n\\`/workflow deep-research-codebase prompt=\"How do payment retries work end to end?\"\\`\n\nIf the research prompt is vague, tighten it first with \\`/skill:prompt-engineer\\`:\n\n\\`/skill:prompt-engineer Draft a sharper repo-research prompt for understanding payment retries end to end, including retries, queues, and failure handling.\\`\n\n## 2. Create a spec when requirements are fuzzy\n\nSkip this if the implementation request is already precise.\n\n\\`/skill:create-spec from research/docs/<date>-<topic>.md\\`\n\n## 3. Implement with review built in\n\nFor ordinary work, ask Atomic directly and require validation:\n\n\\`Implement the approved spec in specs/<date>-<topic>.md. Run focused tests and summarize validation.\\`\n\nFor small-to-medium scoped changes where you can identify the work surface, exact outcome, and validation, use \\`goal\\`:\n\n\\`/workflow goal objective=\"Implement specs/<date>-<topic>.md, run focused tests, and finish when the documented behavior is validated\"\\`\n\nFor larger migrations, broad refactors, multi-package changes, or spec-to-PR work, use \\`ralph\\`:\n\n\\`/workflow ralph prompt=\"Plan and implement specs/<date>-<topic>.md, then prepare the PR\"\\`\n\n## 4. Decide and land\n\nIf you used \\`goal\\`, the workflow already persisted receipts in a goal ledger and reviewer-gated completion. Use its final status — \\`complete\\`, \\`blocked\\`, or \\`needs_human\\` — plus the remaining-work report to decide whether to ship, unblock, or clarify.\n\nIf you used \\`ralph\\`, the workflow planned the approach, delegated implementation through sub-agents, simplified, reviewed, iterated, and prepared a pull-request report. Use its review feedback and PR report to decide whether to ship or iterate again.\n\nIf you implemented directly instead of using a workflow, you can still run:\n\n\\`/parallel-review current diff\\`\n\nAtomic will synthesize reviewer feedback and ask before applying fixes.\n\n─────────────────────────────────────────────────────────────────\n\nWhere to next:\n\n\\`/atomic workflows\\` — learn when to use workflows\n\\`/atomic overview\\` — quick refresh`;\n\nconst WORKFLOWS = `# Workflows primer\n\nA workflow is a TypeScript-defined pipeline exported from \\`defineWorkflow(...).compile()\\`. It can run tasks, chains, parallel fan-out, human-in-the-loop prompts, background status, and model fallback chains.\n\nYou do not have to write TypeScript to add one. Describe the workflow you want in plain chat — goal, inputs, stages, which steps are parallel or sequential, handoff/output shape, and any model or thinking-level preferences — and Atomic will use the workflow docs to scaffold a reusable definition under \\`.atomic/workflows/\\` and reload it for you. Hand-edit the TypeScript afterward when you want precise control.\n\n## Built-in workflows\n\n| Workflow | When to use | How to run |\n|---|---|---|\n| \\`deep-research-codebase\\` | broad repo or cross-cutting research before you decide what to change (for one area, use \\`/skill:research-codebase\\`; this indexes the whole repo) | \\`/workflow deep-research-codebase prompt=\"How do payment retries work end to end?\"\\` |\n| \\`goal\\` | small-to-medium scoped changes with a clear outcome and named validation | \\`/workflow goal objective=\"Update the CLI docs, include one usage example, and verify the docs build passes\"\\` |\n| \\`ralph\\` | larger migrations, broad refactors, multi-package changes, and spec-to-PR work | \\`/workflow ralph prompt=\"Plan a database-layer migration, implement it, review it, and prepare the PR\"\\` |\n| \\`open-claude-design\\` | frontend and product design work | \\`/workflow open-claude-design prompt=\"Refresh the settings page hierarchy\"\\` |\n\nUse \\`/workflow inputs <name>\\` to inspect the exact inputs in your environment.\n\nUse \\`/skill:research-codebase ...\\` when you want research on one subsystem, directory, or focused question. Use \\`/workflow deep-research-codebase ...\\` when the answer needs end-to-end tracing across many parts of the repo.\n\nIf you are drafting research, reviewer, or synthesis prompts for a workflow, use \\`/skill:prompt-engineer\\` first. It is a good fit when a stage prompt feels vague, overloaded, or underspecified.\n\n## What good workflow authoring looks like\n\nA good workflow request is explicit about stage purpose, model choice, handoff, and the decision each step must return.\n\nExample: ask Atomic in chat with something like this:\n\n~~~text\nCreate a reusable workflow called review-changes.\n\nIt should accept one required text input called target for a diff, PR summary, or review target.\n\nRun two independent review stages in parallel with fresh context:\n- one reviewer focused on correctness, regressions, and missing tests using openai-codex/gpt-5.5 at xhigh thinking\n- one reviewer focused on edge cases, maintainability, and hidden risks using anthropic/claude-opus-4-8 at xhigh thinking\n\nThen add an aggregate stage that consolidates both reviews, deduplicates overlap, keeps only evidence-backed issues, and separates blockers from optional suggestions using openai/gpt-5.5 at high thinking.\n\nFinally add an adjudicate stage using anthropic/claude-sonnet-4 at high thinking that decides what to fix now, what to defer, and what to reject. Return a short action list with rationale.\n\nThe workflow should return structured output with consolidated_review and decision fields.\n~~~\n\nWhy this is good:\n- it names the workflow and required input\n- it specifies which stages are parallel vs sequential\n- each stage has one job\n- it defines the handoff and final outputs\n- it calls out model choice and thinking level where that matters\n\n## Run and inspect\n\n\\`/workflow list\\`\n\n\\`/workflow inputs goal\\`\n\n\\`/workflow goal objective=\"Fix the settings form validation bug, add the focused test, and finish when invalid emails show the inline error without submitting\"\\`\n\n\\`/workflow inputs ralph\\`\n\n\\`/workflow ralph prompt=\"Migrate the database layer to Drizzle and prepare the PR\"\\`\n\n\\`/workflow status\\`\n\n\\`/workflow connect <run-id>\\`\n\n\\`/workflow interrupt <run-id>\\`\n\n\\`/workflow resume <run-id>\\`\n\nWorkflows run as background tasks. Use F2 or \\`/workflow connect <run-id>\\` for the graph viewer. Human-in-the-loop prompts appear there, not as chat modals, and awaiting-input states do not wake the main chat agent. Completion and failure notices are steered back into the main chat; answers submitted in the workflow UI interrupt stale main-chat questions so the model does not ask again.\n\n## Author your own\n\nDescribe your workflow in plain chat — say what you want the workflow to accomplish, what inputs it should accept, what stages should run, and what final output or decision it should return. Atomic will use the workflow docs to scaffold a reusable definition under \\`.atomic/workflows/\\`, ask clarifying questions when stage purpose, models, or handoffs are ambiguous, and run \\`/workflow reload\\` so you can launch it immediately.\n\n─────────────────────────────────────────────────────────────────\n\nWhere to next:\n\n\\`/atomic example\\` — see workflows in a normal task flow\n\\`/atomic overview\\` — quick refresh`;\n\nconst GUIDE_SECTIONS = [\n {\n name: \"overview\",\n aliases: [],\n label: \"overview\",\n description: \"30-second overview\",\n render: () => OVERVIEW,\n },\n {\n name: \"workflows\",\n aliases: [\"workflow\"],\n label: \"workflows\",\n description: \"Workflow primer\",\n render: () => WORKFLOWS,\n },\n {\n name: \"example\",\n aliases: [\"examples\"],\n label: \"example\",\n description: \"Practical first workflow\",\n render: () => EXAMPLE,\n },\n {\n name: \"whats-new\",\n aliases: [\"what's new\", \"whats new\", \"news\", \"updates\", \"changelog\"],\n label: \"what's new\",\n description: \"Recent release notes\",\n render: readLatestStableChangelog,\n },\n] as const satisfies readonly {\n readonly name: string;\n readonly aliases: readonly string[];\n readonly label: string;\n readonly description: string;\n readonly render: (cwd: string) => string;\n}[];\n\ntype AtomicGuideSection = (typeof GUIDE_SECTIONS)[number];\ntype AtomicGuideSectionName = AtomicGuideSection[\"name\"];\n\nexport type AtomicGuideHelpChoice = AtomicGuideSection[\"label\"];\n\nexport type AtomicGuideMode = \"help\" | AtomicGuideSectionName;\n\nexport const ATOMIC_GUIDE_HELP_CHOICES: readonly AtomicGuideHelpChoice[] =\n GUIDE_SECTIONS.map((section) => section.label);\n\nconst GUIDE_SECTIONS_BY_NAME = new Map<\n AtomicGuideSectionName,\n AtomicGuideSection\n>(GUIDE_SECTIONS.map((section) => [section.name, section]));\nconst GUIDE_SECTIONS_BY_LABEL = new Map<string, AtomicGuideSection>(\n GUIDE_SECTIONS.map((section) => [section.label, section]),\n);\nconst GUIDE_SECTIONS_BY_INPUT = new Map<string, AtomicGuideSection>(\n GUIDE_SECTIONS.flatMap((section) =>\n [section.name, section.label, ...section.aliases].map(\n (input) => [input, section] as const,\n ),\n ),\n);\n\nexport function isAtomicGuideHelpChoice(\n choice: string,\n): choice is AtomicGuideHelpChoice {\n return GUIDE_SECTIONS_BY_LABEL.has(choice);\n}\n\nconst ATOMIC_GUIDE_TRAILING_PUNCTUATION = \"?!.,;:\";\n\nfunction stripTrailingAtomicGuidePunctuation(value: string): string {\n let end = value.length;\n while (\n end > 0 &&\n ATOMIC_GUIDE_TRAILING_PUNCTUATION.includes(value.charAt(end - 1))\n ) {\n end--;\n }\n return value.slice(0, end);\n}\n\nfunction getGuideSectionForChoice(\n choice: string,\n): AtomicGuideSection | undefined {\n return GUIDE_SECTIONS_BY_LABEL.get(choice);\n}\n\nfunction getGuideSectionForMode(\n mode: AtomicGuideSectionName,\n): AtomicGuideSection {\n const section = GUIDE_SECTIONS_BY_NAME.get(mode);\n if (!section) throw new Error(`Unknown Atomic guide section: ${mode}`);\n return section;\n}\n\nfunction getAtomicGuideHelpMenu(): string {\n const sectionHelp = GUIDE_SECTIONS.map(\n (section) => `- \\`${section.label}\\` — run \\`/atomic ${section.label}\\``,\n ).join(\"\\n\");\n return `# Atomic\\n\\nSelect where to start:\\n\\n${sectionHelp}`;\n}\n\nexport function normalizeAtomicGuideMode(args: string): AtomicGuideMode {\n const normalized = stripTrailingAtomicGuidePunctuation(\n args.trim().toLowerCase(),\n );\n if (!normalized) return \"help\";\n\n return GUIDE_SECTIONS_BY_INPUT.get(normalized)?.name ?? \"help\";\n}\n\nexport function getAtomicGuideArgumentCompletions(\n prefix: string,\n): AutocompleteItem[] | null {\n const query = prefix.trim().toLowerCase();\n const items = GUIDE_SECTIONS.map((section) => ({\n value: section.label,\n label: section.label,\n description: section.description,\n }));\n const filtered = query\n ? items.filter(\n (item) => item.value.startsWith(query) || item.label.startsWith(query),\n )\n : items;\n return filtered.length > 0 ? filtered : null;\n}\n\nfunction readLatestStableChangelog(cwd: string): string {\n const changelogPath = getChangelogPath();\n const stableSections = parseChangelog(changelogPath)\n .filter((entry) => entry.prerelease === null)\n .slice(0, 3)\n .map((entry) => entry.content.trim())\n .filter(Boolean);\n\n if (stableSections.length === 0) {\n return `# What's new\\n\\nNo stable release sections were found. Try \\`/changelog\\` for the interactive changelog viewer.\\n\\n─────────────────────────────────────────────────────────────────\\n\\nWhere to next:\\n\\n\\`/atomic example\\` — see a practical first workflow\\n\\`/atomic overview\\` — quick refresh`;\n }\n\n const relativePath = path.relative(cwd, changelogPath) || changelogPath;\n return `# What's new\\n\\n${stableSections.join(\"\\n\\n\")}\\n\\nSource: \\`${relativePath}\\`\\n\\n─────────────────────────────────────────────────────────────────\\n\\nWhere to next:\\n\\n\\`/atomic example\\` — see a practical first workflow\\n\\`/atomic overview\\` — quick refresh`;\n}\n\nexport function getAtomicGuideMessage(\n mode: AtomicGuideMode,\n cwd: string,\n): string {\n if (mode === \"help\") return getAtomicGuideHelpMenu();\n return getGuideSectionForMode(mode).render(cwd);\n}\n\nexport function atomicGuideModeForChoice(\n choice: AtomicGuideHelpChoice,\n): AtomicGuideMode {\n return getGuideSectionForChoice(choice)?.name ?? \"help\";\n}\n"]}
|
|
1
|
+
{"version":3,"file":"atomic-guide-command.d.ts","sourceRoot":"","sources":["../../src/core/atomic-guide-command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG/D,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,eAAO,MAAM,gCAAgC,qCACT,CAAC;AAuNrC,QAAA,MAAM,cAAc;mBAEV,UAAU;;oBAET,UAAU;0BACJ,oBAAoB;;;mBAI3B,WAAW;;oBAEV,WAAW;0BACL,iBAAiB;;;mBAIxB,SAAS;;oBAER,SAAS;0BACH,0BAA0B;;;mBAIjC,WAAW;;oBAEV,YAAY;0BACN,sBAAsB;;EASpC,CAAC;AAEJ,KAAK,kBAAkB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAC1D,KAAK,sBAAsB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAEzD,MAAM,MAAM,qBAAqB,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAEhE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,sBAAsB,CAAC;AAE9D,eAAO,MAAM,yBAAyB,EAAE,SAAS,qBAAqB,EACtB,CAAC;AAiBjD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,GACb,MAAM,IAAI,qBAAqB,CAEjC;AAoCD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAOtE;AAED,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,MAAM,GACb,gBAAgB,EAAE,GAAG,IAAI,CAa3B;AAED,iBAAS,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CActD;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,eAAe,EACrB,GAAG,EAAE,MAAM,GACV,MAAM,CAGR;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,qBAAqB,GAC5B,eAAe,CAEjB","sourcesContent":["import * as path from \"node:path\";\nimport type { AutocompleteItem } from \"@earendil-works/pi-tui\";\nimport { getChangelogPath, parseChangelog } from \"../utils/changelog.ts\";\n\nexport const ATOMIC_GUIDE_COMMAND_NAME = \"atomic\";\nexport const ATOMIC_GUIDE_COMMAND_DESCRIPTION =\n \"Atomic onboarding and help guide\";\n\nconst OVERVIEW = `# Atomic overview\n\nAtomic turns one-off prompts into developer workflows: on-call debugging, repo research that turns into implementation, testing and review loops, and larger multi-stage automation. Use \\`/workflow goal\\` for small-to-medium changes with a clear work surface, exact outcome, and named validation; keep \\`/workflow ralph\\` for larger migrations, broad refactors, and spec-to-reviewed-change work. Start Atomic in a project with \\`atomic\\`, then talk to it normally. Use \\`@file\\` to attach files, \\`!command\\` to run shell output through the model, and \\`!!command\\` to run shell output without adding it to context.\n\n## Core session commands\n\n| Command | Use |\n|---|---|\n| \\`/login\\` | configure auth |\n| \\`/model\\` | switch model |\n| \\`/settings\\` | thinking level, theme, message delivery, transport |\n| \\`/new\\`, \\`/resume\\` | start or resume sessions |\n| \\`/tree\\`, \\`/fork\\`, \\`/clone\\` | branch or navigate session history |\n| \\`/compact\\` | summarize older context |\n| \\`/hotkeys\\`, \\`/changelog\\` | local help and release notes |\n\n## Examples of using Atomic\n\n| Goal | How to use |\n|---|---|\n| On-call / broken behavior | Run \\`/run debugger \"Reproduce the failure, patch the root cause, and validate it\"\\` for a focused fix loop, or ask Atomic in chat to build a reusable workflow that does the same |\n| Research → spec → implementation | Chain \\`/skill:research-codebase\\` → \\`/skill:create-spec\\` → \\`/workflow goal objective=\"...\"\\` for bounded scoped work with explicit validation; use \\`/workflow ralph ...\\` when the work needs planning, broad refactoring, or final-stage PR prep with \\`create_pr=true\\` |\n| Testing / regression hardening | Run \\`/skill:tdd\\` for test-first work, then \\`/parallel-review current diff\\`, then land the change |\n| Large repo discovery | Run \\`/parallel codebase-locator \"map the area\" -> codebase-analyzer \"trace the current flow\" -> codebase-pattern-finder \"find patterns\" --bg\\`, or \\`/workflow deep-research-codebase\\` for whole-repo synthesis |\n| UI / product polish | Run \\`/skill:impeccable\\` for interface critique and refinement, or \\`/workflow open-claude-design\\` for generation + refinement loops |\n\n## Built-in workflows\n\n| Workflow | When to use | How to run |\n|---|---|---|\n| \\`deep-research-codebase\\` | broad repo or cross-cutting research before you decide what to change (for one area, use \\`/skill:research-codebase\\`; this indexes the whole repo) | \\`/workflow deep-research-codebase prompt=\"How do payment retries work end to end?\"\\` |\n| \\`goal\\` | small-to-medium scoped changes when you can name the work surface, outcome, and validation; keeps receipts in a ledger and stops as \\`complete\\`, \\`blocked\\`, or \\`needs_human\\` | \\`/workflow goal objective=\"Implement specs/<date>-<topic>.md, run focused tests, and validate the changed behavior\"\\` |\n| \\`ralph\\` | larger migrations, broad refactors, multi-package changes, and spec-to-reviewed-change work where you want Atomic to plan, delegate, simplify, review, and iterate; add \\`create_pr=true\\` only when you want the final pull-request stage and report | \\`/workflow ralph prompt=\"Plan and implement specs/<date>-<topic>.md\" create_pr=true\\` |\n| \\`open-claude-design\\` | UI and design-system work that benefits from generation and refinement loops | \\`/workflow open-claude-design prompt=\"Refresh the settings page hierarchy\"\\` |\n\nUse \\`/workflow list\\` to see what is available and \\`/workflow inputs <name>\\` to inspect inputs in your environment.\n\n## Top skills\n\n| Skill | When to use | How to run |\n|---|---|---|\n| \\`research-codebase\\` | write a grounded research artifact for one subsystem or question | \\`/skill:research-codebase how the rate limiter works in src/middleware/\\` |\n| \\`create-spec\\` | turn research into an implementation-ready plan | \\`/skill:create-spec from research/docs/<date>-<topic>.md\\` |\n| \\`tdd\\` | do test-first feature or bug work | \\`/skill:tdd\\` |\n| \\`prompt-engineer\\` | tighten a vague prompt before a long run | \\`/skill:prompt-engineer Draft a sharper implementation prompt for ...\\` |\n| \\`subagent\\` | learn delegation patterns and exact \\`/run\\`, \\`/parallel\\`, and \\`/chain\\` usage | \\`/skill:subagent\\` |\n| \\`impeccable\\` | critique or refine frontend and product UI | \\`/skill:impeccable\\` |\n\n## Subagents\n\nSubagents are focused child Atomic sessions you can point at one job inside the repo.\n\n| Built-in subagent | Use |\n|---|---|\n| \\`codebase-locator\\` | find relevant files, tests, entrypoints, and configs |\n| \\`codebase-analyzer\\` | explain current behavior with file:line refs |\n| \\`codebase-pattern-finder\\` | find existing code to model after |\n| \\`debugger\\` | reproduce, diagnose, and fix broken behavior |\n\nHow the direct commands map to repo work:\n- \\`/run\\` = one specialist on one job, for example \\`/run codebase-locator \"Map the webhook retry flow\"\\`\n- \\`/parallel\\` = several independent specialists at once, for example \\`/parallel codebase-locator \"map retry files\" -> codebase-pattern-finder \"find existing retry/backoff patterns\" -> codebase-online-researcher \"research current retry guidance\" --bg\\`\n- \\`/chain\\` = ordered handoffs, for example \\`/chain codebase-locator \"find the auth files\" -> codebase-analyzer \"trace the auth flow\" -> debugger \"patch the failing auth edge case\"\\`\n\n─────────────────────────────────────────────────────────────────\n\nWhere to next:\n\n\\`/atomic example\\` — see the pieces used on a code task\n\\`/atomic workflows\\` — learn when to use workflows`;\n\nconst EXAMPLE = `# Practical example\n\nThis is an example of a spec-driven development process using Atomic workflows. Use it when you are new to a repo or the task has non-trivial scope. Type the examples below into the Atomic TUI chat after starting \\`atomic\\` in your project.\n\n## 1. Research what exists\n\nUse \\`/skill:research-codebase\\` for a scoped area, subsystem, or directory:\n\n\\`/skill:research-codebase how the rate limiter works in src/middleware/\\`\n\nUse \\`deep-research-codebase\\` when the answer spans the whole repo or a cross-cutting implementation path:\n\n\\`/workflow deep-research-codebase prompt=\"How do payment retries work end to end?\"\\`\n\nIf the research prompt is vague, tighten it first with \\`/skill:prompt-engineer\\`:\n\n\\`/skill:prompt-engineer Draft a sharper repo-research prompt for understanding payment retries end to end, including retries, queues, and failure handling.\\`\n\n## 2. Create a spec when requirements are fuzzy\n\nSkip this if the implementation request is already precise.\n\n\\`/skill:create-spec from research/docs/<date>-<topic>.md\\`\n\n## 3. Implement with review built in\n\nFor ordinary work, ask Atomic directly and require validation:\n\n\\`Implement the approved spec in specs/<date>-<topic>.md. Run focused tests and summarize validation.\\`\n\nFor small-to-medium scoped changes where you can identify the work surface, exact outcome, and validation, use \\`goal\\`:\n\n\\`/workflow goal objective=\"Implement specs/<date>-<topic>.md, run focused tests, and finish when the documented behavior is validated\"\\`\n\nFor larger migrations, broad refactors, multi-package changes, or spec-to-reviewed-change work, use \\`ralph\\`:\n\n\\`/workflow ralph prompt=\"Plan and implement specs/<date>-<topic>.md\"\\`\n\nAdd \\`create_pr=true\\` only when you want Ralph's final pull-request stage and report.\n\n## 4. Decide and land\n\nIf you used \\`goal\\`, the workflow already persisted receipts in a goal ledger and reviewer-gated completion. Use its final status — \\`complete\\`, \\`blocked\\`, or \\`needs_human\\` — plus the remaining-work report to decide whether to ship, unblock, or clarify.\n\nIf you used \\`ralph\\`, the workflow planned the approach, delegated implementation through sub-agents, simplified, reviewed, and iterated. If you enabled \\`create_pr=true\\`, use its final pull-request report to decide whether to ship or iterate again.\n\nIf you implemented directly instead of using a workflow, you can still run:\n\n\\`/parallel-review current diff\\`\n\nAtomic will synthesize reviewer feedback and ask before applying fixes.\n\n─────────────────────────────────────────────────────────────────\n\nWhere to next:\n\n\\`/atomic workflows\\` — learn when to use workflows\n\\`/atomic overview\\` — quick refresh`;\n\nconst WORKFLOWS = `# Workflows primer\n\nA workflow is a TypeScript-defined pipeline exported from \\`defineWorkflow(...).compile()\\`. It can run tasks, chains, parallel fan-out, human-in-the-loop prompts, background status, and model fallback chains.\n\nYou do not have to write TypeScript to add one. Describe the workflow you want in plain chat — goal, inputs, stages, which steps are parallel or sequential, handoff/output shape, and any model or thinking-level preferences — and Atomic will use the workflow docs to scaffold a reusable definition under \\`.atomic/workflows/\\` and reload it for you. Hand-edit the TypeScript afterward when you want precise control.\n\n## Built-in workflows\n\n| Workflow | When to use | How to run |\n|---|---|---|\n| \\`deep-research-codebase\\` | broad repo or cross-cutting research before you decide what to change (for one area, use \\`/skill:research-codebase\\`; this indexes the whole repo) | \\`/workflow deep-research-codebase prompt=\"How do payment retries work end to end?\"\\` |\n| \\`goal\\` | small-to-medium scoped changes with a clear outcome and named validation | \\`/workflow goal objective=\"Update the CLI docs, include one usage example, and verify the docs build passes\"\\` |\n| \\`ralph\\` | larger migrations, broad refactors, multi-package changes, and spec-to-reviewed-change work | \\`/workflow ralph prompt=\"Plan a database-layer migration, implement it, and review it\" create_pr=true\\` |\n| \\`open-claude-design\\` | frontend and product design work | \\`/workflow open-claude-design prompt=\"Refresh the settings page hierarchy\"\\` |\n\nUse \\`/workflow inputs <name>\\` to inspect the exact inputs in your environment.\n\nUse \\`/skill:research-codebase ...\\` when you want research on one subsystem, directory, or focused question. Use \\`/workflow deep-research-codebase ...\\` when the answer needs end-to-end tracing across many parts of the repo.\n\nIf you are drafting research, reviewer, or synthesis prompts for a workflow, use \\`/skill:prompt-engineer\\` first. It is a good fit when a stage prompt feels vague, overloaded, or underspecified.\n\n## What good workflow authoring looks like\n\nA good workflow request is explicit about stage purpose, model choice, handoff, and the decision each step must return.\n\nExample: ask Atomic in chat with something like this:\n\n~~~text\nCreate a reusable workflow called review-changes.\n\nIt should accept one required text input called target for a diff, PR summary, or review target.\n\nRun two independent review stages in parallel with fresh context:\n- one reviewer focused on correctness, regressions, and missing tests using openai-codex/gpt-5.5 at xhigh thinking\n- one reviewer focused on edge cases, maintainability, and hidden risks using anthropic/claude-opus-4-8 at xhigh thinking\n\nThen add an aggregate stage that consolidates both reviews, deduplicates overlap, keeps only evidence-backed issues, and separates blockers from optional suggestions using openai/gpt-5.5 at high thinking.\n\nFinally add an adjudicate stage using anthropic/claude-sonnet-4 at high thinking that decides what to fix now, what to defer, and what to reject. Return a short action list with rationale.\n\nThe workflow should return structured output with consolidated_review and decision fields.\n~~~\n\nWhy this is good:\n- it names the workflow and required input\n- it specifies which stages are parallel vs sequential\n- each stage has one job\n- it defines the handoff and final outputs\n- it calls out model choice and thinking level where that matters\n\n## Run and inspect\n\n\\`/workflow list\\`\n\n\\`/workflow inputs goal\\`\n\n\\`/workflow goal objective=\"Fix the settings form validation bug, add the focused test, and finish when invalid emails show the inline error without submitting\"\\`\n\n\\`/workflow inputs ralph\\`\n\n\\`/workflow ralph prompt=\"Migrate the database layer to Drizzle\" create_pr=true\\`\n\n\\`/workflow status\\`\n\n\\`/workflow connect <run-id>\\`\n\n\\`/workflow interrupt <run-id>\\`\n\n\\`/workflow resume <run-id>\\`\n\nWorkflows run as background tasks. Use F2 or \\`/workflow connect <run-id>\\` for the graph viewer. Human-in-the-loop prompts appear there, not as chat modals, and awaiting-input states do not wake the main chat agent. Completion and failure notices are steered back into the main chat; answers submitted in the workflow UI interrupt stale main-chat questions so the model does not ask again.\n\n## Author your own\n\nDescribe your workflow in plain chat — say what you want the workflow to accomplish, what inputs it should accept, what stages should run, and what final output or decision it should return. Atomic will use the workflow docs to scaffold a reusable definition under \\`.atomic/workflows/\\`, ask clarifying questions when stage purpose, models, or handoffs are ambiguous, and run \\`/workflow reload\\` so you can launch it immediately.\n\n─────────────────────────────────────────────────────────────────\n\nWhere to next:\n\n\\`/atomic example\\` — see workflows in a normal task flow\n\\`/atomic overview\\` — quick refresh`;\n\nconst GUIDE_SECTIONS = [\n {\n name: \"overview\",\n aliases: [],\n label: \"overview\",\n description: \"30-second overview\",\n render: () => OVERVIEW,\n },\n {\n name: \"workflows\",\n aliases: [\"workflow\"],\n label: \"workflows\",\n description: \"Workflow primer\",\n render: () => WORKFLOWS,\n },\n {\n name: \"example\",\n aliases: [\"examples\"],\n label: \"example\",\n description: \"Practical first workflow\",\n render: () => EXAMPLE,\n },\n {\n name: \"whats-new\",\n aliases: [\"what's new\", \"whats new\", \"news\", \"updates\", \"changelog\"],\n label: \"what's new\",\n description: \"Recent release notes\",\n render: readLatestStableChangelog,\n },\n] as const satisfies readonly {\n readonly name: string;\n readonly aliases: readonly string[];\n readonly label: string;\n readonly description: string;\n readonly render: (cwd: string) => string;\n}[];\n\ntype AtomicGuideSection = (typeof GUIDE_SECTIONS)[number];\ntype AtomicGuideSectionName = AtomicGuideSection[\"name\"];\n\nexport type AtomicGuideHelpChoice = AtomicGuideSection[\"label\"];\n\nexport type AtomicGuideMode = \"help\" | AtomicGuideSectionName;\n\nexport const ATOMIC_GUIDE_HELP_CHOICES: readonly AtomicGuideHelpChoice[] =\n GUIDE_SECTIONS.map((section) => section.label);\n\nconst GUIDE_SECTIONS_BY_NAME = new Map<\n AtomicGuideSectionName,\n AtomicGuideSection\n>(GUIDE_SECTIONS.map((section) => [section.name, section]));\nconst GUIDE_SECTIONS_BY_LABEL = new Map<string, AtomicGuideSection>(\n GUIDE_SECTIONS.map((section) => [section.label, section]),\n);\nconst GUIDE_SECTIONS_BY_INPUT = new Map<string, AtomicGuideSection>(\n GUIDE_SECTIONS.flatMap((section) =>\n [section.name, section.label, ...section.aliases].map(\n (input) => [input, section] as const,\n ),\n ),\n);\n\nexport function isAtomicGuideHelpChoice(\n choice: string,\n): choice is AtomicGuideHelpChoice {\n return GUIDE_SECTIONS_BY_LABEL.has(choice);\n}\n\nconst ATOMIC_GUIDE_TRAILING_PUNCTUATION = \"?!.,;:\";\n\nfunction stripTrailingAtomicGuidePunctuation(value: string): string {\n let end = value.length;\n while (\n end > 0 &&\n ATOMIC_GUIDE_TRAILING_PUNCTUATION.includes(value.charAt(end - 1))\n ) {\n end--;\n }\n return value.slice(0, end);\n}\n\nfunction getGuideSectionForChoice(\n choice: string,\n): AtomicGuideSection | undefined {\n return GUIDE_SECTIONS_BY_LABEL.get(choice);\n}\n\nfunction getGuideSectionForMode(\n mode: AtomicGuideSectionName,\n): AtomicGuideSection {\n const section = GUIDE_SECTIONS_BY_NAME.get(mode);\n if (!section) throw new Error(`Unknown Atomic guide section: ${mode}`);\n return section;\n}\n\nfunction getAtomicGuideHelpMenu(): string {\n const sectionHelp = GUIDE_SECTIONS.map(\n (section) => `- \\`${section.label}\\` — run \\`/atomic ${section.label}\\``,\n ).join(\"\\n\");\n return `# Atomic\\n\\nSelect where to start:\\n\\n${sectionHelp}`;\n}\n\nexport function normalizeAtomicGuideMode(args: string): AtomicGuideMode {\n const normalized = stripTrailingAtomicGuidePunctuation(\n args.trim().toLowerCase(),\n );\n if (!normalized) return \"help\";\n\n return GUIDE_SECTIONS_BY_INPUT.get(normalized)?.name ?? \"help\";\n}\n\nexport function getAtomicGuideArgumentCompletions(\n prefix: string,\n): AutocompleteItem[] | null {\n const query = prefix.trim().toLowerCase();\n const items = GUIDE_SECTIONS.map((section) => ({\n value: section.label,\n label: section.label,\n description: section.description,\n }));\n const filtered = query\n ? items.filter(\n (item) => item.value.startsWith(query) || item.label.startsWith(query),\n )\n : items;\n return filtered.length > 0 ? filtered : null;\n}\n\nfunction readLatestStableChangelog(cwd: string): string {\n const changelogPath = getChangelogPath();\n const stableSections = parseChangelog(changelogPath)\n .filter((entry) => entry.prerelease === null)\n .slice(0, 3)\n .map((entry) => entry.content.trim())\n .filter(Boolean);\n\n if (stableSections.length === 0) {\n return `# What's new\\n\\nNo stable release sections were found. Try \\`/changelog\\` for the interactive changelog viewer.\\n\\n─────────────────────────────────────────────────────────────────\\n\\nWhere to next:\\n\\n\\`/atomic example\\` — see a practical first workflow\\n\\`/atomic overview\\` — quick refresh`;\n }\n\n const relativePath = path.relative(cwd, changelogPath) || changelogPath;\n return `# What's new\\n\\n${stableSections.join(\"\\n\\n\")}\\n\\nSource: \\`${relativePath}\\`\\n\\n─────────────────────────────────────────────────────────────────\\n\\nWhere to next:\\n\\n\\`/atomic example\\` — see a practical first workflow\\n\\`/atomic overview\\` — quick refresh`;\n}\n\nexport function getAtomicGuideMessage(\n mode: AtomicGuideMode,\n cwd: string,\n): string {\n if (mode === \"help\") return getAtomicGuideHelpMenu();\n return getGuideSectionForMode(mode).render(cwd);\n}\n\nexport function atomicGuideModeForChoice(\n choice: AtomicGuideHelpChoice,\n): AtomicGuideMode {\n return getGuideSectionForChoice(choice)?.name ?? \"help\";\n}\n"]}
|
|
@@ -4,7 +4,7 @@ export const ATOMIC_GUIDE_COMMAND_NAME = "atomic";
|
|
|
4
4
|
export const ATOMIC_GUIDE_COMMAND_DESCRIPTION = "Atomic onboarding and help guide";
|
|
5
5
|
const OVERVIEW = `# Atomic overview
|
|
6
6
|
|
|
7
|
-
Atomic turns one-off prompts into developer workflows: on-call debugging, repo research that turns into implementation, testing and review loops, and larger multi-stage automation. Use \`/workflow goal\` for small-to-medium changes with a clear work surface, exact outcome, and named validation; keep \`/workflow ralph\` for larger migrations, broad refactors, and spec-to-
|
|
7
|
+
Atomic turns one-off prompts into developer workflows: on-call debugging, repo research that turns into implementation, testing and review loops, and larger multi-stage automation. Use \`/workflow goal\` for small-to-medium changes with a clear work surface, exact outcome, and named validation; keep \`/workflow ralph\` for larger migrations, broad refactors, and spec-to-reviewed-change work. Start Atomic in a project with \`atomic\`, then talk to it normally. Use \`@file\` to attach files, \`!command\` to run shell output through the model, and \`!!command\` to run shell output without adding it to context.
|
|
8
8
|
|
|
9
9
|
## Core session commands
|
|
10
10
|
|
|
@@ -23,7 +23,7 @@ Atomic turns one-off prompts into developer workflows: on-call debugging, repo r
|
|
|
23
23
|
| Goal | How to use |
|
|
24
24
|
|---|---|
|
|
25
25
|
| On-call / broken behavior | Run \`/run debugger "Reproduce the failure, patch the root cause, and validate it"\` for a focused fix loop, or ask Atomic in chat to build a reusable workflow that does the same |
|
|
26
|
-
| Research → spec → implementation | Chain \`/skill:research-codebase\` → \`/skill:create-spec\` → \`/workflow goal objective="..."\` for bounded scoped work with explicit validation; use \`/workflow ralph ...\` when the work needs planning, broad refactoring, or PR prep |
|
|
26
|
+
| Research → spec → implementation | Chain \`/skill:research-codebase\` → \`/skill:create-spec\` → \`/workflow goal objective="..."\` for bounded scoped work with explicit validation; use \`/workflow ralph ...\` when the work needs planning, broad refactoring, or final-stage PR prep with \`create_pr=true\` |
|
|
27
27
|
| Testing / regression hardening | Run \`/skill:tdd\` for test-first work, then \`/parallel-review current diff\`, then land the change |
|
|
28
28
|
| Large repo discovery | Run \`/parallel codebase-locator "map the area" -> codebase-analyzer "trace the current flow" -> codebase-pattern-finder "find patterns" --bg\`, or \`/workflow deep-research-codebase\` for whole-repo synthesis |
|
|
29
29
|
| UI / product polish | Run \`/skill:impeccable\` for interface critique and refinement, or \`/workflow open-claude-design\` for generation + refinement loops |
|
|
@@ -34,7 +34,7 @@ Atomic turns one-off prompts into developer workflows: on-call debugging, repo r
|
|
|
34
34
|
|---|---|---|
|
|
35
35
|
| \`deep-research-codebase\` | broad repo or cross-cutting research before you decide what to change (for one area, use \`/skill:research-codebase\`; this indexes the whole repo) | \`/workflow deep-research-codebase prompt="How do payment retries work end to end?"\` |
|
|
36
36
|
| \`goal\` | small-to-medium scoped changes when you can name the work surface, outcome, and validation; keeps receipts in a ledger and stops as \`complete\`, \`blocked\`, or \`needs_human\` | \`/workflow goal objective="Implement specs/<date>-<topic>.md, run focused tests, and validate the changed behavior"\` |
|
|
37
|
-
| \`ralph\` | larger migrations, broad refactors, multi-package changes, and spec-to-
|
|
37
|
+
| \`ralph\` | larger migrations, broad refactors, multi-package changes, and spec-to-reviewed-change work where you want Atomic to plan, delegate, simplify, review, and iterate; add \`create_pr=true\` only when you want the final pull-request stage and report | \`/workflow ralph prompt="Plan and implement specs/<date>-<topic>.md" create_pr=true\` |
|
|
38
38
|
| \`open-claude-design\` | UI and design-system work that benefits from generation and refinement loops | \`/workflow open-claude-design prompt="Refresh the settings page hierarchy"\` |
|
|
39
39
|
|
|
40
40
|
Use \`/workflow list\` to see what is available and \`/workflow inputs <name>\` to inspect inputs in your environment.
|
|
@@ -106,15 +106,17 @@ For small-to-medium scoped changes where you can identify the work surface, exac
|
|
|
106
106
|
|
|
107
107
|
\`/workflow goal objective="Implement specs/<date>-<topic>.md, run focused tests, and finish when the documented behavior is validated"\`
|
|
108
108
|
|
|
109
|
-
For larger migrations, broad refactors, multi-package changes, or spec-to-
|
|
109
|
+
For larger migrations, broad refactors, multi-package changes, or spec-to-reviewed-change work, use \`ralph\`:
|
|
110
110
|
|
|
111
|
-
\`/workflow ralph prompt="Plan and implement specs/<date>-<topic>.md
|
|
111
|
+
\`/workflow ralph prompt="Plan and implement specs/<date>-<topic>.md"\`
|
|
112
|
+
|
|
113
|
+
Add \`create_pr=true\` only when you want Ralph's final pull-request stage and report.
|
|
112
114
|
|
|
113
115
|
## 4. Decide and land
|
|
114
116
|
|
|
115
117
|
If you used \`goal\`, the workflow already persisted receipts in a goal ledger and reviewer-gated completion. Use its final status — \`complete\`, \`blocked\`, or \`needs_human\` — plus the remaining-work report to decide whether to ship, unblock, or clarify.
|
|
116
118
|
|
|
117
|
-
If you used \`ralph\`, the workflow planned the approach, delegated implementation through sub-agents, simplified, reviewed, iterated
|
|
119
|
+
If you used \`ralph\`, the workflow planned the approach, delegated implementation through sub-agents, simplified, reviewed, and iterated. If you enabled \`create_pr=true\`, use its final pull-request report to decide whether to ship or iterate again.
|
|
118
120
|
|
|
119
121
|
If you implemented directly instead of using a workflow, you can still run:
|
|
120
122
|
|
|
@@ -140,7 +142,7 @@ You do not have to write TypeScript to add one. Describe the workflow you want i
|
|
|
140
142
|
|---|---|---|
|
|
141
143
|
| \`deep-research-codebase\` | broad repo or cross-cutting research before you decide what to change (for one area, use \`/skill:research-codebase\`; this indexes the whole repo) | \`/workflow deep-research-codebase prompt="How do payment retries work end to end?"\` |
|
|
142
144
|
| \`goal\` | small-to-medium scoped changes with a clear outcome and named validation | \`/workflow goal objective="Update the CLI docs, include one usage example, and verify the docs build passes"\` |
|
|
143
|
-
| \`ralph\` | larger migrations, broad refactors, multi-package changes, and spec-to-
|
|
145
|
+
| \`ralph\` | larger migrations, broad refactors, multi-package changes, and spec-to-reviewed-change work | \`/workflow ralph prompt="Plan a database-layer migration, implement it, and review it" create_pr=true\` |
|
|
144
146
|
| \`open-claude-design\` | frontend and product design work | \`/workflow open-claude-design prompt="Refresh the settings page hierarchy"\` |
|
|
145
147
|
|
|
146
148
|
Use \`/workflow inputs <name>\` to inspect the exact inputs in your environment.
|
|
@@ -188,7 +190,7 @@ Why this is good:
|
|
|
188
190
|
|
|
189
191
|
\`/workflow inputs ralph\`
|
|
190
192
|
|
|
191
|
-
\`/workflow ralph prompt="Migrate the database layer to Drizzle
|
|
193
|
+
\`/workflow ralph prompt="Migrate the database layer to Drizzle" create_pr=true\`
|
|
192
194
|
|
|
193
195
|
\`/workflow status\`
|
|
194
196
|
|