@bastani/atomic 0.9.28-alpha.4 → 0.9.28-alpha.5
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 +16 -0
- package/dist/builtin/intercom/CHANGELOG.md +6 -0
- package/dist/builtin/intercom/README.md +3 -2
- package/dist/builtin/intercom/broker/broker.ts +90 -14
- package/dist/builtin/intercom/broker/paths.ts +4 -0
- package/dist/builtin/intercom/broker/socket-liveness.ts +32 -0
- package/dist/builtin/intercom/broker/socket-replacement-lock.ts +104 -0
- package/dist/builtin/intercom/broker/spawn.ts +108 -63
- package/dist/builtin/intercom/index.bundle.mjs +114 -61
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +6 -0
- package/dist/builtin/workflows/builtin/{chunk-aqv8ny38.js → chunk-9ywkdsa9.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-p6jagvyf.js → chunk-bnz4knhy.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-br4ac9a3.js → chunk-dx5sjaxe.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-p3xmajmj.js → chunk-v4scsq3y.js} +41 -13
- package/dist/builtin/workflows/builtin/goal.js +2 -2
- package/dist/builtin/workflows/builtin/index.js +3 -3
- package/dist/builtin/workflows/builtin/ralph.js +2 -2
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +38 -14
- package/dist/builtin/workflows/src/index.js +38 -14
- package/dist/cli/startup-ui.d.ts +3 -2
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +19 -4
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +5 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +13 -9
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/extensions/session-events.d.ts +2 -0
- package/dist/core/extensions/session-events.d.ts.map +1 -1
- package/dist/core/extensions/session-events.js.map +1 -1
- package/dist/core/provider-alias.d.ts.map +1 -1
- package/dist/core/provider-alias.js +8 -0
- package/dist/core/provider-alias.js.map +1 -1
- package/dist/core/provider-composer-internal.d.ts.map +1 -1
- package/dist/core/provider-composer-internal.js +6 -3
- package/dist/core/provider-composer-internal.js.map +1 -1
- package/dist/core/resource-loader-reload.d.ts.map +1 -1
- package/dist/core/resource-loader-reload.js +1 -0
- package/dist/core/resource-loader-reload.js.map +1 -1
- package/dist/core/resource-loader-types.d.ts +1 -0
- package/dist/core/resource-loader-types.d.ts.map +1 -1
- package/dist/core/resource-loader-types.js.map +1 -1
- package/dist/extensions/herdr/index.d.ts.map +1 -1
- package/dist/extensions/herdr/index.js +20 -2
- package/dist/extensions/herdr/index.js.map +1 -1
- package/dist/extensions/herdr/pane-owner.d.ts +7 -0
- package/dist/extensions/herdr/pane-owner.d.ts.map +1 -1
- package/dist/extensions/herdr/pane-owner.js +53 -11
- package/dist/extensions/herdr/pane-owner.js.map +1 -1
- package/dist/main-deferred-startup.d.ts +8 -0
- package/dist/main-deferred-startup.d.ts.map +1 -1
- package/dist/main-deferred-startup.js +6 -0
- package/dist/main-deferred-startup.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +11 -3
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/interactive-auth-routing.js +2 -2
- package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-extension-dialogs.js +8 -0
- package/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +1 -0
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-helpers.js +1 -1
- package/dist/modes/interactive/interactive-mode-helpers.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-types.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
- package/dist/modes/interactive/interactive-process-lifecycle.js +1 -1
- package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
- package/dist/modes/interactive/interactive-startup-trust.d.ts +6 -0
- package/dist/modes/interactive/interactive-startup-trust.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-startup-trust.js +15 -0
- package/dist/modes/interactive/interactive-startup-trust.js.map +1 -0
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +3 -0
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive-engine/engine-child-liveness.d.ts +1 -0
- package/dist/modes/interactive-engine/engine-child-liveness.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-child-liveness.js +15 -1
- package/dist/modes/interactive-engine/engine-child-liveness.js.map +1 -1
- package/dist/modes/interactive-engine/engine-monitor.d.ts +4 -0
- package/dist/modes/interactive-engine/engine-monitor.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-monitor.js +17 -0
- package/dist/modes/interactive-engine/engine-monitor.js.map +1 -1
- package/dist/modes/interactive-engine/engine-quit-intent.d.ts +16 -0
- package/dist/modes/interactive-engine/engine-quit-intent.d.ts.map +1 -0
- package/dist/modes/interactive-engine/engine-quit-intent.js +27 -0
- package/dist/modes/interactive-engine/engine-quit-intent.js.map +1 -0
- package/dist/modes/interactive-engine/extension-ui-bridge.d.ts +1 -0
- package/dist/modes/interactive-engine/extension-ui-bridge.d.ts.map +1 -1
- package/dist/modes/interactive-engine/extension-ui-bridge.js +5 -0
- package/dist/modes/interactive-engine/extension-ui-bridge.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.d.ts +4 -1
- package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.js +19 -2
- package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
- package/dist/modes/interactive-engine/protocol.d.ts +18 -1
- package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
- package/dist/modes/interactive-engine/protocol.js +6 -0
- package/dist/modes/interactive-engine/protocol.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +11 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +42 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-input-scheduler.js +2 -2
- package/dist/modes/rpc/rpc-input-scheduler.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +23 -6
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-provider-auth.js +1 -1
- package/dist/modes/rpc/rpc-provider-auth.js.map +1 -1
- package/docs/extensions/events.md +3 -0
- package/docs/herdr.md +11 -2
- package/docs/models.md +1 -1
- package/docs/providers.md +2 -0
- package/docs/sdk.md +1 -1
- package/docs/settings.md +1 -1
- package/npm-shrinkwrap.json +32 -32
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-input-scheduler.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-input-scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"rpc-input-scheduler.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-input-scheduler.ts"],"names":[],"mappings":"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","sourcesContent":["import { parseEngineExplicitQuitCommand, parseInteractiveEngineCommand } from \"../interactive-engine/protocol.ts\";\nimport type { RpcExtensionUIResponse } from \"./rpc-types.ts\";\n\nconst INTERRUPT_COMMANDS: ReadonlySet<string> = new Set([\n\t\"abort\",\n\t\"cancel_login_provider\",\n\t\"abort_compaction\",\n\t\"abort_retry\",\n\t\"abort_bash\",\n\t\"pause_queued_messages\",\n\t\"resume_queued_messages\",\n\t\"clear_queue\",\n]);\nconst CONCURRENT_COMMANDS: ReadonlySet<string> = new Set([\"bash\", \"user_bash\", \"refresh_models\"]);\n\nexport function isRpcExtensionUIResponse(value: unknown): value is RpcExtensionUIResponse {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"type\" in value &&\n\t\tvalue.type === \"extension_ui_response\" &&\n\t\t\"id\" in value &&\n\t\ttypeof value.id === \"string\"\n\t);\n}\n\n/**\n * Control frames must remain reachable while an ordinary RPC command is\n * pending. Interrupts cancel or adjust queued work for that command, while\n * host responses can unblock UI work awaited by it. Everything else stays on\n * the ordered command lane.\n */\nexport function isConcurrentRpcControlLine(line: string): boolean {\n\tif (parseInteractiveEngineCommand(line) || parseEngineExplicitQuitCommand(line)) return true;\n\tlet value: object | null;\n\ttry {\n\t\tconst parsed = JSON.parse(line) as object | boolean | null | number | string;\n\t\tvalue = typeof parsed === \"object\" && !Array.isArray(parsed) ? parsed : null;\n\t} catch {\n\t\treturn false;\n\t}\n\tif (isRpcExtensionUIResponse(value)) return true;\n\treturn (\n\t\tvalue !== null &&\n\t\t\"type\" in value &&\n\t\ttypeof value.type === \"string\" &&\n\t\t(INTERRUPT_COMMANDS.has(value.type) || CONCURRENT_COMMANDS.has(value.type))\n\t);\n}\n\n/**\n * Runs ordinary RPC input one frame at a time while giving validated control\n * frames and independently correlated bash executions a concurrent lane. The\n * first ordinary frame starts synchronously, so a following interrupt cannot\n * overtake initialization of the operation it is intended to cancel.\n */\nexport function createRpcInputScheduler(handleLine: (line: string) => Promise<void>): (line: string) => void {\n\tconst ordinaryQueue: string[] = [];\n\tlet ordinaryActive = false;\n\n\tconst invoke = (line: string): Promise<void> => {\n\t\ttry {\n\t\t\treturn handleLine(line);\n\t\t} catch (error) {\n\t\t\treturn Promise.reject(error);\n\t\t}\n\t};\n\n\tconst startNextOrdinary = (): void => {\n\t\tconst line = ordinaryQueue.shift();\n\t\tif (line === undefined) {\n\t\t\tordinaryActive = false;\n\t\t\treturn;\n\t\t}\n\t\tordinaryActive = true;\n\t\tvoid invoke(line)\n\t\t\t.finally(startNextOrdinary)\n\t\t\t.catch(() => {});\n\t};\n\n\treturn (line: string): void => {\n\t\tif (isConcurrentRpcControlLine(line)) {\n\t\t\tvoid invoke(line).catch(() => {});\n\t\t\treturn;\n\t\t}\n\t\tordinaryQueue.push(line);\n\t\tif (!ordinaryActive) startNextOrdinary();\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-mode.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"rpc-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-mode.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAwB/E,YAAY,EACX,UAAU,EACV,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,EACX,eAAe,GACf,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,cAAc;IAC9B,+BAA+B,CAAC,EAAE,OAAO,CAAC;CAC1C;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,WAAW,EAAE,mBAAmB,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,KAAK,CAAC,CA+M/G"}
|
|
@@ -20,6 +20,7 @@ import { startInteractiveEngineLiveness } from "../interactive-engine/engine-chi
|
|
|
20
20
|
import { EngineCustomUiService } from "../interactive-engine/engine-custom-ui.js";
|
|
21
21
|
import { EngineInputFormService } from "../interactive-engine/engine-input-form.js";
|
|
22
22
|
import { EngineProjectTrustService } from "../interactive-engine/engine-project-trust.js";
|
|
23
|
+
import { EngineQuitIntent } from "../interactive-engine/engine-quit-intent.js";
|
|
23
24
|
import { EngineRenderService } from "../interactive-engine/engine-render-service.js";
|
|
24
25
|
import { EngineSessionPickerService } from "../interactive-engine/engine-session-picker.js";
|
|
25
26
|
import { serializeInteractiveEngineMessage } from "../interactive-engine/protocol.js";
|
|
@@ -52,6 +53,7 @@ export async function runRpcMode(runtimeHost, options = {}) {
|
|
|
52
53
|
const renderService = interactiveEngineChild ? new EngineRenderService(writeRawStdout) : undefined;
|
|
53
54
|
const sessionPicker = interactiveEngineChild ? new EngineSessionPickerService(writeRawStdout) : undefined;
|
|
54
55
|
const inputForm = interactiveEngineChild ? new EngineInputFormService(writeRawStdout) : undefined;
|
|
56
|
+
const quitIntent = interactiveEngineChild ? new EngineQuitIntent(writeRawStdout) : undefined;
|
|
55
57
|
const projectTrust = interactiveEngineChild
|
|
56
58
|
? new EngineProjectTrustService(() => runtimeHost.session.extensionRunner)
|
|
57
59
|
: undefined;
|
|
@@ -110,7 +112,21 @@ export async function runRpcMode(runtimeHost, options = {}) {
|
|
|
110
112
|
reloadResources: deferInteractiveEngineResources ? loadDeferredResources : undefined,
|
|
111
113
|
shouldRetryResources: deferInteractiveEngineResources ? () => resourceReadiness.needsRetry() : undefined,
|
|
112
114
|
});
|
|
113
|
-
|
|
115
|
+
/**
|
|
116
|
+
* Whether this shutdown ends the process but not the conversation. A signal and a
|
|
117
|
+
* closed stdin only do that when no explicit quit was announced: the interactive host
|
|
118
|
+
* announces one before it stops the engine, so anything else is the host being
|
|
119
|
+
* signalled or dying. A standalone RPC client has no such announcement; for it a
|
|
120
|
+
* signal is a host termination and a closed stdin or a shutdown request is a deliberate end.
|
|
121
|
+
*/
|
|
122
|
+
const endsProcessOnly = (cause) => {
|
|
123
|
+
if (cause === "request")
|
|
124
|
+
return false;
|
|
125
|
+
if (quitIntent)
|
|
126
|
+
return !quitIntent.explicitQuitRequested;
|
|
127
|
+
return cause === "signal";
|
|
128
|
+
};
|
|
129
|
+
async function shutdown(exitCode = 0, signal, cause = "request") {
|
|
114
130
|
if (shuttingDown) {
|
|
115
131
|
process.exit(exitCode);
|
|
116
132
|
}
|
|
@@ -129,7 +145,7 @@ export async function runRpcMode(runtimeHost, options = {}) {
|
|
|
129
145
|
inputForm?.dispose();
|
|
130
146
|
projectTrust?.dispose();
|
|
131
147
|
outputBuffer.dispose();
|
|
132
|
-
await runtimeHost.dispose();
|
|
148
|
+
await runtimeHost.dispose({ fromSignal: endsProcessOnly(cause) });
|
|
133
149
|
if (signal !== "SIGTERM") {
|
|
134
150
|
await flushRawStdout();
|
|
135
151
|
}
|
|
@@ -148,7 +164,7 @@ export async function runRpcMode(runtimeHost, options = {}) {
|
|
|
148
164
|
for (const signal of signals) {
|
|
149
165
|
const handler = () => {
|
|
150
166
|
killTrackedDetachedChildren();
|
|
151
|
-
void shutdown(signal === "SIGHUP" ? 129 : 143, signal);
|
|
167
|
+
void shutdown(signal === "SIGHUP" ? 129 : 143, signal, "signal");
|
|
152
168
|
};
|
|
153
169
|
process.on(signal, handler);
|
|
154
170
|
signalCleanupHandlers.push(() => process.off(signal, handler));
|
|
@@ -163,8 +179,9 @@ export async function runRpcMode(runtimeHost, options = {}) {
|
|
|
163
179
|
announceRequestAccepted: interactiveEngineChild
|
|
164
180
|
? (requestId, command) => writeRawStdout(serializeInteractiveEngineMessage({ type: "engine_request_accepted", requestId, command }))
|
|
165
181
|
: undefined,
|
|
166
|
-
handleInteractiveEngineLine: customUi || renderService || sessionPicker || inputForm || projectTrust
|
|
167
|
-
? (line) =>
|
|
182
|
+
handleInteractiveEngineLine: customUi || renderService || sessionPicker || inputForm || projectTrust || quitIntent
|
|
183
|
+
? (line) => quitIntent?.handleLine(line) === true ||
|
|
184
|
+
customUi?.handleLine(line) === true ||
|
|
168
185
|
renderService?.handleLine(line) === true ||
|
|
169
186
|
sessionPicker?.handleLine(line) === true ||
|
|
170
187
|
inputForm?.handleLine(line) === true ||
|
|
@@ -172,7 +189,7 @@ export async function runRpcMode(runtimeHost, options = {}) {
|
|
|
172
189
|
: undefined,
|
|
173
190
|
});
|
|
174
191
|
const onInputEnd = () => {
|
|
175
|
-
void shutdown();
|
|
192
|
+
void shutdown(0, undefined, "input-end");
|
|
176
193
|
};
|
|
177
194
|
process.stdin.on("end", onInputEnd);
|
|
178
195
|
detachInput = (() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-mode.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-mode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,8BAA8B,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAClF,OAAO,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AACpF,OAAO,EAAE,yBAAyB,EAAE,MAAM,+CAA+C,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,gDAAgD,CAAC;AACrF,OAAO,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAC5F,OAAO,EAAE,iCAAiC,EAAE,MAAM,mCAAmC,CAAC;AACtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAe7D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,WAAgC,EAAE,OAAO,GAAmB,EAAE;IAC9F,cAAc,EAAE,CAAC;IAEjB,MAAM,sBAAsB,GAAG,wBAAwB,EAAE,CAAC;IAC1D,MAAM,+BAA+B,GAAG,sBAAsB,IAAI,OAAO,CAAC,+BAA+B,KAAK,IAAI,CAAC;IACnH,MAAM,iBAAiB,GAAG,IAAI,oBAAoB,EAAE,CAAC;IACrD,MAAM,WAAW,GAAG,sBAAsB,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClH,IAAI,WAAW;QAAE,cAAc,CAAC,WAAW,CAAC,CAAC;IAE7C,MAAM,YAAY,GAAG,IAAI,eAAe,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;IACnC,MAAM,wBAAwB,GAAgC,IAAI,GAAG,EAAE,CAAC;IACxE,MAAM,qBAAqB,GAAsB,EAAE,CAAC;IACpD,MAAM,cAAc,GAAG,8BAA8B,CAAC,cAAc,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,qBAAqB,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClG,MAAM,aAAa,GAAG,sBAAsB,CAAC,CAAC,CAAC,IAAI,mBAAmB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnG,MAAM,aAAa,GAAG,sBAAsB,CAAC,CAAC,CAAC,IAAI,0BAA0B,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1G,MAAM,SAAS,GAAG,sBAAsB,CAAC,CAAC,CAAC,IAAI,sBAAsB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClG,MAAM,YAAY,GAAG,sBAAsB;QAC1C,CAAC,CAAC,IAAI,yBAAyB,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC;QAC1E,CAAC,CAAC,SAAS,CAAC;IACb,MAAM,iBAAiB,GAAG,WAAW;QACpC,CAAC,CAAC,IAAI,4BAA4B,CAChC,WAAW,EACX,CAAC,KAAK,EAAE,EAAE,CACT,cAAc,CAAC,iCAAiC,CAAC,EAAE,IAAI,EAAE,6BAA6B,EAAE,KAAK,EAAE,CAAC,CAAC,EAClG,CAAC,OAAO,EAAE,iBAAiB,EAAE,EAAE,CAC9B,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;YACtF,GAAG;YACH,GAAG,CAAC,QAAQ,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC;YACpF,GAAG,CAAC,QAAQ,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;SACjF,CAAC,CAAC,CACJ;QACF,CAAC,CAAC,SAAS,CAAC;IAEb,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,WAAW,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IAE3B,MAAM,eAAe,GAAG,GAAG,EAAE;QAC5B,iBAAiB,GAAG,IAAI,CAAC;IAC1B,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,IAAI,iBAAiB,CAAC;QAC5C,WAAW;QACX,MAAM;QACN,wBAAwB;QACxB,eAAe;QACf,QAAQ;QACR,aAAa;QACb,aAAa;QACb,SAAS;QACT,iBAAiB;KACjB,CAAC,CAAC;IACH,MAAM,qBAAqB,GAAG,GAAG,EAAE,CAClC,iBAAiB,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;QAChC,IAAI,CAAC;YACJ,MAAM,cAAc,CAAC,qBAAqB,EAAE,CAAC;YAC7C,mBAAmB,CAAC,wBAAwB,CAAC,CAAC;YAC9C,cAAc,CAAC,cAAc,EAAE,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,aAAa,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAChF,cAAc,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;YAC9C,MAAM,aAAa,CAAC;QACrB,CAAC;IACF,CAAC,CAAC,CAAC;IAEJ,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAAE;QACvC,YAAY,EAAE,OAAO,EAAE,CAAC;QACxB,MAAM,cAAc,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,uBAAuB,CAAC;QAC7C,WAAW;QACX,UAAU,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,cAAc;QAC/C,aAAa,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,aAAa,EAAE;QACnD,MAAM;QACN,WAAW;QACX,wEAAwE;QACxE,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;QAClF,iBAAiB;QACjB,SAAS;QACT,wBAAwB;QACxB,gBAAgB,EAAE,+BAA+B,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS;QAC9F,eAAe,EAAE,+BAA+B,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS;QACpF,oBAAoB,EAAE,+BAA+B,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS;KACxG,CAAC,CAAC;IAEH,KAAK,UAAU,QAAQ,CAAC,QAAQ,GAAG,CAAC,EAAE,MAAuB;QAC5D,IAAI,YAAY,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxB,CAAC;QACD,YAAY,GAAG,IAAI,CAAC;QACpB,WAAW,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,aAAa,CAAC,iBAAiB,EAAE,CAAC;QACxC,KAAK,MAAM,OAAO,IAAI,qBAAqB,EAAE,CAAC;YAC7C,OAAO,EAAE,CAAC;QACX,CAAC;QACD,cAAc,CAAC,oBAAoB,EAAE,CAAC;QACtC,cAAc,CAAC,IAAI,EAAE,CAAC;QACtB,QAAQ,EAAE,OAAO,EAAE,CAAC;QACpB,aAAa,EAAE,OAAO,EAAE,CAAC;QACzB,aAAa,EAAE,OAAO,EAAE,CAAC;QACzB,SAAS,EAAE,OAAO,EAAE,CAAC;QACrB,YAAY,EAAE,OAAO,EAAE,CAAC;QACxB,YAAY,CAAC,OAAO,EAAE,CAAC;QACvB,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;QAC5B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,cAAc,EAAE,CAAC;QACxB,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC;IAED,MAAM,sBAAsB,GAAG,KAAK,IAAmB,EAAE;QACxD,IAAI,CAAC,iBAAiB;YAAE,OAAO;QAC/B,MAAM,QAAQ,EAAE,CAAC;IAClB,CAAC,CAAC;IAEF,MAAM,sBAAsB,GAAG,GAAS,EAAE;QACzC,MAAM,OAAO,GAAqB,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxB,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,GAAG,EAAE;gBACpB,2BAA2B,EAAE,CAAC;gBAC9B,KAAK,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACxD,CAAC,CAAC;YACF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC5B,qBAAqB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QAChE,CAAC;IACF,CAAC,CAAC;IAEF,MAAM,eAAe,GAAG,yBAAyB,CAAC;QACjD,MAAM;QACN,wBAAwB;QACxB,aAAa;QACb,sBAAsB;QACtB,qEAAqE;QACrE,uBAAuB,EAAE,sBAAsB;YAC9C,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,CACvB,cAAc,CACb,iCAAiC,CAAC,EAAE,IAAI,EAAE,yBAAyB,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAC1F;YACH,CAAC,CAAC,SAAS;QACZ,2BAA2B,EAC1B,QAAQ,IAAI,aAAa,IAAI,aAAa,IAAI,SAAS,IAAI,YAAY;YACtE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CACT,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI;gBACnC,aAAa,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI;gBACxC,aAAa,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI;gBACxC,SAAS,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI;gBACpC,YAAY,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI;YACzC,CAAC,CAAC,SAAS;KACb,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,GAAG,EAAE;QACvB,KAAK,QAAQ,EAAE,CAAC;IACjB,CAAC,CAAC;IACF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAEpC,WAAW,GAAG,CAAC,GAAG,EAAE;QACnB,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,eAAe,CAAC,CAAC;QACnE,MAAM,WAAW,GAAG,qBAAqB,CAAC,OAAO,CAAC,KAAK,EAAE,iBAAiB,EAAE;YAC3E,eAAe,EAAE,GAAG,GAAG,IAAI;SAC3B,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACX,WAAW,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QACtC,CAAC,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IACL,sBAAsB,EAAE,CAAC;IACzB,cAAc,CAAC,KAAK,EAAE,CAAC;IACvB,MAAM,cAAc,CAAC,aAAa,EAAE,CAAC;IACrC,IAAI,sBAAsB;QAAE,cAAc,CAAC,KAAK,EAAE,CAAC;IACnD,IAAI,+BAA+B,EAAE,CAAC;QACrC,uEAAuE;QACvE,oFAAoF;QACpF,KAAK,qBAAqB,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC9C,CAAC;SAAM,IAAI,sBAAsB,EAAE,CAAC;QACnC,mBAAmB,CAAC,wBAAwB,CAAC,CAAC;QAC9C,cAAc,CAAC,cAAc,EAAE,CAAC;IACjC,CAAC;IAED,6BAA6B;IAC7B,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["import { markLifecycleTiming } from \"../../core/lifecycle-timings.ts\";\n/**\n * RPC mode: Headless operation with JSON stdin/stdout protocol.\n *\n * Used for embedding the agent in other applications.\n * Receives commands as JSON on stdin, outputs events and responses as JSON on stdout.\n *\n * Protocol:\n * - Commands: JSON objects with `type` field, optional `id` for correlation\n * - Responses: JSON objects with `type: \"response\"`, `command`, `success`, and optional `data`/`error`\n * - Events: AgentSessionEvent objects streamed as they occur\n * - Extension UI: Extension UI requests are emitted, client responds with extension_ui_response\n */\n\nimport { setKeybindings } from \"@earendil-works/pi-tui\";\nimport type { AgentSession } from \"../../core/agent-session.js\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\nimport { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport { flushRawStdout, takeOverStdout, writeRawStdout } from \"../../core/output-guard.ts\";\nimport { isInteractiveEngineChild } from \"../../utils/interactive-engine-env.ts\";\nimport { killTrackedDetachedChildren } from \"../../utils/shell.ts\";\nimport { startInteractiveEngineLiveness } from \"../interactive-engine/engine-child-liveness.ts\";\nimport { EngineCustomUiService } from \"../interactive-engine/engine-custom-ui.ts\";\nimport { EngineInputFormService } from \"../interactive-engine/engine-input-form.ts\";\nimport { EngineProjectTrustService } from \"../interactive-engine/engine-project-trust.js\";\nimport { EngineRenderService } from \"../interactive-engine/engine-render-service.ts\";\nimport { EngineSessionPickerService } from \"../interactive-engine/engine-session-picker.ts\";\nimport { serializeInteractiveEngineMessage } from \"../interactive-engine/protocol.ts\";\nimport { attachJsonlLineReader } from \"./jsonl.ts\";\nimport { createRpcCommandHandler } from \"./rpc-command-handler.ts\";\nimport type { RpcPendingExtensionRequests } from \"./rpc-extension-ui.ts\";\nimport { createRpcInputLineHandler } from \"./rpc-input.ts\";\nimport { createRpcInputScheduler } from \"./rpc-input-scheduler.ts\";\nimport { KeybindingsReloadCoordinator } from \"./rpc-keybindings-reload.ts\";\nimport { RpcOutputBuffer } from \"./rpc-output-buffer.ts\";\nimport { RpcResourceReadiness } from \"./rpc-resource-readiness.ts\";\nimport { RpcSessionBinding } from \"./rpc-session-binding.ts\";\n\n// Re-export types for consumers\nexport type {\n\tRpcCommand,\n\tRpcExtensionUIRequest,\n\tRpcExtensionUIResponse,\n\tRpcResponse,\n\tRpcSessionState,\n} from \"./rpc-types.ts\";\n\nexport interface RpcModeOptions {\n\tdeferInteractiveEngineResources?: boolean;\n}\n\n/**\n * Run in RPC mode.\n * Listens for JSON commands on stdin, outputs events and responses on stdout.\n */\nexport async function runRpcMode(runtimeHost: AgentSessionRuntime, options: RpcModeOptions = {}): Promise<never> {\n\ttakeOverStdout();\n\n\tconst interactiveEngineChild = isInteractiveEngineChild();\n\tconst deferInteractiveEngineResources = interactiveEngineChild && options.deferInteractiveEngineResources === true;\n\tconst resourceReadiness = new RpcResourceReadiness();\n\tconst keybindings = interactiveEngineChild ? KeybindingsManager.create(runtimeHost.services.agentDir) : undefined;\n\tif (keybindings) setKeybindings(keybindings);\n\n\tconst outputBuffer = new RpcOutputBuffer();\n\tconst output = outputBuffer.output;\n\tconst pendingExtensionRequests: RpcPendingExtensionRequests = new Map();\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\tconst engineLiveness = startInteractiveEngineLiveness(writeRawStdout);\n\tconst customUi = keybindings ? new EngineCustomUiService(writeRawStdout, keybindings) : undefined;\n\tconst renderService = interactiveEngineChild ? new EngineRenderService(writeRawStdout) : undefined;\n\tconst sessionPicker = interactiveEngineChild ? new EngineSessionPickerService(writeRawStdout) : undefined;\n\tconst inputForm = interactiveEngineChild ? new EngineInputFormService(writeRawStdout) : undefined;\n\tconst projectTrust = interactiveEngineChild\n\t\t? new EngineProjectTrustService(() => runtimeHost.session.extensionRunner)\n\t\t: undefined;\n\tconst reloadCoordinator = keybindings\n\t\t? new KeybindingsReloadCoordinator<AgentSession>(\n\t\t\t\tkeybindings,\n\t\t\t\t(state) =>\n\t\t\t\t\twriteRawStdout(serializeInteractiveEngineMessage({ type: \"engine_keybindings_reloaded\", state })),\n\t\t\t\t(session, effectiveBindings) =>\n\t\t\t\t\t[...session.extensionRunner.getShortcuts(effectiveBindings)].map(([key, shortcut]) => ({\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\t...(shortcut.description === undefined ? {} : { description: shortcut.description }),\n\t\t\t\t\t\t...(shortcut.editorKeys === undefined ? {} : { editorKeys: shortcut.editorKeys }),\n\t\t\t\t\t})),\n\t\t\t)\n\t\t: undefined;\n\n\tlet shutdownRequested = false;\n\tlet shuttingDown = false;\n\tlet detachInput = () => {};\n\n\tconst requestShutdown = () => {\n\t\tshutdownRequested = true;\n\t};\n\n\tconst sessionBinding = new RpcSessionBinding({\n\t\truntimeHost,\n\t\toutput,\n\t\tpendingExtensionRequests,\n\t\trequestShutdown,\n\t\tcustomUi,\n\t\trenderService,\n\t\tsessionPicker,\n\t\tinputForm,\n\t\treloadCoordinator,\n\t});\n\tconst loadDeferredResources = () =>\n\t\tresourceReadiness.run(async () => {\n\t\t\ttry {\n\t\t\t\tawait sessionBinding.loadDeferredResources();\n\t\t\t\tmarkLifecycleTiming(\"engine-resources-ready\");\n\t\t\t\tengineLiveness.resourcesReady();\n\t\t\t} catch (error) {\n\t\t\t\tconst resourceError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\tengineLiveness.resourcesFailed(resourceError);\n\t\t\t\tthrow resourceError;\n\t\t\t}\n\t\t});\n\n\truntimeHost.setRebindSession(async () => {\n\t\tprojectTrust?.dispose();\n\t\tawait sessionBinding.rebindSession();\n\t});\n\n\tconst handleCommand = createRpcCommandHandler({\n\t\truntimeHost,\n\t\tgetSession: () => sessionBinding.currentSession,\n\t\trebindSession: () => sessionBinding.rebindSession(),\n\t\toutput,\n\t\tkeybindings,\n\t\t// Browsing host-owned task history is not an extension approval prompt.\n\t\ttaskInspectorUi: customUi ? { custom: customUi.custom.bind(customUi) } : undefined,\n\t\treloadCoordinator,\n\t\tinputForm,\n\t\tpendingExtensionRequests,\n\t\twaitForResources: deferInteractiveEngineResources ? () => resourceReadiness.wait() : undefined,\n\t\treloadResources: deferInteractiveEngineResources ? loadDeferredResources : undefined,\n\t\tshouldRetryResources: deferInteractiveEngineResources ? () => resourceReadiness.needsRetry() : undefined,\n\t});\n\n\tasync function shutdown(exitCode = 0, signal?: NodeJS.Signals): Promise<never> {\n\t\tif (shuttingDown) {\n\t\t\tprocess.exit(exitCode);\n\t\t}\n\t\tshuttingDown = true;\n\t\tdetachInput();\n\t\tprocess.stdin.pause();\n\t\tawait handleCommand.disposeActiveBash();\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tsessionBinding.disposeSubscriptions();\n\t\tengineLiveness.stop();\n\t\tcustomUi?.dispose();\n\t\trenderService?.dispose();\n\t\tsessionPicker?.dispose();\n\t\tinputForm?.dispose();\n\t\tprojectTrust?.dispose();\n\t\toutputBuffer.dispose();\n\t\tawait runtimeHost.dispose();\n\t\tif (signal !== \"SIGTERM\") {\n\t\t\tawait flushRawStdout();\n\t\t}\n\t\tprocess.exit(exitCode);\n\t}\n\n\tconst checkShutdownRequested = async (): Promise<void> => {\n\t\tif (!shutdownRequested) return;\n\t\tawait shutdown();\n\t};\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid shutdown(signal === \"SIGHUP\" ? 129 : 143, signal);\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tconst handleInputLine = createRpcInputLineHandler({\n\t\toutput,\n\t\tpendingExtensionRequests,\n\t\thandleCommand,\n\t\tcheckShutdownRequested,\n\t\t// Only the interactive engine host consults this ownership boundary.\n\t\tannounceRequestAccepted: interactiveEngineChild\n\t\t\t? (requestId, command) =>\n\t\t\t\t\twriteRawStdout(\n\t\t\t\t\t\tserializeInteractiveEngineMessage({ type: \"engine_request_accepted\", requestId, command }),\n\t\t\t\t\t)\n\t\t\t: undefined,\n\t\thandleInteractiveEngineLine:\n\t\t\tcustomUi || renderService || sessionPicker || inputForm || projectTrust\n\t\t\t\t? (line) =>\n\t\t\t\t\t\tcustomUi?.handleLine(line) === true ||\n\t\t\t\t\t\trenderService?.handleLine(line) === true ||\n\t\t\t\t\t\tsessionPicker?.handleLine(line) === true ||\n\t\t\t\t\t\tinputForm?.handleLine(line) === true ||\n\t\t\t\t\t\tprojectTrust?.handleLine(line) === true\n\t\t\t\t: undefined,\n\t});\n\n\tconst onInputEnd = () => {\n\t\tvoid shutdown();\n\t};\n\tprocess.stdin.on(\"end\", onInputEnd);\n\n\tdetachInput = (() => {\n\t\tconst scheduleInputLine = createRpcInputScheduler(handleInputLine);\n\t\tconst detachJsonl = attachJsonlLineReader(process.stdin, scheduleInputLine, {\n\t\t\tmaxBytesPerTurn: 256 * 1024,\n\t\t});\n\t\treturn () => {\n\t\t\tdetachJsonl();\n\t\t\tprocess.stdin.off(\"end\", onInputEnd);\n\t\t};\n\t})();\n\tregisterSignalHandlers();\n\tengineLiveness.ready();\n\tawait sessionBinding.rebindSession();\n\tif (interactiveEngineChild) engineLiveness.bound();\n\tif (deferInteractiveEngineResources) {\n\t\t// RPC control and the mandatory minimal session are usable now. Prompt\n\t\t// handling remains generation-gated until a retryable transactional reload commits.\n\t\tvoid loadDeferredResources().catch(() => {});\n\t} else if (interactiveEngineChild) {\n\t\tmarkLifecycleTiming(\"engine-resources-ready\");\n\t\tengineLiveness.resourcesReady();\n\t}\n\n\t// Keep process alive forever\n\treturn new Promise(() => {});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"rpc-mode.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-mode.ts"],"names":[],"mappings":"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","sourcesContent":["import { markLifecycleTiming } from \"../../core/lifecycle-timings.ts\";\n/**\n * RPC mode: Headless operation with JSON stdin/stdout protocol.\n *\n * Used for embedding the agent in other applications.\n * Receives commands as JSON on stdin, outputs events and responses as JSON on stdout.\n *\n * Protocol:\n * - Commands: JSON objects with `type` field, optional `id` for correlation\n * - Responses: JSON objects with `type: \"response\"`, `command`, `success`, and optional `data`/`error`\n * - Events: AgentSessionEvent objects streamed as they occur\n * - Extension UI: Extension UI requests are emitted, client responds with extension_ui_response\n */\n\nimport { setKeybindings } from \"@earendil-works/pi-tui\";\nimport type { AgentSession } from \"../../core/agent-session.js\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\nimport { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport { flushRawStdout, takeOverStdout, writeRawStdout } from \"../../core/output-guard.ts\";\nimport { isInteractiveEngineChild } from \"../../utils/interactive-engine-env.ts\";\nimport { killTrackedDetachedChildren } from \"../../utils/shell.ts\";\nimport { startInteractiveEngineLiveness } from \"../interactive-engine/engine-child-liveness.ts\";\nimport { EngineCustomUiService } from \"../interactive-engine/engine-custom-ui.ts\";\nimport { EngineInputFormService } from \"../interactive-engine/engine-input-form.ts\";\nimport { EngineProjectTrustService } from \"../interactive-engine/engine-project-trust.js\";\nimport { EngineQuitIntent } from \"../interactive-engine/engine-quit-intent.ts\";\nimport { EngineRenderService } from \"../interactive-engine/engine-render-service.ts\";\nimport { EngineSessionPickerService } from \"../interactive-engine/engine-session-picker.ts\";\nimport { serializeInteractiveEngineMessage } from \"../interactive-engine/protocol.ts\";\nimport { attachJsonlLineReader } from \"./jsonl.ts\";\nimport { createRpcCommandHandler } from \"./rpc-command-handler.ts\";\nimport type { RpcPendingExtensionRequests } from \"./rpc-extension-ui.ts\";\nimport { createRpcInputLineHandler } from \"./rpc-input.ts\";\nimport { createRpcInputScheduler } from \"./rpc-input-scheduler.ts\";\nimport { KeybindingsReloadCoordinator } from \"./rpc-keybindings-reload.ts\";\nimport { RpcOutputBuffer } from \"./rpc-output-buffer.ts\";\nimport { RpcResourceReadiness } from \"./rpc-resource-readiness.ts\";\nimport { RpcSessionBinding } from \"./rpc-session-binding.ts\";\n\n// Re-export types for consumers\nexport type {\n\tRpcCommand,\n\tRpcExtensionUIRequest,\n\tRpcExtensionUIResponse,\n\tRpcResponse,\n\tRpcSessionState,\n} from \"./rpc-types.ts\";\n\nexport interface RpcModeOptions {\n\tdeferInteractiveEngineResources?: boolean;\n}\n\n/**\n * Run in RPC mode.\n * Listens for JSON commands on stdin, outputs events and responses on stdout.\n */\nexport async function runRpcMode(runtimeHost: AgentSessionRuntime, options: RpcModeOptions = {}): Promise<never> {\n\ttakeOverStdout();\n\n\tconst interactiveEngineChild = isInteractiveEngineChild();\n\tconst deferInteractiveEngineResources = interactiveEngineChild && options.deferInteractiveEngineResources === true;\n\tconst resourceReadiness = new RpcResourceReadiness();\n\tconst keybindings = interactiveEngineChild ? KeybindingsManager.create(runtimeHost.services.agentDir) : undefined;\n\tif (keybindings) setKeybindings(keybindings);\n\n\tconst outputBuffer = new RpcOutputBuffer();\n\tconst output = outputBuffer.output;\n\tconst pendingExtensionRequests: RpcPendingExtensionRequests = new Map();\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\tconst engineLiveness = startInteractiveEngineLiveness(writeRawStdout);\n\tconst customUi = keybindings ? new EngineCustomUiService(writeRawStdout, keybindings) : undefined;\n\tconst renderService = interactiveEngineChild ? new EngineRenderService(writeRawStdout) : undefined;\n\tconst sessionPicker = interactiveEngineChild ? new EngineSessionPickerService(writeRawStdout) : undefined;\n\tconst inputForm = interactiveEngineChild ? new EngineInputFormService(writeRawStdout) : undefined;\n\tconst quitIntent = interactiveEngineChild ? new EngineQuitIntent(writeRawStdout) : undefined;\n\tconst projectTrust = interactiveEngineChild\n\t\t? new EngineProjectTrustService(() => runtimeHost.session.extensionRunner)\n\t\t: undefined;\n\tconst reloadCoordinator = keybindings\n\t\t? new KeybindingsReloadCoordinator<AgentSession>(\n\t\t\t\tkeybindings,\n\t\t\t\t(state) =>\n\t\t\t\t\twriteRawStdout(serializeInteractiveEngineMessage({ type: \"engine_keybindings_reloaded\", state })),\n\t\t\t\t(session, effectiveBindings) =>\n\t\t\t\t\t[...session.extensionRunner.getShortcuts(effectiveBindings)].map(([key, shortcut]) => ({\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\t...(shortcut.description === undefined ? {} : { description: shortcut.description }),\n\t\t\t\t\t\t...(shortcut.editorKeys === undefined ? {} : { editorKeys: shortcut.editorKeys }),\n\t\t\t\t\t})),\n\t\t\t)\n\t\t: undefined;\n\n\tlet shutdownRequested = false;\n\tlet shuttingDown = false;\n\tlet detachInput = () => {};\n\n\tconst requestShutdown = () => {\n\t\tshutdownRequested = true;\n\t};\n\n\tconst sessionBinding = new RpcSessionBinding({\n\t\truntimeHost,\n\t\toutput,\n\t\tpendingExtensionRequests,\n\t\trequestShutdown,\n\t\tcustomUi,\n\t\trenderService,\n\t\tsessionPicker,\n\t\tinputForm,\n\t\treloadCoordinator,\n\t});\n\tconst loadDeferredResources = () =>\n\t\tresourceReadiness.run(async () => {\n\t\t\ttry {\n\t\t\t\tawait sessionBinding.loadDeferredResources();\n\t\t\t\tmarkLifecycleTiming(\"engine-resources-ready\");\n\t\t\t\tengineLiveness.resourcesReady();\n\t\t\t} catch (error) {\n\t\t\t\tconst resourceError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\tengineLiveness.resourcesFailed(resourceError);\n\t\t\t\tthrow resourceError;\n\t\t\t}\n\t\t});\n\n\truntimeHost.setRebindSession(async () => {\n\t\tprojectTrust?.dispose();\n\t\tawait sessionBinding.rebindSession();\n\t});\n\n\tconst handleCommand = createRpcCommandHandler({\n\t\truntimeHost,\n\t\tgetSession: () => sessionBinding.currentSession,\n\t\trebindSession: () => sessionBinding.rebindSession(),\n\t\toutput,\n\t\tkeybindings,\n\t\t// Browsing host-owned task history is not an extension approval prompt.\n\t\ttaskInspectorUi: customUi ? { custom: customUi.custom.bind(customUi) } : undefined,\n\t\treloadCoordinator,\n\t\tinputForm,\n\t\tpendingExtensionRequests,\n\t\twaitForResources: deferInteractiveEngineResources ? () => resourceReadiness.wait() : undefined,\n\t\treloadResources: deferInteractiveEngineResources ? loadDeferredResources : undefined,\n\t\tshouldRetryResources: deferInteractiveEngineResources ? () => resourceReadiness.needsRetry() : undefined,\n\t});\n\n\t/**\n\t * Whether this shutdown ends the process but not the conversation. A signal and a\n\t * closed stdin only do that when no explicit quit was announced: the interactive host\n\t * announces one before it stops the engine, so anything else is the host being\n\t * signalled or dying. A standalone RPC client has no such announcement; for it a\n\t * signal is a host termination and a closed stdin or a shutdown request is a deliberate end.\n\t */\n\tconst endsProcessOnly = (cause: \"signal\" | \"input-end\" | \"request\"): boolean => {\n\t\tif (cause === \"request\") return false;\n\t\tif (quitIntent) return !quitIntent.explicitQuitRequested;\n\t\treturn cause === \"signal\";\n\t};\n\n\tasync function shutdown(\n\t\texitCode = 0,\n\t\tsignal?: NodeJS.Signals,\n\t\tcause: \"signal\" | \"input-end\" | \"request\" = \"request\",\n\t): Promise<never> {\n\t\tif (shuttingDown) {\n\t\t\tprocess.exit(exitCode);\n\t\t}\n\t\tshuttingDown = true;\n\t\tdetachInput();\n\t\tprocess.stdin.pause();\n\t\tawait handleCommand.disposeActiveBash();\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tsessionBinding.disposeSubscriptions();\n\t\tengineLiveness.stop();\n\t\tcustomUi?.dispose();\n\t\trenderService?.dispose();\n\t\tsessionPicker?.dispose();\n\t\tinputForm?.dispose();\n\t\tprojectTrust?.dispose();\n\t\toutputBuffer.dispose();\n\t\tawait runtimeHost.dispose({ fromSignal: endsProcessOnly(cause) });\n\t\tif (signal !== \"SIGTERM\") {\n\t\t\tawait flushRawStdout();\n\t\t}\n\t\tprocess.exit(exitCode);\n\t}\n\n\tconst checkShutdownRequested = async (): Promise<void> => {\n\t\tif (!shutdownRequested) return;\n\t\tawait shutdown();\n\t};\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid shutdown(signal === \"SIGHUP\" ? 129 : 143, signal, \"signal\");\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tconst handleInputLine = createRpcInputLineHandler({\n\t\toutput,\n\t\tpendingExtensionRequests,\n\t\thandleCommand,\n\t\tcheckShutdownRequested,\n\t\t// Only the interactive engine host consults this ownership boundary.\n\t\tannounceRequestAccepted: interactiveEngineChild\n\t\t\t? (requestId, command) =>\n\t\t\t\t\twriteRawStdout(\n\t\t\t\t\t\tserializeInteractiveEngineMessage({ type: \"engine_request_accepted\", requestId, command }),\n\t\t\t\t\t)\n\t\t\t: undefined,\n\t\thandleInteractiveEngineLine:\n\t\t\tcustomUi || renderService || sessionPicker || inputForm || projectTrust || quitIntent\n\t\t\t\t? (line) =>\n\t\t\t\t\t\tquitIntent?.handleLine(line) === true ||\n\t\t\t\t\t\tcustomUi?.handleLine(line) === true ||\n\t\t\t\t\t\trenderService?.handleLine(line) === true ||\n\t\t\t\t\t\tsessionPicker?.handleLine(line) === true ||\n\t\t\t\t\t\tinputForm?.handleLine(line) === true ||\n\t\t\t\t\t\tprojectTrust?.handleLine(line) === true\n\t\t\t\t: undefined,\n\t});\n\n\tconst onInputEnd = () => {\n\t\tvoid shutdown(0, undefined, \"input-end\");\n\t};\n\tprocess.stdin.on(\"end\", onInputEnd);\n\n\tdetachInput = (() => {\n\t\tconst scheduleInputLine = createRpcInputScheduler(handleInputLine);\n\t\tconst detachJsonl = attachJsonlLineReader(process.stdin, scheduleInputLine, {\n\t\t\tmaxBytesPerTurn: 256 * 1024,\n\t\t});\n\t\treturn () => {\n\t\t\tdetachJsonl();\n\t\t\tprocess.stdin.off(\"end\", onInputEnd);\n\t\t};\n\t})();\n\tregisterSignalHandlers();\n\tengineLiveness.ready();\n\tawait sessionBinding.rebindSession();\n\tif (interactiveEngineChild) engineLiveness.bound();\n\tif (deferInteractiveEngineResources) {\n\t\t// RPC control and the mandatory minimal session are usable now. Prompt\n\t\t// handling remains generation-gated until a retryable transactional reload commits.\n\t\tvoid loadDeferredResources().catch(() => {});\n\t} else if (interactiveEngineChild) {\n\t\tmarkLifecycleTiming(\"engine-resources-ready\");\n\t\tengineLiveness.resourcesReady();\n\t}\n\n\t// Keep process alive forever\n\treturn new Promise(() => {});\n}\n"]}
|
|
@@ -10,7 +10,7 @@ export class RpcProviderAuth {
|
|
|
10
10
|
this.oauthTransport = oauthTransport;
|
|
11
11
|
}
|
|
12
12
|
async login(session, provider, loginId = provider) {
|
|
13
|
-
if (!session.modelRuntime.getProvider(provider)?.auth.apiKey)
|
|
13
|
+
if (!session.modelRuntime.getProvider(provider)?.auth.apiKey?.login)
|
|
14
14
|
throw new Error(`Provider does not support API-key login: ${provider}`);
|
|
15
15
|
if (!this.inputForm)
|
|
16
16
|
throw new Error("Provider login requires an interactive input host");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-provider-auth.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-provider-auth.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Credential } from \"@bastani/pi-ai\";\nimport type { AgentSession } from \"../../core/agent-session.js\";\nimport type { HostInputFormRequest } from \"../../core/extensions/ui-types.js\";\nimport { CredentialSynchronizationError, type SaveCredentialOptions } from \"../../core/model-runtime.js\";\nimport { createAuthInteraction, isOAuthLoginCancelled } from \"../../core/oauth-login.ts\";\nimport { createRpcOAuthCallbacks, type OAuthInteractionTransport } from \"./rpc-oauth-interaction.ts\";\nimport type { RpcLoginProviderResult, RpcModelCatalog, RpcOAuthLoginProviderResult } from \"./rpc-types.ts\";\n\nexport interface ProviderLoginInput {\n\topen(request: HostInputFormRequest, signal?: AbortSignal): Promise<Record<string, string> | undefined>;\n}\ninterface ActiveLogin {\n\tprovider: string;\n\tcontroller: AbortController;\n}\n\nexport class RpcProviderAuth {\n\tprivate readonly controllers = new Map<string, ActiveLogin>();\n\tprivate readonly inputForm: ProviderLoginInput | undefined;\n\tprivate readonly oauthTransport: OAuthInteractionTransport | undefined;\n\tconstructor(inputForm?: ProviderLoginInput, oauthTransport?: OAuthInteractionTransport) {\n\t\tthis.inputForm = inputForm;\n\t\tthis.oauthTransport = oauthTransport;\n\t}\n\n\tasync login(session: AgentSession, provider: string, loginId = provider): Promise<RpcLoginProviderResult> {\n\t\tif (!session.modelRuntime.getProvider(provider)?.auth.apiKey)\n\t\t\tthrow new Error(`Provider does not support API-key login: ${provider}`);\n\t\tif (!this.inputForm) throw new Error(\"Provider login requires an interactive input host\");\n\t\tconst controller = this.begin(provider, loginId);\n\t\ttry {\n\t\t\tconst credential = await session.modelRuntime.login(provider, \"api_key\", {\n\t\t\t\tsignal: controller.signal,\n\t\t\t\tprompt: async (prompt) => {\n\t\t\t\t\tconst values = await this.inputForm!.open(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttitle: prompt.message,\n\t\t\t\t\t\t\theading: \"PROVIDER LOGIN\",\n\t\t\t\t\t\t\tsubmitLabel: \"[ Submit ]\",\n\t\t\t\t\t\t\tfields: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tname: \"value\",\n\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\trequired: false,\n\t\t\t\t\t\t\t\t\tinitialValue: \"\",\n\t\t\t\t\t\t\t\t\tplaceholder: \"placeholder\" in prompt ? prompt.placeholder : undefined,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcontroller.signal,\n\t\t\t\t\t);\n\t\t\t\t\tif (!values || controller.signal.aborted) throw new Error(\"Login cancelled\");\n\t\t\t\t\treturn values.value ?? \"\";\n\t\t\t\t},\n\t\t\t\tnotify: () => {},\n\t\t\t});\n\t\t\tif (controller.signal.aborted) return { provider, cancelled: true };\n\t\t\tif (credential.type !== \"api_key\")\n\t\t\t\tthrow new Error(`Provider returned an unexpected ${credential.type} credential`);\n\t\t\t// The key came from the host's own input form; it is confirmed by type\n\t\t\t// and never sent back down the stdout pipe.\n\t\t\treturn { provider, cancelled: false, type: \"api_key\", ...this.catalog(session) };\n\t\t} catch (error) {\n\t\t\tif (error instanceof CredentialSynchronizationError) throw error;\n\t\t\tif (controller.signal.aborted || (error instanceof Error && error.message === \"Login cancelled\"))\n\t\t\t\treturn { provider, cancelled: true };\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.finish(loginId, controller);\n\t\t}\n\t}\n\n\tasync loginOAuth(session: AgentSession, provider: string, loginId = provider): Promise<RpcOAuthLoginProviderResult> {\n\t\tif (!session.modelRuntime.getProvider(provider)?.auth.oauth)\n\t\t\tthrow new Error(`Unknown OAuth provider: ${provider}`);\n\t\tif (!this.oauthTransport) throw new Error(\"OAuth login requires an interactive host\");\n\t\tconst controller = this.begin(provider, loginId);\n\t\ttry {\n\t\t\tconst callbacks = createRpcOAuthCallbacks(provider, loginId, controller.signal, this.oauthTransport);\n\t\t\ttry {\n\t\t\t\tawait session.modelRuntime.login(provider, \"oauth\", createAuthInteraction(callbacks), {\n\t\t\t\t\tgetDeviceId: () => session.settingsManager.getOrCreateDeviceId(),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tif (isOAuthLoginCancelled(error, controller.signal)) return { provider, cancelled: true };\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (controller.signal.aborted) return { provider, cancelled: true };\n\t\t\tsession.refreshCurrentModelFromRegistry();\n\t\t\treturn { provider, cancelled: false, ...this.catalog(session) };\n\t\t} finally {\n\t\t\tthis.finish(loginId, controller);\n\t\t}\n\t}\n\n\tasync save(\n\t\tsession: AgentSession,\n\t\tprovider: string,\n\t\tcredential: Credential,\n\t\toptions: SaveCredentialOptions = {},\n\t): Promise<RpcModelCatalog> {\n\t\tawait session.modelRuntime.saveCredential(provider, credential, options);\n\t\tsession.refreshCurrentModelFromRegistry();\n\t\treturn this.catalog(session);\n\t}\n\tcancel(provider: string, loginId?: string): void {\n\t\tif (loginId !== undefined) {\n\t\t\tconst active = this.controllers.get(loginId);\n\t\t\tif (active?.provider === provider) active.controller.abort();\n\t\t\treturn;\n\t\t}\n\t\tfor (const active of this.controllers.values()) if (active.provider === provider) active.controller.abort();\n\t}\n\tprivate begin(provider: string, loginId: string): AbortController {\n\t\tif ([...this.controllers.values()].some((active) => active.provider === provider))\n\t\t\tthrow new Error(`Login already in progress: ${provider}`);\n\t\tconst controller = new AbortController();\n\t\tthis.controllers.set(loginId, { provider, controller });\n\t\treturn controller;\n\t}\n\tprivate finish(loginId: string, controller: AbortController): void {\n\t\tif (this.controllers.get(loginId)?.controller === controller) this.controllers.delete(loginId);\n\t}\n\tprivate catalog(session: AgentSession): RpcModelCatalog {\n\t\treturn {\n\t\t\tmodels: [...session.modelRuntime.getAvailableSnapshot()],\n\t\t\tscopedModels: [...session.scopedModels],\n\t\t\tcustomAuthProviders: [],\n\t\t\toauthProviders: session.modelRuntime.getOAuthProviderMetadata(),\n\t\t};\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"rpc-provider-auth.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-provider-auth.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Credential } from \"@bastani/pi-ai\";\nimport type { AgentSession } from \"../../core/agent-session.js\";\nimport type { HostInputFormRequest } from \"../../core/extensions/ui-types.js\";\nimport { CredentialSynchronizationError, type SaveCredentialOptions } from \"../../core/model-runtime.js\";\nimport { createAuthInteraction, isOAuthLoginCancelled } from \"../../core/oauth-login.ts\";\nimport { createRpcOAuthCallbacks, type OAuthInteractionTransport } from \"./rpc-oauth-interaction.ts\";\nimport type { RpcLoginProviderResult, RpcModelCatalog, RpcOAuthLoginProviderResult } from \"./rpc-types.ts\";\n\nexport interface ProviderLoginInput {\n\topen(request: HostInputFormRequest, signal?: AbortSignal): Promise<Record<string, string> | undefined>;\n}\ninterface ActiveLogin {\n\tprovider: string;\n\tcontroller: AbortController;\n}\n\nexport class RpcProviderAuth {\n\tprivate readonly controllers = new Map<string, ActiveLogin>();\n\tprivate readonly inputForm: ProviderLoginInput | undefined;\n\tprivate readonly oauthTransport: OAuthInteractionTransport | undefined;\n\tconstructor(inputForm?: ProviderLoginInput, oauthTransport?: OAuthInteractionTransport) {\n\t\tthis.inputForm = inputForm;\n\t\tthis.oauthTransport = oauthTransport;\n\t}\n\n\tasync login(session: AgentSession, provider: string, loginId = provider): Promise<RpcLoginProviderResult> {\n\t\tif (!session.modelRuntime.getProvider(provider)?.auth.apiKey?.login)\n\t\t\tthrow new Error(`Provider does not support API-key login: ${provider}`);\n\t\tif (!this.inputForm) throw new Error(\"Provider login requires an interactive input host\");\n\t\tconst controller = this.begin(provider, loginId);\n\t\ttry {\n\t\t\tconst credential = await session.modelRuntime.login(provider, \"api_key\", {\n\t\t\t\tsignal: controller.signal,\n\t\t\t\tprompt: async (prompt) => {\n\t\t\t\t\tconst values = await this.inputForm!.open(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttitle: prompt.message,\n\t\t\t\t\t\t\theading: \"PROVIDER LOGIN\",\n\t\t\t\t\t\t\tsubmitLabel: \"[ Submit ]\",\n\t\t\t\t\t\t\tfields: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tname: \"value\",\n\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\trequired: false,\n\t\t\t\t\t\t\t\t\tinitialValue: \"\",\n\t\t\t\t\t\t\t\t\tplaceholder: \"placeholder\" in prompt ? prompt.placeholder : undefined,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcontroller.signal,\n\t\t\t\t\t);\n\t\t\t\t\tif (!values || controller.signal.aborted) throw new Error(\"Login cancelled\");\n\t\t\t\t\treturn values.value ?? \"\";\n\t\t\t\t},\n\t\t\t\tnotify: () => {},\n\t\t\t});\n\t\t\tif (controller.signal.aborted) return { provider, cancelled: true };\n\t\t\tif (credential.type !== \"api_key\")\n\t\t\t\tthrow new Error(`Provider returned an unexpected ${credential.type} credential`);\n\t\t\t// The key came from the host's own input form; it is confirmed by type\n\t\t\t// and never sent back down the stdout pipe.\n\t\t\treturn { provider, cancelled: false, type: \"api_key\", ...this.catalog(session) };\n\t\t} catch (error) {\n\t\t\tif (error instanceof CredentialSynchronizationError) throw error;\n\t\t\tif (controller.signal.aborted || (error instanceof Error && error.message === \"Login cancelled\"))\n\t\t\t\treturn { provider, cancelled: true };\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.finish(loginId, controller);\n\t\t}\n\t}\n\n\tasync loginOAuth(session: AgentSession, provider: string, loginId = provider): Promise<RpcOAuthLoginProviderResult> {\n\t\tif (!session.modelRuntime.getProvider(provider)?.auth.oauth)\n\t\t\tthrow new Error(`Unknown OAuth provider: ${provider}`);\n\t\tif (!this.oauthTransport) throw new Error(\"OAuth login requires an interactive host\");\n\t\tconst controller = this.begin(provider, loginId);\n\t\ttry {\n\t\t\tconst callbacks = createRpcOAuthCallbacks(provider, loginId, controller.signal, this.oauthTransport);\n\t\t\ttry {\n\t\t\t\tawait session.modelRuntime.login(provider, \"oauth\", createAuthInteraction(callbacks), {\n\t\t\t\t\tgetDeviceId: () => session.settingsManager.getOrCreateDeviceId(),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tif (isOAuthLoginCancelled(error, controller.signal)) return { provider, cancelled: true };\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (controller.signal.aborted) return { provider, cancelled: true };\n\t\t\tsession.refreshCurrentModelFromRegistry();\n\t\t\treturn { provider, cancelled: false, ...this.catalog(session) };\n\t\t} finally {\n\t\t\tthis.finish(loginId, controller);\n\t\t}\n\t}\n\n\tasync save(\n\t\tsession: AgentSession,\n\t\tprovider: string,\n\t\tcredential: Credential,\n\t\toptions: SaveCredentialOptions = {},\n\t): Promise<RpcModelCatalog> {\n\t\tawait session.modelRuntime.saveCredential(provider, credential, options);\n\t\tsession.refreshCurrentModelFromRegistry();\n\t\treturn this.catalog(session);\n\t}\n\tcancel(provider: string, loginId?: string): void {\n\t\tif (loginId !== undefined) {\n\t\t\tconst active = this.controllers.get(loginId);\n\t\t\tif (active?.provider === provider) active.controller.abort();\n\t\t\treturn;\n\t\t}\n\t\tfor (const active of this.controllers.values()) if (active.provider === provider) active.controller.abort();\n\t}\n\tprivate begin(provider: string, loginId: string): AbortController {\n\t\tif ([...this.controllers.values()].some((active) => active.provider === provider))\n\t\t\tthrow new Error(`Login already in progress: ${provider}`);\n\t\tconst controller = new AbortController();\n\t\tthis.controllers.set(loginId, { provider, controller });\n\t\treturn controller;\n\t}\n\tprivate finish(loginId: string, controller: AbortController): void {\n\t\tif (this.controllers.get(loginId)?.controller === controller) this.controllers.delete(loginId);\n\t}\n\tprivate catalog(session: AgentSession): RpcModelCatalog {\n\t\treturn {\n\t\t\tmodels: [...session.modelRuntime.getAvailableSnapshot()],\n\t\t\tscopedModels: [...session.scopedModels],\n\t\t\tcustomAuthProviders: [],\n\t\t\toauthProviders: session.modelRuntime.getOAuthProviderMetadata(),\n\t\t};\n\t}\n}\n"]}
|
|
@@ -260,10 +260,13 @@ Fired before a started session runtime is torn down. Use this to clean up resour
|
|
|
260
260
|
pi.on("session_shutdown", async (event, ctx) => {
|
|
261
261
|
// event.reason - "quit" | "reload" | "new" | "resume" | "fork"
|
|
262
262
|
// event.targetSessionFile - destination session for session replacement flows
|
|
263
|
+
// event.fromSignal - true when a "quit" came from a host SIGTERM/SIGHUP, not an explicit quit
|
|
263
264
|
// Cleanup, save state, etc.
|
|
264
265
|
});
|
|
265
266
|
```
|
|
266
267
|
|
|
268
|
+
`fromSignal` is set only on `reason: "quit"`. Ctrl+D and `/quit` leave it unset. Use it to tell a deliberate exit from the host stopping the process, for example to keep externally registered state that a restart can resume from.
|
|
269
|
+
|
|
267
270
|
### Agent Events
|
|
268
271
|
|
|
269
272
|
#### before_agent_start
|
package/docs/herdr.md
CHANGED
|
@@ -24,6 +24,15 @@ Opening `/tasks`, `/agents`, or `/workflow connect` does not count as an approva
|
|
|
24
24
|
|
|
25
25
|
A failed workflow can remain marked blocked in Atomic after its execution ends, while the pane returns to Idle. Check the workflow details for its result; the pane indicator is not a success or failure verdict. Sending a message acknowledges existing workflow attention for the indicator, but does not resume the workflow or approve a budget increase.
|
|
26
26
|
|
|
27
|
+
## Restore after a Herdr restart
|
|
28
|
+
|
|
29
|
+
With Herdr 0.9.2 or newer, Atomic also reports the command that reopens the current session, so Herdr can restart Atomic in the same pane with the same conversation after a Herdr server restart. Atomic does not restore anything itself. To turn this off in Herdr, set `[session] resume_agents_on_restore = false` in Herdr's config.
|
|
30
|
+
|
|
31
|
+
- The command is `atomic --session <id>`, with `--session-dir` added when you use a custom session directory. A session ID that `--session` would read as a file path, such as one ending in `.jsonl`, is reopened by its session file instead, still with any custom `--session-dir`. A new session is reopened only once it has been saved, so a session with no messages yet may not be found when Herdr tries to restore it.
|
|
32
|
+
- Sessions that are not saved (`--no-session`) are reported without a resume command.
|
|
33
|
+
- Quitting Atomic yourself, with Ctrl+D or `/quit`, clears the resume command, so the pane is not reopened. When Herdr or the system stops Atomic with `SIGTERM` or `SIGHUP`, the command stays registered so the session can be restored.
|
|
34
|
+
- Herdr 0.8.2 to 0.9.1 still show status but do not restore sessions.
|
|
35
|
+
|
|
27
36
|
## Disable the integration
|
|
28
37
|
|
|
29
38
|
Add this to `~/.atomic/agent/settings.json` or trusted project `.atomic/settings.json`, then reload or restart Atomic:
|
|
@@ -36,7 +45,7 @@ Add this to `~/.atomic/agent/settings.json` or trusted project `.atomic/settings
|
|
|
36
45
|
}
|
|
37
46
|
```
|
|
38
47
|
|
|
39
|
-
Reporting is enabled by default. Project settings follow the normal [settings precedence](/settings).
|
|
48
|
+
Reporting is enabled by default, and disabling it also stops resume reporting. Project settings follow the normal [settings precedence](/settings).
|
|
40
49
|
|
|
41
50
|
## Troubleshooting
|
|
42
51
|
|
|
@@ -53,4 +62,4 @@ Reloading or compacting a session should not remove Atomic from the pane. If sta
|
|
|
53
62
|
|
|
54
63
|
## Privacy
|
|
55
64
|
|
|
56
|
-
Atomic sends status, generic attention messages,
|
|
65
|
+
Atomic sends status, generic attention messages, the parent session's ID and local session path, and the resume command to the local Herdr server. The resume command contains only `atomic --session` with the session ID (or, for an ID that reads as a path, the session file) and, for a custom session directory, the `--session-dir` path. Atomic does not send prompt text, tool arguments, transcripts, or workflow output.
|
package/docs/models.md
CHANGED
|
@@ -25,7 +25,7 @@ For choosing which model to use rather than how to declare one, see [Model selec
|
|
|
25
25
|
|
|
26
26
|
Classifier models answer typed questions about JSON state instead of chatting. They do not appear in `/model`. Enable [codemode](/tools#codemode), list them with `models.getAvailableOfType("classifier")`, and call `models.classify(model, { state, questions })`. See [Codemode](/codemode#classify) for question and answer shapes.
|
|
27
27
|
|
|
28
|
-
OpenAI's GPT-6 Luna Decisions classifier is `openai-decisions/gpt-6-luna`. It uses the [Decisions API](https://developers.openai.com/api/docs/guides/decisions)
|
|
28
|
+
OpenAI's GPT-6 Luna Decisions classifier is `openai-decisions/gpt-6-luna`. It uses the [Decisions API](https://developers.openai.com/api/docs/guides/decisions), which needs an OpenAI API key. It has no `/login` entry of its own and reuses the first key it finds, in this order: a key saved for `openai-api`, a key saved for `openai`, then `OPENAI_API_KEY`. ChatGPT sign-in on `openai` does not work with it and is skipped, so with only a ChatGPT sign-in the classifier stays unavailable until you save an API key with `/login openai-api` or set `OPENAI_API_KEY`. `openai/gpt-6-luna` always means the chat model.
|
|
29
29
|
|
|
30
30
|
GPT-6 Luna accepts up to 128 image blocks through `images`, alongside the JSON state. Other classifiers reject images unless their catalog input and API support them. Refused answers produce an error result. The endpoint rejects inputs above 922K tokens; very large inputs, currently above roughly 600K tokens, can hit its gateway time limit. These 504 responses are not retried, so reduce the input before trying again.
|
|
31
31
|
|
package/docs/providers.md
CHANGED
|
@@ -73,6 +73,8 @@ Apps using `@bastani/pi-ai` directly can pass `{ agentName: "my-app" }` as the f
|
|
|
73
73
|
|
|
74
74
|
For example, sign in with ChatGPT under `openai` and select `openai/gpt-6-sol` for subscription chat, while a workflow stage pinned to `openai-api/gpt-6-sol` bills the API key.
|
|
75
75
|
|
|
76
|
+
The GPT-6 Luna Decisions classifier (`openai-decisions`) has no login of its own. It uses the key saved for `openai-api`, then a key saved for `openai`, then `OPENAI_API_KEY`, and ignores a ChatGPT sign-in. See [Classifier models](/models#use-classifier-models).
|
|
77
|
+
|
|
76
78
|
### OpenAI Codex
|
|
77
79
|
|
|
78
80
|
- Requires ChatGPT Plus or Pro subscription
|
package/docs/sdk.md
CHANGED
|
@@ -475,7 +475,7 @@ Shared loaders, event buses, settings, and `SessionManager` instances do not sha
|
|
|
475
475
|
|
|
476
476
|
#### Session replacement and deferred cleanup
|
|
477
477
|
|
|
478
|
-
`await runtime.dispose()` refuses new replacements and waits for pending factories, startup, and cleanup. No successor is published after closure. Host callbacks must settle independently of disposal.
|
|
478
|
+
`await runtime.dispose()` refuses new replacements and waits for pending factories, startup, and cleanup. No successor is published after closure. Host callbacks must settle independently of disposal. Call `runtime.dispose({ fromSignal: true })` when the host is shutting down because of `SIGTERM` or `SIGHUP`, so `session_shutdown` handlers receive `fromSignal: true` and can tell it from an explicit quit.
|
|
479
479
|
|
|
480
480
|
An extension command may await `ctx.newSession()`, `ctx.fork()`, `ctx.switchSession()`, or `session.reload()`. Its old generation remains owned until the command continuation finishes, and final disposal waits for that cleanup. Do not await disposal inside the continuation it must drain. Concurrent replacements are supported, and deferred cleanup failures remain visible.
|
|
481
481
|
|
package/docs/settings.md
CHANGED
|
@@ -19,7 +19,7 @@ This page is the exhaustive settings reference: every field, its default, and it
|
|
|
19
19
|
|
|
20
20
|
On interactive startup, Atomic asks before trusting a project folder that contains trust-gated project inputs and has no saved decision for the folder or a parent folder in `~/.atomic/agent/trust.json`. Trusting a project allows Atomic to load project-local `.atomic/settings.json` and `.atomic` resources, legacy `.pi/settings.json` and `.pi` resources, project-local context files, install missing project packages, and execute project extensions.
|
|
21
21
|
|
|
22
|
-
Project resources and borrowed project-local code stay blocked until authorized. The trust dialog does not require a model request. Trusted global and explicitly authorized CLI extensions can report the wait.
|
|
22
|
+
The startup prompt appears on its own, before the interface paints, and the interface appears once you choose. If you decline, the transcript warns that project resources are ignored; if you trust the project, it does not. Project resources and borrowed project-local code stay blocked until authorized. The trust dialog does not require a model request. Trusted global and explicitly authorized CLI extensions can report the wait.
|
|
23
23
|
|
|
24
24
|
Non-interactive modes (`-p`, `--mode json`, and `--mode rpc`) do not show a trust prompt. Without an applicable saved trust decision, they use `defaultProjectTrust` from global settings: `ask` (default) and `never` ignore trust-gated project inputs, while `always` trusts them. Pass `--approve`/`-a` or `--no-approve`/`-na` to override project trust for one run.
|
|
25
25
|
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/atomic",
|
|
3
|
-
"version": "0.9.28-alpha.
|
|
3
|
+
"version": "0.9.28-alpha.5",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bastani/atomic",
|
|
9
|
-
"version": "0.9.28-alpha.
|
|
9
|
+
"version": "0.9.28-alpha.5",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@bastani/atomic-natives": "0.9.28-alpha.
|
|
13
|
-
"@bastani/pi-ai": "0.9.28-alpha.
|
|
12
|
+
"@bastani/atomic-natives": "0.9.28-alpha.5",
|
|
13
|
+
"@bastani/pi-ai": "0.9.28-alpha.5",
|
|
14
14
|
"@dbos-inc/dbos-sdk": "4.25.14",
|
|
15
15
|
"@earendil-works/pi-agent-core": "1.1.0",
|
|
16
16
|
"@earendil-works/pi-client": "1.1.0",
|
|
@@ -432,18 +432,18 @@
|
|
|
432
432
|
}
|
|
433
433
|
},
|
|
434
434
|
"node_modules/@bastani/atomic-natives": {
|
|
435
|
-
"version": "0.9.28-alpha.
|
|
436
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.28-alpha.
|
|
435
|
+
"version": "0.9.28-alpha.5",
|
|
436
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.28-alpha.5.tgz",
|
|
437
437
|
"license": "MIT",
|
|
438
438
|
"optionalDependencies": {
|
|
439
|
-
"@bastani/atomic-natives-darwin-arm64": "0.9.28-alpha.
|
|
440
|
-
"@bastani/atomic-natives-darwin-x64": "0.9.28-alpha.
|
|
441
|
-
"@bastani/atomic-natives-linux-arm64-gnu": "0.9.28-alpha.
|
|
442
|
-
"@bastani/atomic-natives-linux-arm64-musl": "0.9.28-alpha.
|
|
443
|
-
"@bastani/atomic-natives-linux-x64-gnu": "0.9.28-alpha.
|
|
444
|
-
"@bastani/atomic-natives-linux-x64-musl": "0.9.28-alpha.
|
|
445
|
-
"@bastani/atomic-natives-win32-arm64-msvc": "0.9.28-alpha.
|
|
446
|
-
"@bastani/atomic-natives-win32-x64-msvc": "0.9.28-alpha.
|
|
439
|
+
"@bastani/atomic-natives-darwin-arm64": "0.9.28-alpha.5",
|
|
440
|
+
"@bastani/atomic-natives-darwin-x64": "0.9.28-alpha.5",
|
|
441
|
+
"@bastani/atomic-natives-linux-arm64-gnu": "0.9.28-alpha.5",
|
|
442
|
+
"@bastani/atomic-natives-linux-arm64-musl": "0.9.28-alpha.5",
|
|
443
|
+
"@bastani/atomic-natives-linux-x64-gnu": "0.9.28-alpha.5",
|
|
444
|
+
"@bastani/atomic-natives-linux-x64-musl": "0.9.28-alpha.5",
|
|
445
|
+
"@bastani/atomic-natives-win32-arm64-msvc": "0.9.28-alpha.5",
|
|
446
|
+
"@bastani/atomic-natives-win32-x64-msvc": "0.9.28-alpha.5"
|
|
447
447
|
},
|
|
448
448
|
"engines": {
|
|
449
449
|
"bun": ">=1.4.2",
|
|
@@ -451,8 +451,8 @@
|
|
|
451
451
|
}
|
|
452
452
|
},
|
|
453
453
|
"node_modules/@bastani/atomic-natives-darwin-arm64": {
|
|
454
|
-
"version": "0.9.28-alpha.
|
|
455
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.28-alpha.
|
|
454
|
+
"version": "0.9.28-alpha.5",
|
|
455
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.28-alpha.5.tgz",
|
|
456
456
|
"license": "MIT",
|
|
457
457
|
"os": [
|
|
458
458
|
"darwin"
|
|
@@ -463,8 +463,8 @@
|
|
|
463
463
|
"optional": true
|
|
464
464
|
},
|
|
465
465
|
"node_modules/@bastani/atomic-natives-darwin-x64": {
|
|
466
|
-
"version": "0.9.28-alpha.
|
|
467
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.28-alpha.
|
|
466
|
+
"version": "0.9.28-alpha.5",
|
|
467
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.28-alpha.5.tgz",
|
|
468
468
|
"license": "MIT",
|
|
469
469
|
"os": [
|
|
470
470
|
"darwin"
|
|
@@ -475,8 +475,8 @@
|
|
|
475
475
|
"optional": true
|
|
476
476
|
},
|
|
477
477
|
"node_modules/@bastani/atomic-natives-linux-arm64-gnu": {
|
|
478
|
-
"version": "0.9.28-alpha.
|
|
479
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.28-alpha.
|
|
478
|
+
"version": "0.9.28-alpha.5",
|
|
479
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.28-alpha.5.tgz",
|
|
480
480
|
"license": "MIT",
|
|
481
481
|
"os": [
|
|
482
482
|
"linux"
|
|
@@ -490,8 +490,8 @@
|
|
|
490
490
|
"optional": true
|
|
491
491
|
},
|
|
492
492
|
"node_modules/@bastani/atomic-natives-linux-arm64-musl": {
|
|
493
|
-
"version": "0.9.28-alpha.
|
|
494
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-musl/-/atomic-natives-linux-arm64-musl-0.9.28-alpha.
|
|
493
|
+
"version": "0.9.28-alpha.5",
|
|
494
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-musl/-/atomic-natives-linux-arm64-musl-0.9.28-alpha.5.tgz",
|
|
495
495
|
"license": "MIT",
|
|
496
496
|
"os": [
|
|
497
497
|
"linux"
|
|
@@ -505,8 +505,8 @@
|
|
|
505
505
|
"optional": true
|
|
506
506
|
},
|
|
507
507
|
"node_modules/@bastani/atomic-natives-linux-x64-gnu": {
|
|
508
|
-
"version": "0.9.28-alpha.
|
|
509
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.28-alpha.
|
|
508
|
+
"version": "0.9.28-alpha.5",
|
|
509
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.28-alpha.5.tgz",
|
|
510
510
|
"license": "MIT",
|
|
511
511
|
"os": [
|
|
512
512
|
"linux"
|
|
@@ -520,8 +520,8 @@
|
|
|
520
520
|
"optional": true
|
|
521
521
|
},
|
|
522
522
|
"node_modules/@bastani/atomic-natives-linux-x64-musl": {
|
|
523
|
-
"version": "0.9.28-alpha.
|
|
524
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-musl/-/atomic-natives-linux-x64-musl-0.9.28-alpha.
|
|
523
|
+
"version": "0.9.28-alpha.5",
|
|
524
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-musl/-/atomic-natives-linux-x64-musl-0.9.28-alpha.5.tgz",
|
|
525
525
|
"license": "MIT",
|
|
526
526
|
"os": [
|
|
527
527
|
"linux"
|
|
@@ -535,8 +535,8 @@
|
|
|
535
535
|
"optional": true
|
|
536
536
|
},
|
|
537
537
|
"node_modules/@bastani/atomic-natives-win32-arm64-msvc": {
|
|
538
|
-
"version": "0.9.28-alpha.
|
|
539
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.28-alpha.
|
|
538
|
+
"version": "0.9.28-alpha.5",
|
|
539
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.28-alpha.5.tgz",
|
|
540
540
|
"license": "MIT",
|
|
541
541
|
"os": [
|
|
542
542
|
"win32"
|
|
@@ -547,8 +547,8 @@
|
|
|
547
547
|
"optional": true
|
|
548
548
|
},
|
|
549
549
|
"node_modules/@bastani/atomic-natives-win32-x64-msvc": {
|
|
550
|
-
"version": "0.9.28-alpha.
|
|
551
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.28-alpha.
|
|
550
|
+
"version": "0.9.28-alpha.5",
|
|
551
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.28-alpha.5.tgz",
|
|
552
552
|
"license": "MIT",
|
|
553
553
|
"os": [
|
|
554
554
|
"win32"
|
|
@@ -559,8 +559,8 @@
|
|
|
559
559
|
"optional": true
|
|
560
560
|
},
|
|
561
561
|
"node_modules/@bastani/pi-ai": {
|
|
562
|
-
"version": "0.9.28-alpha.
|
|
563
|
-
"resolved": "https://registry.npmjs.org/@bastani/pi-ai/-/pi-ai-0.9.28-alpha.
|
|
562
|
+
"version": "0.9.28-alpha.5",
|
|
563
|
+
"resolved": "https://registry.npmjs.org/@bastani/pi-ai/-/pi-ai-0.9.28-alpha.5.tgz",
|
|
564
564
|
"license": "MIT",
|
|
565
565
|
"dependencies": {
|
|
566
566
|
"@anthropic-ai/sdk": "0.129.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/atomic",
|
|
3
|
-
"version": "0.9.28-alpha.
|
|
3
|
+
"version": "0.9.28-alpha.5",
|
|
4
4
|
"description": "Atomic coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"atomicConfig": {
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
"prepublishOnly": "bun run clean && bun run build && bun run shrinkwrap"
|
|
81
81
|
},
|
|
82
82
|
"dependencies": {
|
|
83
|
-
"@bastani/atomic-natives": "0.9.28-alpha.
|
|
84
|
-
"@bastani/pi-ai": "0.9.28-alpha.
|
|
83
|
+
"@bastani/atomic-natives": "0.9.28-alpha.5",
|
|
84
|
+
"@bastani/pi-ai": "0.9.28-alpha.5",
|
|
85
85
|
"@dbos-inc/dbos-sdk": "4.25.14",
|
|
86
86
|
"@earendil-works/pi-agent-core": "1.1.0",
|
|
87
87
|
"@earendil-works/pi-client": "1.1.0",
|