@bastani/atomic 0.9.7 → 0.9.8
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 +28 -0
- package/dist/builtin/cursor/CHANGELOG.md +12 -0
- package/dist/builtin/cursor/package.json +2 -2
- 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 +14 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/skills/{effective-liteparse → liteparse}/SKILL.md +4 -4
- package/dist/builtin/subagents/skills/playwright-cli/SKILL.md +21 -5
- package/dist/builtin/subagents/skills/playwright-cli/references/test-generation.md +311 -12
- package/dist/builtin/web-access/CHANGELOG.md +12 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +24 -0
- package/dist/builtin/workflows/README.md +2 -2
- package/dist/builtin/workflows/builtin/goal-prompts.ts +9 -7
- package/dist/builtin/workflows/builtin/goal-reducer.ts +9 -24
- package/dist/builtin/workflows/builtin/goal-review.ts +17 -36
- package/dist/builtin/workflows/builtin/ralph-core.ts +1 -3
- package/dist/builtin/workflows/builtin/ralph-review-gate.ts +31 -53
- package/dist/builtin/workflows/builtin/ralph-reviewer-prompt.ts +10 -4
- package/dist/builtin/workflows/builtin/shared-prompts.ts +5 -4
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +2 -2
- package/dist/builtin/workflows/skills/impeccable/reference/init.md +37 -10
- package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +1 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +2 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/critique-storage.mjs +2 -2
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +20 -4
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +3 -6
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +2 -4
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/page.mjs +31 -8
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +7 -6
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +11 -10
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-paths.mjs +1 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/is-generated.mjs +1 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/provider.mjs +4 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/live/browser-script-parts.mjs +2 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-component.mjs +38 -16
- package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +33 -19
- package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +9 -9
- package/dist/builtin/workflows/skills/impeccable/scripts/live-server.mjs +2 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/pin.mjs +16 -9
- package/dist/builtin/workflows/src/tui/overlay-adapter.ts +59 -14
- package/docs/quickstart.md +1 -1
- package/docs/workflows.md +4 -4
- package/npm-shrinkwrap.json +23 -23
- package/package.json +2 -2
- package/dist/builtin/subagents/skills/playwright-cli/references/spec-driven-testing.md +0 -305
- /package/dist/builtin/subagents/skills/{effective-liteparse → liteparse}/scripts/search.py +0 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* node <scripts_path>/pin.mjs pin <command>
|
|
7
7
|
* node <scripts_path>/pin.mjs unpin <command>
|
|
8
8
|
*
|
|
9
|
-
* `pin audit` creates a lightweight
|
|
9
|
+
* `pin audit` creates a lightweight audit skill that redirects to Impeccable's audit workflow.
|
|
10
10
|
* `unpin audit` removes that shortcut.
|
|
11
11
|
*
|
|
12
12
|
* The script discovers harness directories (.claude/skills, .cursor/skills, etc.)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync, readdirSync } from 'node:fs';
|
|
17
|
-
import { join, resolve, dirname } from 'node:path';
|
|
17
|
+
import { basename, join, resolve, dirname } from 'node:path';
|
|
18
18
|
import { fileURLToPath } from 'node:url';
|
|
19
19
|
|
|
20
20
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -25,6 +25,8 @@ const HARNESS_DIRS = [
|
|
|
25
25
|
'.trae', '.trae-cn', '.pi', '.opencode', '.kiro', '.rovodev',
|
|
26
26
|
];
|
|
27
27
|
|
|
28
|
+
const CODEX_HARNESSES = new Set(['.codex', '.agents']);
|
|
29
|
+
|
|
28
30
|
// Valid sub-command names
|
|
29
31
|
const VALID_COMMANDS = [
|
|
30
32
|
'craft', 'init', 'extract', 'document', 'shape',
|
|
@@ -87,8 +89,12 @@ function loadCommandMetadata() {
|
|
|
87
89
|
/**
|
|
88
90
|
* Generate a pinned skill's SKILL.md content.
|
|
89
91
|
*/
|
|
90
|
-
function
|
|
91
|
-
|
|
92
|
+
function commandPrefixForSkillsDir(skillsDir) {
|
|
93
|
+
return CODEX_HARNESSES.has(basename(dirname(skillsDir))) ? '$' : '/';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function generatePinnedSkill(command, metadata, commandPrefix) {
|
|
97
|
+
const desc = metadata[command]?.description || `Shortcut for ${commandPrefix}impeccable ${command}.`;
|
|
92
98
|
const hint = metadata[command]?.argumentHint || '[target]';
|
|
93
99
|
|
|
94
100
|
return `---
|
|
@@ -100,9 +106,9 @@ user-invocable: true
|
|
|
100
106
|
|
|
101
107
|
${PIN_MARKER}
|
|
102
108
|
|
|
103
|
-
This is a pinned shortcut for
|
|
109
|
+
This is a pinned shortcut for \`${commandPrefix}impeccable ${command}\`.
|
|
104
110
|
|
|
105
|
-
Invoke {
|
|
111
|
+
Invoke ${commandPrefix}impeccable ${command}, passing along any arguments provided here, and follow its instructions.
|
|
106
112
|
`;
|
|
107
113
|
}
|
|
108
114
|
|
|
@@ -118,10 +124,11 @@ function pin(command, projectRoot) {
|
|
|
118
124
|
return false;
|
|
119
125
|
}
|
|
120
126
|
|
|
121
|
-
const content = generatePinnedSkill(command, metadata);
|
|
122
127
|
let created = 0;
|
|
123
128
|
|
|
124
129
|
for (const skillsDir of harnessDirs) {
|
|
130
|
+
const commandPrefix = commandPrefixForSkillsDir(skillsDir);
|
|
131
|
+
const content = generatePinnedSkill(command, metadata, commandPrefix);
|
|
125
132
|
// Check if skill already exists (and isn't a pin)
|
|
126
133
|
const skillDir = join(skillsDir, command);
|
|
127
134
|
if (existsSync(skillDir)) {
|
|
@@ -143,7 +150,7 @@ function pin(command, projectRoot) {
|
|
|
143
150
|
|
|
144
151
|
if (created > 0) {
|
|
145
152
|
console.log(`\nPinned '${command}' as a standalone shortcut in ${created} location(s).`);
|
|
146
|
-
console.log(
|
|
153
|
+
console.log('Use the pinned command directly in each harness.');
|
|
147
154
|
}
|
|
148
155
|
|
|
149
156
|
return created > 0;
|
|
@@ -177,7 +184,7 @@ function unpin(command, projectRoot) {
|
|
|
177
184
|
|
|
178
185
|
if (removed > 0) {
|
|
179
186
|
console.log(`\nUnpinned '${command}' from ${removed} location(s).`);
|
|
180
|
-
console.log(`Use
|
|
187
|
+
console.log(`Use Impeccable's '${command}' workflow directly to access it.`);
|
|
181
188
|
} else {
|
|
182
189
|
console.log(`No pinned '${command}' shortcut found.`);
|
|
183
190
|
}
|
|
@@ -103,12 +103,25 @@ const FULLSCREEN_OVERLAY_OPTIONS: PiOverlayOptions = {
|
|
|
103
103
|
|
|
104
104
|
const MOUSE_SCROLL_TRACKING_ON = "\x1b[?1000h\x1b[?1002h\x1b[?1006h";
|
|
105
105
|
const MOUSE_SCROLL_TRACKING_OFF = "\x1b[?1006l\x1b[?1002l\x1b[?1000l";
|
|
106
|
+
const TERMINAL_AUTOWRAP_ON = "\x1b[?7h";
|
|
107
|
+
const TERMINAL_AUTOWRAP_OFF = "\x1b[?7l";
|
|
106
108
|
const MAIN_CHAT_INPUT_STATUS_KEY = `${WORKFLOW_STATUS_KEY}:main-chat-input`;
|
|
107
109
|
const MAIN_CHAT_INPUT_STATUS = "Main chat needs input — exit graph to answer.";
|
|
108
110
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
export interface OverlayTerminalOutput {
|
|
112
|
+
platform: NodeJS.Platform;
|
|
113
|
+
isTTY: boolean | undefined;
|
|
114
|
+
write(data: string): void;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function setMouseScrollTracking(enabled: boolean, output: OverlayTerminalOutput): void {
|
|
118
|
+
if (!output.isTTY) return;
|
|
119
|
+
output.write(enabled ? MOUSE_SCROLL_TRACKING_ON : MOUSE_SCROLL_TRACKING_OFF);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function setTerminalAutowrap(enabled: boolean, output: OverlayTerminalOutput): void {
|
|
123
|
+
if (output.platform !== "win32" || !output.isTTY) return;
|
|
124
|
+
output.write(enabled ? TERMINAL_AUTOWRAP_ON : TERMINAL_AUTOWRAP_OFF);
|
|
112
125
|
}
|
|
113
126
|
|
|
114
127
|
export interface BuildGraphOverlayAdapterOpts {
|
|
@@ -126,6 +139,8 @@ export interface BuildGraphOverlayAdapterOpts {
|
|
|
126
139
|
onQuitRun?: (runId: string) => void;
|
|
127
140
|
/** Optional clock injection for deterministic attach-pane transition tests. */
|
|
128
141
|
now?: () => number;
|
|
142
|
+
/** Terminal output seam used to test raw overlay control sequences. */
|
|
143
|
+
terminalOutput?: OverlayTerminalOutput;
|
|
129
144
|
}
|
|
130
145
|
|
|
131
146
|
export function buildGraphOverlayAdapter(
|
|
@@ -135,6 +150,16 @@ export function buildGraphOverlayAdapter(
|
|
|
135
150
|
): GraphOverlayPort {
|
|
136
151
|
const registry = buildOpts.stageControlRegistry ?? defaultStageControlRegistry;
|
|
137
152
|
const stageUiBroker = buildOpts.stageUiBroker;
|
|
153
|
+
const terminalOutput = buildOpts.terminalOutput ?? {
|
|
154
|
+
platform: process.platform,
|
|
155
|
+
isTTY: process.stdout.isTTY,
|
|
156
|
+
write: (data: string): void => {
|
|
157
|
+
process.stdout.write(data);
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
const updateMouseScrollTracking = (enabled: boolean): void => {
|
|
161
|
+
setMouseScrollTracking(enabled, terminalOutput);
|
|
162
|
+
};
|
|
138
163
|
const quitRun = buildOpts.onQuitRun ?? ((id: string): void => {
|
|
139
164
|
defaultQuitRun(id, { store, stageControlRegistry: registry });
|
|
140
165
|
});
|
|
@@ -149,6 +174,13 @@ export function buildGraphOverlayAdapter(
|
|
|
149
174
|
let observedUi: OverlayUISurface | undefined;
|
|
150
175
|
let unsubscribeHostCustomUi: (() => void) | null = null;
|
|
151
176
|
let hostInlineCustomUiActive = false;
|
|
177
|
+
let overlayVisible = false;
|
|
178
|
+
|
|
179
|
+
function updateTerminalAutowrap(visible: boolean): void {
|
|
180
|
+
if (overlayVisible === visible) return;
|
|
181
|
+
overlayVisible = visible;
|
|
182
|
+
setTerminalAutowrap(!visible, terminalOutput);
|
|
183
|
+
}
|
|
152
184
|
|
|
153
185
|
function readHostCustomUiActive(ui: OverlayUISurface | undefined = observedUi): boolean {
|
|
154
186
|
const state = ui?.getHostCustomUiState?.();
|
|
@@ -188,8 +220,9 @@ export function buildGraphOverlayAdapter(
|
|
|
188
220
|
}
|
|
189
221
|
|
|
190
222
|
function close(): void {
|
|
191
|
-
|
|
223
|
+
updateMouseScrollTracking(false);
|
|
192
224
|
currentHandle?.hide();
|
|
225
|
+
updateTerminalAutowrap(false);
|
|
193
226
|
finishMounted?.();
|
|
194
227
|
observedUi?.setStatus?.(WORKFLOW_STATUS_KEY, undefined);
|
|
195
228
|
observedUi?.setStatus?.(MAIN_CHAT_INPUT_STATUS_KEY, undefined);
|
|
@@ -218,11 +251,12 @@ export function buildGraphOverlayAdapter(
|
|
|
218
251
|
* running and can be re-attached.
|
|
219
252
|
*/
|
|
220
253
|
function hideMounted(): void {
|
|
221
|
-
|
|
254
|
+
updateMouseScrollTracking(false);
|
|
222
255
|
observedUi?.setStatus?.(MAIN_CHAT_INPUT_STATUS_KEY, undefined);
|
|
223
256
|
if (currentHandle) {
|
|
224
257
|
currentView?.setVisible(false);
|
|
225
258
|
currentHandle.setHidden(true);
|
|
259
|
+
updateTerminalAutowrap(false);
|
|
226
260
|
currentHandle.unfocus();
|
|
227
261
|
return;
|
|
228
262
|
}
|
|
@@ -230,6 +264,7 @@ export function buildGraphOverlayAdapter(
|
|
|
230
264
|
finishMounted();
|
|
231
265
|
return;
|
|
232
266
|
}
|
|
267
|
+
updateTerminalAutowrap(false);
|
|
233
268
|
}
|
|
234
269
|
|
|
235
270
|
function refocusVisibleOverlayForAwaitingInput(snapshot: StoreSnapshot): void {
|
|
@@ -258,7 +293,8 @@ export function buildGraphOverlayAdapter(
|
|
|
258
293
|
},
|
|
259
294
|
invalidate: () => tui.requestRender?.(),
|
|
260
295
|
dispose: () => {
|
|
261
|
-
|
|
296
|
+
updateTerminalAutowrap(false);
|
|
297
|
+
updateMouseScrollTracking(false);
|
|
262
298
|
unsubscribe();
|
|
263
299
|
view.dispose();
|
|
264
300
|
},
|
|
@@ -277,14 +313,16 @@ export function buildGraphOverlayAdapter(
|
|
|
277
313
|
if (mounted && currentHandle?.isHidden()) {
|
|
278
314
|
currentView?.retarget(runId, stageId);
|
|
279
315
|
currentView?.setVisible(true);
|
|
280
|
-
|
|
316
|
+
updateTerminalAutowrap(true);
|
|
317
|
+
updateMouseScrollTracking(currentView?.wantsMouseScrollTracking() ?? true);
|
|
281
318
|
currentHandle.setHidden(false);
|
|
282
319
|
currentHandle.focus();
|
|
283
320
|
return;
|
|
284
321
|
}
|
|
285
322
|
if (mounted) {
|
|
286
323
|
currentView?.retarget(runId, stageId);
|
|
287
|
-
|
|
324
|
+
updateTerminalAutowrap(true);
|
|
325
|
+
updateMouseScrollTracking(currentView?.wantsMouseScrollTracking() ?? true);
|
|
288
326
|
// Restore keyboard focus to the visible overlay after retargeting.
|
|
289
327
|
// pi-tui dispatches key events only to the focused component, so a
|
|
290
328
|
// mounted-but-visible overlay that is retargeted (e.g. to a stage-scoped
|
|
@@ -309,7 +347,7 @@ export function buildGraphOverlayAdapter(
|
|
|
309
347
|
const finish = (): void => {
|
|
310
348
|
if (settled) return;
|
|
311
349
|
settled = true;
|
|
312
|
-
|
|
350
|
+
updateMouseScrollTracking(false);
|
|
313
351
|
observedUi?.setStatus?.(WORKFLOW_STATUS_KEY, undefined);
|
|
314
352
|
observedUi?.setStatus?.(MAIN_CHAT_INPUT_STATUS_KEY, undefined);
|
|
315
353
|
currentView?.dispose();
|
|
@@ -318,7 +356,11 @@ export function buildGraphOverlayAdapter(
|
|
|
318
356
|
finishMounted = null;
|
|
319
357
|
mounted = false;
|
|
320
358
|
clearHostCustomUiObservation();
|
|
321
|
-
|
|
359
|
+
try {
|
|
360
|
+
done(undefined);
|
|
361
|
+
} finally {
|
|
362
|
+
updateTerminalAutowrap(false);
|
|
363
|
+
}
|
|
322
364
|
};
|
|
323
365
|
const view = new WorkflowAttachPane({
|
|
324
366
|
store,
|
|
@@ -369,7 +411,7 @@ export function buildGraphOverlayAdapter(
|
|
|
369
411
|
if (currentHandle?.isFocused() === true) return;
|
|
370
412
|
currentHandle?.focus();
|
|
371
413
|
},
|
|
372
|
-
setMouseScrollTracking,
|
|
414
|
+
setMouseScrollTracking: updateMouseScrollTracking,
|
|
373
415
|
now: buildOpts.now,
|
|
374
416
|
} as ConstructorParameters<typeof WorkflowAttachPane>[0] & {
|
|
375
417
|
piTui?: PiCustomOverlayFactoryTui;
|
|
@@ -379,7 +421,8 @@ export function buildGraphOverlayAdapter(
|
|
|
379
421
|
currentView = view;
|
|
380
422
|
finishMounted = finish;
|
|
381
423
|
mounted = true;
|
|
382
|
-
|
|
424
|
+
updateTerminalAutowrap(true);
|
|
425
|
+
updateMouseScrollTracking(view.wantsMouseScrollTracking());
|
|
383
426
|
updateMainChatInputHint(readHostCustomUiActive(ui));
|
|
384
427
|
return makeComponent(view, tui);
|
|
385
428
|
};
|
|
@@ -403,11 +446,13 @@ export function buildGraphOverlayAdapter(
|
|
|
403
446
|
if (mounted && currentHandle) {
|
|
404
447
|
const nowHidden = !currentHandle.isHidden();
|
|
405
448
|
currentView?.setVisible(!nowHidden);
|
|
406
|
-
|
|
449
|
+
if (!nowHidden) updateTerminalAutowrap(true);
|
|
450
|
+
updateMouseScrollTracking(
|
|
407
451
|
nowHidden ? false : currentView?.wantsMouseScrollTracking() ?? true,
|
|
408
452
|
);
|
|
409
453
|
currentHandle.setHidden(nowHidden);
|
|
410
|
-
if (
|
|
454
|
+
if (nowHidden) updateTerminalAutowrap(false);
|
|
455
|
+
else currentHandle.focus();
|
|
411
456
|
return;
|
|
412
457
|
}
|
|
413
458
|
if (mounted) {
|
package/docs/quickstart.md
CHANGED
|
@@ -151,7 +151,7 @@ Skills are reusable expert instructions. Trigger one with `/skill:<name>` follow
|
|
|
151
151
|
| `tdd` | Test-first feature or bug work. | `/skill:tdd` |
|
|
152
152
|
| `impeccable` | Critique or refine web/native frontend and product UI; includes detector hooks. | `/skill:impeccable` |
|
|
153
153
|
| `playwright-cli` | Drive a real browser for end-to-end UI checks, screenshots, and reviewable proof videos. | `/skill:playwright-cli` |
|
|
154
|
-
| `
|
|
154
|
+
| `liteparse` | Pull text, tables, or values out of PDF, DOCX, PPTX, XLSX, and image files locally. | `/skill:liteparse` |
|
|
155
155
|
|
|
156
156
|
Use `/skill:research-codebase` for a focused area and `/workflow deep-research-codebase` when a clearly delegated repo-wide research job benefits from durable stages and artifacts. Keep conversation-led planning and implementation inline, or use bounded subagents while the parent remains in control. When an autonomous implementation job needs durable execution, use `/workflow goal` for a goal ledger, bounded worker turns, and reviewer-gated completion, or `/workflow ralph` for a research-first pipeline with delegated implementation and iterative review. Task size alone does not select either workflow. Add `create_pr=true` only when you want the workflow's final pull-request stage after approval.
|
|
157
157
|
|
package/docs/workflows.md
CHANGED
|
@@ -227,7 +227,7 @@ Inputs:
|
|
|
227
227
|
| `git_worktree_dir` | string | no | `""` | Optional reusable Git worktree root. Empty runs in the invoking checkout; non-empty values run Goal stages in the created/reused worktree. |
|
|
228
228
|
| `create_pr` | boolean | no | `false` | Safe-by-default PR creation flag. Omitted or `false` skips the final `pull-request` stage and omits `pr_report`; prompt text alone does not opt in, and only strict `true` authorizes the final `pull-request` stage to attempt provider-appropriate PR/MR/review creation after Goal reaches `complete`. |
|
|
229
229
|
|
|
230
|
-
`goal` defaults to 10 worker/review turns. Reviewer quorum is fixed internally at 2 reviewer `complete` votes,
|
|
230
|
+
`goal` defaults to 10 worker/review turns. Reviewer quorum is fixed internally at 2 reviewer `complete` votes, and approval is deterministic on each reviewer's self-reported `stop_review_loop` boolean: a reviewer approves exactly when it returns `stop_review_loop=true` with no `reviewer_error` (schema-parse failures count as non-approval), and the reducer completes the run when quorum of those booleans is met without recomputing approval from findings arrays or traceability statuses. The repeated-blocker threshold defaults to 3 consecutive same-blocker turns and is clamped to `max_turns` when you run fewer than 3 turns.
|
|
231
231
|
|
|
232
232
|
Run examples:
|
|
233
233
|
|
|
@@ -245,9 +245,9 @@ Set `git_worktree_dir` when you want Goal's worker and reviewer stages isolated
|
|
|
245
245
|
|
|
246
246
|
Write the `objective` like a compact acceptance spec. Say what should exist when the run is done, how you want testing handled, which command(s) or manual checks matter, and what outcome proves completion. The workflow is intentionally lean: it does not first generate an RFC or migration plan, so the developer-supplied objective is where scope, validation, and completion criteria belong.
|
|
247
247
|
|
|
248
|
-
Goal worker/reviewer prompts treat the objective and acceptance criteria as the sole literal source of truth: if follow-up deltas, language specs, upstream issues, in-repo comments, or best practices conflict with explicit wording, reviewers surface the conflict instead of silently implementing external knowledge. Reviewer findings carry `objective_alignment` (`required_by_objective`, `consistent_with_objective`, `beyond_objective`, or `contradicts_objective`); `beyond_objective` and `contradicts_objective` findings are reported but do not block completion and must not be promoted into follow-up objectives without reconciling them against the acceptance criteria. Severity labels alone never dismiss objective-relevant findings: `required_by_objective` findings block at any priority (P3 included), while `consistent_with_objective` P3 nice-to-haves stay non-blocking. Review decisions also include `requirements_traceability`, a clause-by-clause evidence map over every explicit objective/acceptance-criteria requirement.
|
|
248
|
+
Goal worker/reviewer prompts treat the objective and acceptance criteria as the sole literal source of truth: if follow-up deltas, language specs, upstream issues, in-repo comments, or best practices conflict with explicit wording, reviewers surface the conflict instead of silently implementing external knowledge. Reviewer findings carry `objective_alignment` (`required_by_objective`, `consistent_with_objective`, `beyond_objective`, or `contradicts_objective`); `beyond_objective` and `contradicts_objective` findings are reported but do not block completion and must not be promoted into follow-up objectives without reconciling them against the acceptance criteria. Severity labels alone never dismiss objective-relevant findings: `required_by_objective` findings block at any priority (P3 included), while `consistent_with_objective` P3 nice-to-haves stay non-blocking. Review decisions also include `requirements_traceability`, a clause-by-clause evidence map over every explicit objective/acceptance-criteria requirement. Findings and traceability are audit evidence that drive how each reviewer derives its authoritative `stop_review_loop` boolean; the harness gates approval on that boolean alone, and reviewers are explicitly told that process-only clauses (reviewer quorum/approval counts, and the authorized post-approval PR/MR/review final action when `create_pr=true`) must never hold the flag at `false`. Passing worker-authored tests or snapshots alone is circular evidence unless tied to independent current-state proof.
|
|
249
249
|
|
|
250
|
-
The worker may claim readiness, but it cannot finalize completion. Workers start from an observable acceptance/contract matrix derived from the literal objective/acceptance criteria (one row per clause, each mapped to the concrete check that proves it), and are prompted to model states, transitions, and invariants explicitly when the work is stateful. Reviewer findings from the latest round are consolidated into a deduplicated cross-reviewer batch persisted in the round artifact (`consolidated_findings` in `review-round-latest.json`), and the next worker turn is instructed to plan and repair the whole batch — with durable regression evidence for reproduced findings — rather than fixing one finding per turn. Workers and reviewers are prompted to verify user-visible behavior end-to-end when practical, using `playwright-cli`-skilled subagents for web/frontend flows that may depend on backend/API behavior and tmux-skilled subagents for TUI or terminal-app scenarios. They must assume credentials/auth/environment access exists until concrete checks plus an actual app/flow launch attempt prove otherwise; skipped E2E is valid only when exact attempted commands and observed failure output are recorded. Goal reviewers also look for any QA E2E video referenced by the ledger or receipt and must inspect the actual video before treating it as proof. Three reviewers independently inspect the ledger, worker receipt, repository state, and diff against `base_branch`; each starts in a clean, non-forked context, matching Ralph's reviewer context behavior, and every Goal reviewer uses Ralph's `reviewer-a` model chain with Claude Fable 5 as the primary model. Each reviewer is instructed to first derive its own adversarial check list from the literal contract — boundary/edge/negative probes plus state/transition/invariant probes — before relying on the worker receipt or worker-authored tests, and each returns structured JSON with findings, evidence, verification still remaining, and an optional blocker. A TypeScript reducer marks the goal complete
|
|
250
|
+
The worker may claim readiness, but it cannot finalize completion. Workers start from an observable acceptance/contract matrix derived from the literal objective/acceptance criteria (one row per clause, each mapped to the concrete check that proves it), and are prompted to model states, transitions, and invariants explicitly when the work is stateful. Reviewer findings from the latest round are consolidated into a deduplicated cross-reviewer batch persisted in the round artifact (`consolidated_findings` in `review-round-latest.json`), and the next worker turn is instructed to plan and repair the whole batch — with durable regression evidence for reproduced findings — rather than fixing one finding per turn. Workers and reviewers are prompted to verify user-visible behavior end-to-end when practical, using `playwright-cli`-skilled subagents for web/frontend flows that may depend on backend/API behavior and tmux-skilled subagents for TUI or terminal-app scenarios. They must assume credentials/auth/environment access exists until concrete checks plus an actual app/flow launch attempt prove otherwise; skipped E2E is valid only when exact attempted commands and observed failure output are recorded. Goal reviewers also look for any QA E2E video referenced by the ledger or receipt and must inspect the actual video before treating it as proof. Three reviewers independently inspect the ledger, worker receipt, repository state, and diff against `base_branch`; each starts in a clean, non-forked context, matching Ralph's reviewer context behavior, and every Goal reviewer uses Ralph's `reviewer-a` model chain with Claude Fable 5 as the primary model. Each reviewer is instructed to first derive its own adversarial check list from the literal contract — boundary/edge/negative probes plus state/transition/invariant probes — before relying on the worker receipt or worker-authored tests, and each returns structured JSON with findings, evidence, verification still remaining, and an optional blocker. A TypeScript reducer marks the goal complete when reviewer quorum approves via the `stop_review_loop` booleans, marks blocked only when the same dependency/tool blocker repeats for the blocker threshold, continues while quorum is missing (recording the reviewers' remaining work in the decision reason), and returns `needs_human` when `max_turns` is exhausted or worker execution fails, so the bounded loop always stops with an inspectable reason.
|
|
251
251
|
|
|
252
252
|
When Goal's reducer returns `needs_human`, `blocked`, or another incomplete status, the top-level workflow run is not reported as a successful completion. `/workflow status` and lifecycle notices surface it as blocked/failed according to the run's terminal condition. Atomic also preserves structured recoverable failure metadata from the run's blocking stage (`failedStageId`) or run-level failure metadata, so auth, rate-limit, and provider fallback exhaustion remains blocked/resumable even if the workflow later returns ordinary outputs instead of a reserved `status` value. Tolerated branch failures from non-fail-fast parallel work do not reclassify an otherwise completed run.
|
|
253
253
|
|
|
@@ -293,7 +293,7 @@ Run examples:
|
|
|
293
293
|
/workflow ralph prompt="Safely implement the API refactor" git_worktree_dir=../atomic-ralph-api-wt base_branch=main
|
|
294
294
|
```
|
|
295
295
|
|
|
296
|
-
Each `ralph` run uses the raw `prompt` exactly as supplied as the operative objective for research, orchestration, and review, and stores `acceptance_criteria` as the immutable literal contract (defaulting to the prompt when omitted). Shared literal-contract prompt language forbids adding behaviors, restrictions, or error conditions beyond the prompt/acceptance criteria and requires surfacing conflicts with external knowledge; Ralph does not run an initial prompt-refinement stage. Each iteration transforms that raw prompt with `/skill:prompt-engineer Transform the following user request into a codebase and online research question which can be thoroughly explored: ...` (`research-prompt-refinement`), researches that transformed question with `/skill:research-codebase ...`, and writes the findings under `research/`. The research, orchestrator, and reviewer prompts carry `acceptance_criteria` next to the literal contract, so orchestrators should pass the ORIGINAL task text when launching follow-up Ralph runs from reviewer findings. The orchestrator starts from an observable acceptance/contract matrix derived from the literal prompt/acceptance criteria (one row per clause mapped to the concrete observable check that proves it) and is prompted to model states, transitions, and invariants explicitly when the work is stateful; it treats the research artifact as its primary implementation context, initializes/updates an OS-temp implementation notes file while generating verifiable evidence for any claims it records in the notes and reviewer artifacts, delegates implementation through sub-agents, repairs unresolved reviewer findings as one consolidated batch (with durable regression evidence for reproduced findings) rather than one finding per iteration, and asks two independent reviewers (`reviewer-a` and `reviewer-b`) to inspect the patch directly against `base_branch`. The reviewer fan-out runs reviewers on different primary model families (Claude Fable 5 and GPT-5.5 Codex, with shared fallbacks) so the adversarial review gets cross-model coverage instead of repeated passes from one model, and each reviewer is instructed to first derive its own adversarial check list from the literal contract — boundary/edge/negative probes plus state/transition/invariant probes — before relying on the implementation notes, orchestrator report, or worker-authored tests. Ralph's orchestrator and reviewers are prompted to verify user-visible behavior end-to-end when practical, using `playwright-cli`-skilled subagents for web/frontend flows that may depend on backend/API behavior and tmux-skilled subagents for TUI or terminal-app scenarios. They must assume credentials/auth/environment access exists until concrete checks plus an actual app/flow launch attempt prove otherwise; skipped E2E is valid only when exact attempted commands and observed failure output are recorded. For UI-applicable or full-stack changes, the orchestrator runs a `playwright-cli` end-to-end QA pass and records a reviewable proof video (referenced in the implementation notes and surfaced as `qa_video_path`); reviewers receive that path and must inspect the actual video before treating it as proof. When `create_pr=true`, the final `pull-request` stage attaches or links that video to the created PR/MR/review after reviewer approval. If reviewers find issues, the next `research-prompt-refinement` and research stages receive the review artifact path (whose `review-round-latest.json` now also carries a deduplicated cross-reviewer `consolidated_findings` batch) so follow-up research can address unresolved findings, and research stages fork from prior research session data when available. The loop stops only when both reviewers independently approve or `max_loops` is reached, so the bounded loop always stops with an inspectable review round. Ralph findings include the same `objective_alignment` classification used by Goal: `required_by_objective` findings
|
|
296
|
+
Each `ralph` run uses the raw `prompt` exactly as supplied as the operative objective for research, orchestration, and review, and stores `acceptance_criteria` as the immutable literal contract (defaulting to the prompt when omitted). Shared literal-contract prompt language forbids adding behaviors, restrictions, or error conditions beyond the prompt/acceptance criteria and requires surfacing conflicts with external knowledge; Ralph does not run an initial prompt-refinement stage. Each iteration transforms that raw prompt with `/skill:prompt-engineer Transform the following user request into a codebase and online research question which can be thoroughly explored: ...` (`research-prompt-refinement`), researches that transformed question with `/skill:research-codebase ...`, and writes the findings under `research/`. The research, orchestrator, and reviewer prompts carry `acceptance_criteria` next to the literal contract, so orchestrators should pass the ORIGINAL task text when launching follow-up Ralph runs from reviewer findings. The orchestrator starts from an observable acceptance/contract matrix derived from the literal prompt/acceptance criteria (one row per clause mapped to the concrete observable check that proves it) and is prompted to model states, transitions, and invariants explicitly when the work is stateful; it treats the research artifact as its primary implementation context, initializes/updates an OS-temp implementation notes file while generating verifiable evidence for any claims it records in the notes and reviewer artifacts, delegates implementation through sub-agents, repairs unresolved reviewer findings as one consolidated batch (with durable regression evidence for reproduced findings) rather than one finding per iteration, and asks two independent reviewers (`reviewer-a` and `reviewer-b`) to inspect the patch directly against `base_branch`. The reviewer fan-out runs reviewers on different primary model families (Claude Fable 5 and GPT-5.5 Codex, with shared fallbacks) so the adversarial review gets cross-model coverage instead of repeated passes from one model, and each reviewer is instructed to first derive its own adversarial check list from the literal contract — boundary/edge/negative probes plus state/transition/invariant probes — before relying on the implementation notes, orchestrator report, or worker-authored tests. Ralph's orchestrator and reviewers are prompted to verify user-visible behavior end-to-end when practical, using `playwright-cli`-skilled subagents for web/frontend flows that may depend on backend/API behavior and tmux-skilled subagents for TUI or terminal-app scenarios. They must assume credentials/auth/environment access exists until concrete checks plus an actual app/flow launch attempt prove otherwise; skipped E2E is valid only when exact attempted commands and observed failure output are recorded. For UI-applicable or full-stack changes, the orchestrator runs a `playwright-cli` end-to-end QA pass and records a reviewable proof video (referenced in the implementation notes and surfaced as `qa_video_path`); reviewers receive that path and must inspect the actual video before treating it as proof. When `create_pr=true`, the final `pull-request` stage attaches or links that video to the created PR/MR/review after reviewer approval. If reviewers find issues, the next `research-prompt-refinement` and research stages receive the review artifact path (whose `review-round-latest.json` now also carries a deduplicated cross-reviewer `consolidated_findings` batch) so follow-up research can address unresolved findings, and research stages fork from prior research session data when available. The loop stops only when both reviewers independently approve or `max_loops` is reached, so the bounded loop always stops with an inspectable review round. Ralph findings include the same `objective_alignment` classification used by Goal, and each reviewer derives a single authoritative `stop_review_loop` boolean from that evidence: `required_by_objective` findings mean `false` at any priority (P3 included, because severity labels alone never dismiss objective-relevant findings), `consistent_with_objective` P0/P1/P2 findings mean `false` while P3 remains a non-blocking nice-to-have, and `beyond_objective`/`contradicts_objective` findings are surfaced but non-blocking so they are not silently converted into new requirements. The loop gate approves deterministically on `stop_review_loop=true` plus a null `reviewer_error` (parse failures count as non-approval) without recomputing approval from the findings arrays. Ralph review decisions also include `requirements_traceability`, a clause-by-clause evidence map over every explicit prompt/acceptance-criteria requirement kept as audit evidence for deriving the flag; reviewers are explicitly told that process-only clauses (reviewer quorum, and the authorized post-approval PR/MR/review final action when `create_pr=true`) must never hold the flag at `false`. Worker-authored tests or snapshots passing are circular evidence unless tied to independent current-state proof. By default Ralph does not start the final `pull-request` stage, and `pr_report` is omitted. Prompt text alone does not opt in. Pass `create_pr=true` only when you explicitly want the final `pull-request` stage to inspect provider credentials and attempt provider-appropriate PR/MR/review creation, such as GitHub `gh`, Azure Repos `az repos pr create`, or Sapling/Phabricator tooling; Ralph's own PR-creation instructions live in that final stage and run only after approval.
|
|
297
297
|
|
|
298
298
|
Each Ralph review artifact and `review-round-latest.json` includes a `convergence_decision` summary with `parsed`, `approved`, `stopReviewLoop`, `nextAction`, `finalActionRemaining`, and `diagnostics`. This makes malformed or missing structured reviewer output visible as a parse failure, separate from a parsed reviewer rejection or blocking finding. When `create_pr=true`, reviewers are told that PR/MR/review creation is a post-approval final action: if implementation and validation requirements are proven and only PR creation remains, the implementation can approve with `finalActionRemaining: true` and `nextAction: "pull-request"` instead of consuming another orchestration iteration. When both reviewers converge, the latest round records `approved: true`, `stopReviewLoop: true`, and `nextAction: "pull-request"` when `create_pr=true` (otherwise `"finish"`), and the implementation loop stops before the final handoff stage.
|
|
299
299
|
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/atomic",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.8",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bastani/atomic",
|
|
9
|
-
"version": "0.9.
|
|
9
|
+
"version": "0.9.8",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@bastani/atomic-natives": "0.9.
|
|
12
|
+
"@bastani/atomic-natives": "0.9.8",
|
|
13
13
|
"@bufbuild/protobuf": "^2.12.1",
|
|
14
14
|
"@earendil-works/pi-agent-core": "^0.80.6",
|
|
15
15
|
"@earendil-works/pi-ai": "^0.80.6",
|
|
@@ -515,16 +515,16 @@
|
|
|
515
515
|
}
|
|
516
516
|
},
|
|
517
517
|
"node_modules/@bastani/atomic-natives": {
|
|
518
|
-
"version": "0.9.
|
|
519
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.
|
|
518
|
+
"version": "0.9.8",
|
|
519
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.8.tgz",
|
|
520
520
|
"license": "MIT",
|
|
521
521
|
"optionalDependencies": {
|
|
522
|
-
"@bastani/atomic-natives-darwin-arm64": "0.9.
|
|
523
|
-
"@bastani/atomic-natives-darwin-x64": "0.9.
|
|
524
|
-
"@bastani/atomic-natives-linux-arm64-gnu": "0.9.
|
|
525
|
-
"@bastani/atomic-natives-linux-x64-gnu": "0.9.
|
|
526
|
-
"@bastani/atomic-natives-win32-arm64-msvc": "0.9.
|
|
527
|
-
"@bastani/atomic-natives-win32-x64-msvc": "0.9.
|
|
522
|
+
"@bastani/atomic-natives-darwin-arm64": "0.9.8",
|
|
523
|
+
"@bastani/atomic-natives-darwin-x64": "0.9.8",
|
|
524
|
+
"@bastani/atomic-natives-linux-arm64-gnu": "0.9.8",
|
|
525
|
+
"@bastani/atomic-natives-linux-x64-gnu": "0.9.8",
|
|
526
|
+
"@bastani/atomic-natives-win32-arm64-msvc": "0.9.8",
|
|
527
|
+
"@bastani/atomic-natives-win32-x64-msvc": "0.9.8"
|
|
528
528
|
},
|
|
529
529
|
"engines": {
|
|
530
530
|
"bun": ">=1.3.14",
|
|
@@ -532,8 +532,8 @@
|
|
|
532
532
|
}
|
|
533
533
|
},
|
|
534
534
|
"node_modules/@bastani/atomic-natives-darwin-arm64": {
|
|
535
|
-
"version": "0.9.
|
|
536
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.
|
|
535
|
+
"version": "0.9.8",
|
|
536
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.8.tgz",
|
|
537
537
|
"license": "MIT",
|
|
538
538
|
"os": [
|
|
539
539
|
"darwin"
|
|
@@ -544,8 +544,8 @@
|
|
|
544
544
|
"optional": true
|
|
545
545
|
},
|
|
546
546
|
"node_modules/@bastani/atomic-natives-darwin-x64": {
|
|
547
|
-
"version": "0.9.
|
|
548
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.
|
|
547
|
+
"version": "0.9.8",
|
|
548
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.8.tgz",
|
|
549
549
|
"license": "MIT",
|
|
550
550
|
"os": [
|
|
551
551
|
"darwin"
|
|
@@ -556,8 +556,8 @@
|
|
|
556
556
|
"optional": true
|
|
557
557
|
},
|
|
558
558
|
"node_modules/@bastani/atomic-natives-linux-arm64-gnu": {
|
|
559
|
-
"version": "0.9.
|
|
560
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.
|
|
559
|
+
"version": "0.9.8",
|
|
560
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.8.tgz",
|
|
561
561
|
"license": "MIT",
|
|
562
562
|
"os": [
|
|
563
563
|
"linux"
|
|
@@ -571,8 +571,8 @@
|
|
|
571
571
|
"optional": true
|
|
572
572
|
},
|
|
573
573
|
"node_modules/@bastani/atomic-natives-linux-x64-gnu": {
|
|
574
|
-
"version": "0.9.
|
|
575
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.
|
|
574
|
+
"version": "0.9.8",
|
|
575
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.8.tgz",
|
|
576
576
|
"license": "MIT",
|
|
577
577
|
"os": [
|
|
578
578
|
"linux"
|
|
@@ -586,8 +586,8 @@
|
|
|
586
586
|
"optional": true
|
|
587
587
|
},
|
|
588
588
|
"node_modules/@bastani/atomic-natives-win32-arm64-msvc": {
|
|
589
|
-
"version": "0.9.
|
|
590
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.
|
|
589
|
+
"version": "0.9.8",
|
|
590
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.8.tgz",
|
|
591
591
|
"license": "MIT",
|
|
592
592
|
"os": [
|
|
593
593
|
"win32"
|
|
@@ -598,8 +598,8 @@
|
|
|
598
598
|
"optional": true
|
|
599
599
|
},
|
|
600
600
|
"node_modules/@bastani/atomic-natives-win32-x64-msvc": {
|
|
601
|
-
"version": "0.9.
|
|
602
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.
|
|
601
|
+
"version": "0.9.8",
|
|
602
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.8.tgz",
|
|
603
603
|
"license": "MIT",
|
|
604
604
|
"os": [
|
|
605
605
|
"win32"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/atomic",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.8",
|
|
4
4
|
"description": "Atomic coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"atomicConfig": {
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"prepublishOnly": "bun run clean && bun run build && bun run shrinkwrap"
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
|
-
"@bastani/atomic-natives": "0.9.
|
|
80
|
+
"@bastani/atomic-natives": "0.9.8",
|
|
81
81
|
"@bufbuild/protobuf": "^2.12.1",
|
|
82
82
|
"@earendil-works/pi-agent-core": "^0.80.6",
|
|
83
83
|
"@earendil-works/pi-ai": "^0.80.6",
|