@bastani/atomic 0.8.14-0 → 0.8.15-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/README.md +0 -8
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/CHANGELOG.md +3 -0
- package/dist/builtin/mcp/index.ts +4 -8
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/skills/tmux/SKILL.md +220 -0
- package/dist/builtin/subagents/skills/tmux/scripts/find-sessions.sh +112 -0
- package/dist/builtin/subagents/skills/tmux/scripts/wait-for-text.sh +83 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +10 -1
- package/dist/builtin/workflows/README.md +3 -1
- package/dist/builtin/workflows/builtin/ralph.ts +222 -295
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/background-ui-adapter.ts +20 -11
- package/dist/builtin/workflows/src/extension/index.ts +1 -0
- package/dist/builtin/workflows/src/extension/status-writer.ts +18 -3
- package/dist/builtin/workflows/src/runs/background/runner.ts +8 -10
- package/dist/builtin/workflows/src/runs/foreground/executor.ts +484 -91
- package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +13 -2
- package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +41 -15
- package/dist/builtin/workflows/src/runs/shared/graph-inference.ts +31 -0
- package/dist/builtin/workflows/src/runs/shared/prompt-callsite.ts +98 -0
- package/dist/builtin/workflows/src/shared/persistence-restore.ts +3 -1
- package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +4 -0
- package/dist/builtin/workflows/src/shared/store-types.ts +12 -1
- package/dist/builtin/workflows/src/shared/store.ts +77 -3
- package/dist/builtin/workflows/src/tui/graph-view.ts +17 -1
- package/dist/builtin/workflows/src/tui/prompt-card.ts +185 -30
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +386 -21
- package/docs/changelog.mdx +41 -14
- package/docs/docs.json +1 -0
- package/docs/extensions.md +19 -19
- package/docs/images/workflow-input-picker.png +0 -0
- package/docs/images/workflow-list.png +0 -0
- package/docs/index.md +33 -27
- package/docs/providers.md +2 -2
- package/docs/quickstart.md +15 -15
- package/docs/sdk.md +8 -8
- package/docs/sessions.md +5 -5
- package/docs/settings.md +27 -1
- package/docs/skills.md +2 -2
- package/docs/subagents.md +157 -0
- package/docs/usage.md +7 -7
- package/docs/windows.md +8 -0
- package/docs/workflows.md +62 -9
- package/package.json +2 -1
- package/docs/images/doom-extension.png +0 -0
- package/docs/images/exy.png +0 -3
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* to store-backed pending
|
|
2
|
+
* Legacy background workflow HIL adapter — bridges
|
|
3
|
+
* `ctx.ui.input/confirm/select/editor` to run-level store-backed pending
|
|
4
|
+
* prompts instead of pi.ui modal dialogs.
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
6
|
+
* Normal detached workflow runs now use executor-owned synthetic prompt nodes
|
|
7
|
+
* backed by `StageSnapshot.pendingPrompt`; this adapter remains for tests and
|
|
8
|
+
* non-executor fallback callers that still need the run-level graph overlay:
|
|
7
9
|
*
|
|
8
10
|
* 1. Stage calls `ctx.ui.editor(prefill)`
|
|
9
11
|
* 2. Adapter records a `PendingPrompt` on the run via the store
|
|
@@ -17,6 +19,10 @@
|
|
|
17
19
|
* rejects via `recordRunEnd` so the executor can finalise cleanly — no leaked
|
|
18
20
|
* pending promises.
|
|
19
21
|
*
|
|
22
|
+
* @internal Legacy fallback retained for tests and non-executor callers.
|
|
23
|
+
* TODO(workflows): delete after all tests and fallback entrypoints migrate to
|
|
24
|
+
* executor-owned synthetic prompt nodes.
|
|
25
|
+
*
|
|
20
26
|
* cross-ref:
|
|
21
27
|
* src/shared/store-types.ts PendingPrompt
|
|
22
28
|
* src/shared/store.ts recordPendingPrompt / resolvePendingPrompt / awaitPendingPrompt
|
|
@@ -111,13 +117,13 @@ function fallbackForKind(descriptor: PromptDescriptor): unknown {
|
|
|
111
117
|
}
|
|
112
118
|
|
|
113
119
|
/**
|
|
114
|
-
* Build a `WorkflowUIAdapter` whose methods record prompts on `runId`
|
|
115
|
-
* the store and await user response through the graph viewer.
|
|
120
|
+
* Build a legacy `WorkflowUIAdapter` whose methods record prompts on `runId`
|
|
121
|
+
* via the store and await user response through the graph viewer overlay.
|
|
116
122
|
*
|
|
117
|
-
*
|
|
118
|
-
* `pi.ui.confirm`, etc. are intentionally never invoked
|
|
119
|
-
* The chat editor stays free;
|
|
120
|
-
* `/workflow connect` overlay.
|
|
123
|
+
* Detached workflow execution normally uses node-local prompt stages instead.
|
|
124
|
+
* `pi.ui.editor`, `pi.ui.confirm`, etc. are still intentionally never invoked
|
|
125
|
+
* from inside a background run. The chat editor stays free; fallback callers
|
|
126
|
+
* attend to run-level prompts via F2 / the `/workflow connect` overlay.
|
|
121
127
|
*
|
|
122
128
|
* `signal` is the run's `AbortController.signal`; when fired (e.g. via
|
|
123
129
|
* `/workflow interrupt <id>`), any HIL waiter rejects so the workflow body
|
|
@@ -144,6 +150,9 @@ export function buildBackgroundUIAdapter(
|
|
|
144
150
|
message: string,
|
|
145
151
|
options: readonly T[],
|
|
146
152
|
): Promise<T> {
|
|
153
|
+
if (options.length === 0) {
|
|
154
|
+
throw new Error("pi-workflows: ctx.ui.select requires at least one option");
|
|
155
|
+
}
|
|
147
156
|
const response = await ask(store, runId, {
|
|
148
157
|
kind: "select",
|
|
149
158
|
message,
|
|
@@ -152,7 +161,7 @@ export function buildBackgroundUIAdapter(
|
|
|
152
161
|
if (typeof response === "string" && (options as readonly string[]).includes(response)) {
|
|
153
162
|
return response as T;
|
|
154
163
|
}
|
|
155
|
-
return options[0]
|
|
164
|
+
return options[0]!;
|
|
156
165
|
},
|
|
157
166
|
|
|
158
167
|
async editor(initial?: string): Promise<string> {
|
|
@@ -3266,6 +3266,7 @@ function factory(pi: ExtensionAPI): void {
|
|
|
3266
3266
|
persistence: persistenceRef.current,
|
|
3267
3267
|
});
|
|
3268
3268
|
store.clear();
|
|
3269
|
+
stageControlRegistry.clear();
|
|
3269
3270
|
|
|
3270
3271
|
// pi-intercom session naming lives here so we don't trip the
|
|
3271
3272
|
// loader's "Action methods cannot be called during extension
|
|
@@ -42,6 +42,8 @@ export interface StatusWriterOpts {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
export interface StatusWriter {
|
|
45
|
+
/** Wait until all currently queued status writes have reached disk. */
|
|
46
|
+
flush(): Promise<void>;
|
|
45
47
|
/** Stop receiving store updates and cancel any pending flush. */
|
|
46
48
|
unsubscribe(): void;
|
|
47
49
|
}
|
|
@@ -105,7 +107,7 @@ export function createStatusWriter(
|
|
|
105
107
|
opts: StatusWriterOpts = {},
|
|
106
108
|
): StatusWriter {
|
|
107
109
|
if (!config.statusFile) {
|
|
108
|
-
return { unsubscribe() {} };
|
|
110
|
+
return { async flush() {}, unsubscribe() {} };
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
const filePath = resolveStatusFilePath(config, opts);
|
|
@@ -117,6 +119,7 @@ export function createStatusWriter(
|
|
|
117
119
|
let active = true;
|
|
118
120
|
let writing = false;
|
|
119
121
|
let pendingContent: string | null = null;
|
|
122
|
+
let drainPromise: Promise<void> | null = null;
|
|
120
123
|
|
|
121
124
|
function recordWriteError(err: unknown): void {
|
|
122
125
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -148,16 +151,28 @@ export function createStatusWriter(
|
|
|
148
151
|
}
|
|
149
152
|
} finally {
|
|
150
153
|
writing = false;
|
|
151
|
-
if (active && pendingContent !== null) void drainWrites();
|
|
152
154
|
}
|
|
153
155
|
}
|
|
154
156
|
|
|
157
|
+
function ensureDrain(): Promise<void> {
|
|
158
|
+
drainPromise ??= drainWrites().finally(() => {
|
|
159
|
+
drainPromise = null;
|
|
160
|
+
if (active && pendingContent !== null) void ensureDrain();
|
|
161
|
+
});
|
|
162
|
+
return drainPromise;
|
|
163
|
+
}
|
|
164
|
+
|
|
155
165
|
const unsubscribeStore = store.subscribe((snap: StoreSnapshot) => {
|
|
156
166
|
pendingContent = JSON.stringify(snap, null, 2);
|
|
157
|
-
void
|
|
167
|
+
void ensureDrain();
|
|
158
168
|
});
|
|
159
169
|
|
|
160
170
|
return {
|
|
171
|
+
async flush() {
|
|
172
|
+
while (active && (pendingContent !== null || drainPromise !== null)) {
|
|
173
|
+
await ensureDrain();
|
|
174
|
+
}
|
|
175
|
+
},
|
|
161
176
|
unsubscribe() {
|
|
162
177
|
active = false;
|
|
163
178
|
pendingContent = null;
|
|
@@ -23,7 +23,6 @@ import { run as syncRun } from "../foreground/executor.js";
|
|
|
23
23
|
import { cancellationRegistry as defaultCancellationRegistry } from "./cancellation-registry.js";
|
|
24
24
|
import { jobTracker as defaultJobTracker } from "./job-tracker.js";
|
|
25
25
|
import { store as defaultStore } from "../../shared/store.js";
|
|
26
|
-
import { buildBackgroundUIAdapter } from "../../extension/background-ui-adapter.js";
|
|
27
26
|
|
|
28
27
|
// ---------------------------------------------------------------------------
|
|
29
28
|
// Types
|
|
@@ -103,20 +102,19 @@ export function runDetached<TInputs extends Record<string, unknown>>(
|
|
|
103
102
|
// are not lost.
|
|
104
103
|
registry.register(runId, controller);
|
|
105
104
|
|
|
106
|
-
// 4. Build executor opts — inject runId seam, signal, and
|
|
107
|
-
// HIL
|
|
108
|
-
// dialogs (those steal focus from the main chat editor); the
|
|
109
|
-
// records prompts on
|
|
110
|
-
// response. Destructure `jobs`/`cancellation`/`ui` out so
|
|
111
|
-
// forwarded to RunOpts twice.
|
|
105
|
+
// 4. Build executor opts — inject runId seam, signal, and node-local
|
|
106
|
+
// store-backed HIL. Background runs must NOT route ctx.ui.* through pi.ui
|
|
107
|
+
// dialogs (those steal focus from the main chat editor); the executor
|
|
108
|
+
// records prompts on synthetic workflow nodes and the attached stage chat
|
|
109
|
+
// drives the response. Destructure `jobs`/`cancellation`/`ui` out so
|
|
110
|
+
// they're not forwarded to RunOpts twice.
|
|
112
111
|
const {
|
|
113
112
|
jobs: _jobs,
|
|
114
113
|
cancellation: _cancellation,
|
|
115
|
-
ui:
|
|
114
|
+
ui: _ui,
|
|
116
115
|
store: storeOverride,
|
|
117
116
|
...restOpts
|
|
118
117
|
} = opts;
|
|
119
|
-
void _ignoredFgUi;
|
|
120
118
|
const store: Store = storeOverride ?? defaultStore;
|
|
121
119
|
const execOpts: RunOpts = {
|
|
122
120
|
...restOpts,
|
|
@@ -124,7 +122,7 @@ export function runDetached<TInputs extends Record<string, unknown>>(
|
|
|
124
122
|
signal: controller.signal,
|
|
125
123
|
cancellation: registry,
|
|
126
124
|
store,
|
|
127
|
-
|
|
125
|
+
usePromptNodesForUi: true,
|
|
128
126
|
deferWorkflowStart: true,
|
|
129
127
|
};
|
|
130
128
|
|