@bastani/atomic 0.9.41 → 0.9.42-alpha.1
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 +49 -0
- package/dist/builtin/intercom/CHANGELOG.md +13 -0
- package/dist/builtin/intercom/README.md +7 -3
- package/dist/builtin/intercom/broker/broker-status.ts +48 -0
- package/dist/builtin/intercom/broker/broker.ts +90 -9
- package/dist/builtin/intercom/broker/client.ts +112 -12
- package/dist/builtin/intercom/broker/control.ts +225 -0
- package/dist/builtin/intercom/broker/multinode-router.ts +32 -39
- package/dist/builtin/intercom/broker/paths.ts +4 -0
- package/dist/builtin/intercom/broker/pending-send-registry.ts +27 -5
- package/dist/builtin/intercom/broker/shared-storage-setting.ts +60 -0
- package/dist/builtin/intercom/broker/spawn.ts +13 -4
- package/dist/builtin/intercom/broker/sql-lease-store.ts +23 -0
- package/dist/builtin/intercom/broker/watchdog.ts +105 -0
- package/dist/builtin/intercom/index.bundle.mjs +200 -22
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/types.ts +34 -2
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/extension/index.bundle.mjs +1 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +12 -0
- package/dist/builtin/workflows/README.md +10 -0
- package/dist/builtin/workflows/builtin/{chunk-txbc93t6.js → chunk-3s95f7ry.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-n2gkzkty.js → chunk-edhf30ef.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-8x61e0s7.js → chunk-frqxd4d1.js} +18 -9
- 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 +6 -1
- package/dist/builtin/workflows/src/authoring.d.ts +3 -1
- package/dist/builtin/workflows/src/durable/journal/internal.d.ts +13 -0
- package/dist/builtin/workflows/src/durable/journal/resolution.d.ts +2 -0
- package/dist/builtin/workflows/src/durable/journal/sql-run-journal.d.ts +1 -0
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +88554 -82820
- package/dist/builtin/workflows/src/extension/local-worker-entry.mjs +72635 -0
- package/dist/builtin/workflows/src/index.js +53824 -5907
- package/dist/builtin/workflows/src/local-worker-entry.mjs +72635 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +7 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +2 -0
- package/dist/builtin/workflows/src/workers/public-options.d.ts +31 -0
- package/dist/bun/app-host-modules.d.ts +9 -0
- package/dist/bun/app-host-modules.d.ts.map +1 -0
- package/dist/bun/app-host-modules.js +10 -0
- package/dist/bun/app-host-modules.js.map +1 -0
- package/dist/bun/cli.d.ts +3 -1
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +15 -1
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/internal-intercom-broker.d.ts +17 -0
- package/dist/bun/internal-intercom-broker.d.ts.map +1 -1
- package/dist/bun/internal-intercom-broker.js +29 -0
- package/dist/bun/internal-intercom-broker.js.map +1 -1
- package/dist/bun/internal-workflow-worker.d.ts +4 -0
- package/dist/bun/internal-workflow-worker.d.ts.map +1 -0
- package/dist/bun/internal-workflow-worker.js +37 -0
- package/dist/bun/internal-workflow-worker.js.map +1 -0
- package/dist/bun/split-loader.js +10 -2
- package/dist/bun/split-loader.js.map +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +3 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/intercom-command.d.ts +15 -0
- package/dist/cli/intercom-command.d.ts.map +1 -0
- package/dist/cli/intercom-command.js +87 -0
- package/dist/cli/intercom-command.js.map +1 -0
- package/dist/cli/storage-command.d.ts +39 -0
- package/dist/cli/storage-command.d.ts.map +1 -0
- package/dist/cli/storage-command.js +367 -0
- package/dist/cli/storage-command.js.map +1 -0
- package/dist/core/agent-session-events.d.ts.map +1 -1
- package/dist/core/agent-session-events.js +5 -1
- package/dist/core/agent-session-events.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +1 -0
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-tasks.d.ts.map +1 -1
- package/dist/core/agent-session-tasks.js +1 -0
- package/dist/core/agent-session-tasks.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +1 -0
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +2 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/builtin-install-layout.d.ts +6 -0
- package/dist/core/builtin-install-layout.d.ts.map +1 -1
- package/dist/core/builtin-install-layout.js +9 -0
- package/dist/core/builtin-install-layout.js.map +1 -1
- package/dist/core/child-session-options.d.ts.map +1 -1
- package/dist/core/child-session-options.js +3 -0
- package/dist/core/child-session-options.js.map +1 -1
- package/dist/core/exec.js +2 -2
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/template.css +9 -0
- package/dist/core/export-html/template.js +165 -45
- package/dist/core/extensions/loader-host-modules.d.ts +6 -0
- package/dist/core/extensions/loader-host-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-host-modules.js +12 -1
- package/dist/core/extensions/loader-host-modules.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts +6 -0
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +18 -0
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/message-types.d.ts +4 -0
- package/dist/core/extensions/message-types.d.ts.map +1 -1
- package/dist/core/extensions/message-types.js.map +1 -1
- package/dist/core/fast-model-routing-transport.d.ts.map +1 -1
- package/dist/core/fast-model-routing-transport.js +5 -1
- package/dist/core/fast-model-routing-transport.js.map +1 -1
- package/dist/core/intercom-broker-control.d.ts +67 -0
- package/dist/core/intercom-broker-control.d.ts.map +1 -0
- package/dist/core/intercom-broker-control.js +17 -0
- package/dist/core/intercom-broker-control.js.map +1 -0
- package/dist/core/model-runtime-streaming.d.ts.map +1 -1
- package/dist/core/model-runtime-streaming.js +38 -1
- package/dist/core/model-runtime-streaming.js.map +1 -1
- package/dist/core/package-manager-git.d.ts +2 -2
- package/dist/core/package-manager-git.d.ts.map +1 -1
- package/dist/core/package-manager-git.js.map +1 -1
- package/dist/core/package-manager-manifest.d.ts.map +1 -1
- package/dist/core/package-manager-manifest.js +9 -1
- package/dist/core/package-manager-manifest.js.map +1 -1
- package/dist/core/package-manager-npm.d.ts +2 -2
- package/dist/core/package-manager-npm.d.ts.map +1 -1
- package/dist/core/package-manager-npm.js.map +1 -1
- package/dist/core/package-manager-paths.d.ts +7 -7
- package/dist/core/package-manager-paths.d.ts.map +1 -1
- package/dist/core/package-manager-paths.js.map +1 -1
- package/dist/core/package-manager-storage-adapters.d.ts +7 -0
- package/dist/core/package-manager-storage-adapters.d.ts.map +1 -0
- package/dist/core/package-manager-storage-adapters.js +76 -0
- package/dist/core/package-manager-storage-adapters.js.map +1 -0
- package/dist/core/package-manager-types.d.ts +4 -0
- package/dist/core/package-manager-types.d.ts.map +1 -1
- package/dist/core/package-manager-types.js.map +1 -1
- package/dist/core/provider-rate-limits.d.ts +23 -0
- package/dist/core/provider-rate-limits.d.ts.map +1 -0
- package/dist/core/provider-rate-limits.js +113 -0
- package/dist/core/provider-rate-limits.js.map +1 -0
- package/dist/core/provider-request-admission.d.ts +7 -0
- package/dist/core/provider-request-admission.d.ts.map +1 -0
- package/dist/core/provider-request-admission.js +91 -0
- package/dist/core/provider-request-admission.js.map +1 -0
- package/dist/core/resource-admission-scope.d.ts +4 -0
- package/dist/core/resource-admission-scope.d.ts.map +1 -0
- package/dist/core/resource-admission-scope.js +9 -0
- package/dist/core/resource-admission-scope.js.map +1 -0
- package/dist/core/sdk-types.d.ts +16 -0
- package/dist/core/sdk-types.d.ts.map +1 -1
- package/dist/core/sdk-types.js.map +1 -1
- package/dist/core/sdk.d.ts +2 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +18 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-lifecycle-work.d.ts +1 -0
- package/dist/core/session-lifecycle-work.d.ts.map +1 -1
- package/dist/core/session-lifecycle-work.js +1 -0
- package/dist/core/session-lifecycle-work.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.d.ts +3 -0
- package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js +6 -0
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-schema.d.ts +22 -0
- package/dist/core/settings-schema.d.ts.map +1 -1
- package/dist/core/settings-schema.js +18 -1
- package/dist/core/settings-schema.js.map +1 -1
- package/dist/core/storage/index.d.ts +1 -0
- package/dist/core/storage/index.d.ts.map +1 -1
- package/dist/core/storage/index.js +1 -0
- package/dist/core/storage/index.js.map +1 -1
- package/dist/core/storage/node-sqlite.d.ts +2 -1
- package/dist/core/storage/node-sqlite.d.ts.map +1 -1
- package/dist/core/storage/node-sqlite.js +5 -4
- package/dist/core/storage/node-sqlite.js.map +1 -1
- package/dist/core/storage/provider.d.ts +6 -0
- package/dist/core/storage/provider.d.ts.map +1 -1
- package/dist/core/storage/provider.js +27 -7
- package/dist/core/storage/provider.js.map +1 -1
- package/dist/core/storage/sqlite-facade.d.ts +49 -0
- package/dist/core/storage/sqlite-facade.d.ts.map +1 -0
- package/dist/core/storage/sqlite-facade.js +180 -0
- package/dist/core/storage/sqlite-facade.js.map +1 -0
- package/dist/core/storage/storage-status.d.ts +81 -0
- package/dist/core/storage/storage-status.d.ts.map +1 -0
- package/dist/core/storage/storage-status.js +409 -0
- package/dist/core/storage/storage-status.js.map +1 -0
- package/dist/core/tasks/supervisor.d.ts +2 -1
- package/dist/core/tasks/supervisor.d.ts.map +1 -1
- package/dist/core/tasks/supervisor.js +105 -4
- package/dist/core/tasks/supervisor.js.map +1 -1
- package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
- package/dist/core/tools/bash-pty-native.js +1 -1
- package/dist/core/tools/bash-pty-native.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +28 -2
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +3 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +7 -3
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.d.ts +9 -1
- package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.js +16 -8
- package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +5 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +69 -2
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.js +2 -2
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js +80 -22
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts +3 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +6 -2
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +6 -2
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/interactive-engine/engine-health.d.ts +8 -4
- package/dist/modes/interactive-engine/engine-health.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-health.js +41 -6
- package/dist/modes/interactive-engine/engine-health.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.js +19 -17
- package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
- package/dist/modes/interactive-engine/remote-queue-pause.js +1 -1
- package/dist/modes/interactive-engine/remote-queue-pause.js.map +1 -1
- package/dist/modes/rpc/rpc-input-scheduler.d.ts +1 -0
- package/dist/modes/rpc/rpc-input-scheduler.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-input-scheduler.js +4 -1
- package/dist/modes/rpc/rpc-input-scheduler.js.map +1 -1
- package/dist/modes/rpc/rpc-input.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-input.js +29 -7
- package/dist/modes/rpc/rpc-input.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +14 -0
- package/dist/utils/shell.js.map +1 -1
- package/docs/custom-provider/oauth.md +8 -1
- package/docs/extensions/api-reference.md +2 -0
- package/docs/intercom/operations.md +17 -8
- package/docs/intercom/reference.md +1 -1
- package/docs/keybindings.md +1 -1
- package/docs/packages/authoring.md +15 -0
- package/docs/packages.md +3 -2
- package/docs/providers.md +2 -0
- package/docs/reference/cli.md +17 -0
- package/docs/sdk.md +37 -0
- package/docs/settings.md +33 -2
- package/docs/storage.md +191 -219
- package/docs/usage.md +1 -1
- package/docs/workflows/api-reference.md +50 -0
- package/docs/workflows/operations.md +44 -1
- package/docs/workflows.md +25 -0
- package/examples/extensions/gondolin/package-lock.json +14 -24
- package/examples/extensions/gondolin/package.json +1 -1
- package/npm-shrinkwrap.json +35 -35
- package/package.json +4 -4
- package/schemas/settings.schema.json +87 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `atomic intercom restart` replaces the agent directory's Intercom broker, so it reads the current storage
|
|
3
|
+
* selection without closing every session; `atomic intercom status` shows what the running broker uses.
|
|
4
|
+
*/
|
|
5
|
+
import type { IntercomBrokerControl } from "../core/intercom-broker-control.js";
|
|
6
|
+
export interface IntercomCommandOptions {
|
|
7
|
+
readonly agentDir: string;
|
|
8
|
+
readonly log?: (line: string) => void;
|
|
9
|
+
readonly error?: (line: string) => void;
|
|
10
|
+
/** Defaults to the bundled Intercom package's broker control. */
|
|
11
|
+
readonly loadControl?: () => Promise<IntercomBrokerControl>;
|
|
12
|
+
}
|
|
13
|
+
/** Run `atomic intercom <args>` and return the exit code. */
|
|
14
|
+
export declare function runIntercomCommand(args: readonly string[], options: IntercomCommandOptions): Promise<number>;
|
|
15
|
+
//# sourceMappingURL=intercom-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intercom-command.d.ts","sourceRoot":"","sources":["../../src/cli/intercom-command.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAe,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAc7F,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,iEAAiE;IACjE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC5D;AAuBD,6DAA6D;AAC7D,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwDlH"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `atomic intercom restart` replaces the agent directory's Intercom broker, so it reads the current storage
|
|
3
|
+
* selection without closing every session; `atomic intercom status` shows what the running broker uses.
|
|
4
|
+
*/
|
|
5
|
+
import { APP_NAME } from "../config.js";
|
|
6
|
+
const HELP = `Usage:
|
|
7
|
+
${APP_NAME} intercom status
|
|
8
|
+
${APP_NAME} intercom restart
|
|
9
|
+
|
|
10
|
+
Commands:
|
|
11
|
+
status Show whether this machine's Intercom broker is running, how many sessions it serves,
|
|
12
|
+
whether it uses the current storage selection, and its multi-node routing state with
|
|
13
|
+
the number of other brokers live in the shared database.
|
|
14
|
+
restart Stop the broker so it picks up a changed storage selection. Connected sessions
|
|
15
|
+
reconnect and start a new broker within a few seconds; without sessions, the next
|
|
16
|
+
session that uses Intercom starts one.`;
|
|
17
|
+
function describeBroker(query, control, agentDir) {
|
|
18
|
+
if (query.state === "legacy") {
|
|
19
|
+
return [
|
|
20
|
+
`Intercom broker: running${query.pid === undefined ? "" : ` (pid ${query.pid})`}, started by an older ${APP_NAME} that does not report its status.`,
|
|
21
|
+
];
|
|
22
|
+
}
|
|
23
|
+
const { report } = query;
|
|
24
|
+
const expected = control.expectedBrokerStorage(agentDir, process.env);
|
|
25
|
+
return [
|
|
26
|
+
`Intercom broker: running (pid ${report.pid}, ${report.sessions} session${report.sessions === 1 ? "" : "s"} connected)`,
|
|
27
|
+
report.storage?.digest === expected?.digest
|
|
28
|
+
? "Storage: matches the current selection"
|
|
29
|
+
: `Storage: differs from the current selection${report.storage?.source === "env" ? " (a session started it with ATOMIC_STORAGE or --storage)" : ""}; run \`${APP_NAME} intercom restart\``,
|
|
30
|
+
`Multi-node routing: ${control.describeMultiNodeStatus(report.multiNode)}`,
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
/** Run `atomic intercom <args>` and return the exit code. */
|
|
34
|
+
export async function runIntercomCommand(args, options) {
|
|
35
|
+
const log = options.log ?? ((line) => console.log(line));
|
|
36
|
+
const error = options.error ?? ((line) => console.error(line));
|
|
37
|
+
const [command, ...rest] = args;
|
|
38
|
+
if (command === undefined || command === "help" || args.includes("--help") || args.includes("-h")) {
|
|
39
|
+
log(HELP);
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
if ((command !== "restart" && command !== "status") || rest.length > 0) {
|
|
43
|
+
error(command === "restart" || command === "status"
|
|
44
|
+
? `Usage: ${APP_NAME} intercom ${command}`
|
|
45
|
+
: `Unknown intercom command "${command}". Use "${APP_NAME} intercom --help" for usage.`);
|
|
46
|
+
return 1;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
let control;
|
|
50
|
+
if (options.loadControl)
|
|
51
|
+
control = await options.loadControl();
|
|
52
|
+
else {
|
|
53
|
+
const { loadIntercomBrokerControl } = await import("../core/intercom-broker-control.js");
|
|
54
|
+
control = await loadIntercomBrokerControl();
|
|
55
|
+
}
|
|
56
|
+
const { agentDir } = options;
|
|
57
|
+
if (command === "status") {
|
|
58
|
+
const query = await control.queryIntercomBroker(agentDir);
|
|
59
|
+
if (query.state === "stopped") {
|
|
60
|
+
log("Intercom broker: not running. The next session that uses Intercom starts one.");
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
for (const line of describeBroker(query, control, agentDir))
|
|
64
|
+
log(line);
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
const outcome = await control.restartIntercomBroker(agentDir, { onProgress: log });
|
|
68
|
+
if (outcome.status === "not-running") {
|
|
69
|
+
log("No Intercom broker is running. The next session that uses Intercom starts one with the current storage selection.");
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
if (outcome.status === "stopped") {
|
|
73
|
+
log(`Stopped the Intercom broker (pid ${outcome.previous.pid}). ${outcome.previous.sessions === 0 ? "No session was connected" : "No session reconnected in time"}, so none started a new one; the next session that uses Intercom starts one with the current storage selection.`);
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
const current = outcome.current;
|
|
77
|
+
log(`Restarted the Intercom broker: pid ${outcome.previous.pid} → ${current.state === "running" ? current.report.pid : (current.pid ?? "unknown")}.`);
|
|
78
|
+
for (const line of describeBroker(current, control, agentDir))
|
|
79
|
+
log(line);
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
catch (caught) {
|
|
83
|
+
error(`Error: ${caught instanceof Error ? caught.message : String(caught)}`);
|
|
84
|
+
return 1;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=intercom-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intercom-command.js","sourceRoot":"","sources":["../../src/cli/intercom-command.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `atomic intercom restart` replaces the agent directory's Intercom broker, so it reads the current storage\n * selection without closing every session; `atomic intercom status` shows what the running broker uses.\n */\n\nimport { APP_NAME } from \"../config.js\";\nimport type { BrokerQuery, IntercomBrokerControl } from \"../core/intercom-broker-control.js\";\n\nconst HELP = `Usage:\n ${APP_NAME} intercom status\n ${APP_NAME} intercom restart\n\nCommands:\n status Show whether this machine's Intercom broker is running, how many sessions it serves,\n whether it uses the current storage selection, and its multi-node routing state with\n the number of other brokers live in the shared database.\n restart Stop the broker so it picks up a changed storage selection. Connected sessions\n reconnect and start a new broker within a few seconds; without sessions, the next\n session that uses Intercom starts one.`;\n\nexport interface IntercomCommandOptions {\n\treadonly agentDir: string;\n\treadonly log?: (line: string) => void;\n\treadonly error?: (line: string) => void;\n\t/** Defaults to the bundled Intercom package's broker control. */\n\treadonly loadControl?: () => Promise<IntercomBrokerControl>;\n}\n\nfunction describeBroker(\n\tquery: Exclude<BrokerQuery, { state: \"stopped\" }>,\n\tcontrol: IntercomBrokerControl,\n\tagentDir: string,\n): string[] {\n\tif (query.state === \"legacy\") {\n\t\treturn [\n\t\t\t`Intercom broker: running${query.pid === undefined ? \"\" : ` (pid ${query.pid})`}, started by an older ${APP_NAME} that does not report its status.`,\n\t\t];\n\t}\n\tconst { report } = query;\n\tconst expected = control.expectedBrokerStorage(agentDir, process.env);\n\treturn [\n\t\t`Intercom broker: running (pid ${report.pid}, ${report.sessions} session${report.sessions === 1 ? \"\" : \"s\"} connected)`,\n\t\treport.storage?.digest === expected?.digest\n\t\t\t? \"Storage: matches the current selection\"\n\t\t\t: `Storage: differs from the current selection${report.storage?.source === \"env\" ? \" (a session started it with ATOMIC_STORAGE or --storage)\" : \"\"}; run \\`${APP_NAME} intercom restart\\``,\n\t\t`Multi-node routing: ${control.describeMultiNodeStatus(report.multiNode)}`,\n\t];\n}\n\n/** Run `atomic intercom <args>` and return the exit code. */\nexport async function runIntercomCommand(args: readonly string[], options: IntercomCommandOptions): Promise<number> {\n\tconst log = options.log ?? ((line: string) => console.log(line));\n\tconst error = options.error ?? ((line: string) => console.error(line));\n\tconst [command, ...rest] = args;\n\tif (command === undefined || command === \"help\" || args.includes(\"--help\") || args.includes(\"-h\")) {\n\t\tlog(HELP);\n\t\treturn 0;\n\t}\n\tif ((command !== \"restart\" && command !== \"status\") || rest.length > 0) {\n\t\terror(\n\t\t\tcommand === \"restart\" || command === \"status\"\n\t\t\t\t? `Usage: ${APP_NAME} intercom ${command}`\n\t\t\t\t: `Unknown intercom command \"${command}\". Use \"${APP_NAME} intercom --help\" for usage.`,\n\t\t);\n\t\treturn 1;\n\t}\n\ttry {\n\t\tlet control: IntercomBrokerControl;\n\t\tif (options.loadControl) control = await options.loadControl();\n\t\telse {\n\t\t\tconst { loadIntercomBrokerControl } = await import(\"../core/intercom-broker-control.js\");\n\t\t\tcontrol = await loadIntercomBrokerControl();\n\t\t}\n\t\tconst { agentDir } = options;\n\t\tif (command === \"status\") {\n\t\t\tconst query = await control.queryIntercomBroker(agentDir);\n\t\t\tif (query.state === \"stopped\") {\n\t\t\t\tlog(\"Intercom broker: not running. The next session that uses Intercom starts one.\");\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tfor (const line of describeBroker(query, control, agentDir)) log(line);\n\t\t\treturn 0;\n\t\t}\n\t\tconst outcome = await control.restartIntercomBroker(agentDir, { onProgress: log });\n\t\tif (outcome.status === \"not-running\") {\n\t\t\tlog(\n\t\t\t\t\"No Intercom broker is running. The next session that uses Intercom starts one with the current storage selection.\",\n\t\t\t);\n\t\t\treturn 0;\n\t\t}\n\t\tif (outcome.status === \"stopped\") {\n\t\t\tlog(\n\t\t\t\t`Stopped the Intercom broker (pid ${outcome.previous.pid}). ${outcome.previous.sessions === 0 ? \"No session was connected\" : \"No session reconnected in time\"}, so none started a new one; the next session that uses Intercom starts one with the current storage selection.`,\n\t\t\t);\n\t\t\treturn 0;\n\t\t}\n\t\tconst current = outcome.current;\n\t\tlog(\n\t\t\t`Restarted the Intercom broker: pid ${outcome.previous.pid} → ${current.state === \"running\" ? current.report.pid : (current.pid ?? \"unknown\")}.`,\n\t\t);\n\t\tfor (const line of describeBroker(current, control, agentDir)) log(line);\n\t\treturn 0;\n\t} catch (caught) {\n\t\terror(`Error: ${caught instanceof Error ? caught.message : String(caught)}`);\n\t\treturn 1;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `atomic storage status` shows which storage each domain (sessions, workflow runs, Intercom) selects, where the
|
|
3
|
+
* selection comes from, whether its adapter loads and its database answers, and what the running Intercom broker
|
|
4
|
+
* uses. `atomic storage join` points this machine's global `storage` setting at a shared libSQL / Turso database.
|
|
5
|
+
*/
|
|
6
|
+
import type { IntercomBrokerControl } from "../core/intercom-broker-control.js";
|
|
7
|
+
import { type StorageStatus } from "../core/storage/storage-status.js";
|
|
8
|
+
/** The first-party libSQL / Turso adapter package that `atomic storage join` selects. */
|
|
9
|
+
export declare const LIBSQL_ADAPTER_PACKAGE = "@bastani/atomic-storage-libsql";
|
|
10
|
+
/** Filename prefix for private token files created by `atomic storage join` in the agent directory. */
|
|
11
|
+
export declare const STORAGE_TOKEN_FILE = "storage-token";
|
|
12
|
+
export type StorageCommand = {
|
|
13
|
+
readonly kind: "help";
|
|
14
|
+
} | {
|
|
15
|
+
readonly kind: "status";
|
|
16
|
+
readonly json: boolean;
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: "join";
|
|
19
|
+
readonly url: string;
|
|
20
|
+
readonly tokenFile?: string;
|
|
21
|
+
readonly prefix?: string;
|
|
22
|
+
};
|
|
23
|
+
export declare class StorageCommandError extends Error {
|
|
24
|
+
}
|
|
25
|
+
/** Parse the arguments after `storage`. */
|
|
26
|
+
export declare function parseStorageCommand(args: readonly string[]): StorageCommand;
|
|
27
|
+
export interface StorageCommandOptions {
|
|
28
|
+
readonly cwd: string;
|
|
29
|
+
readonly agentDir: string;
|
|
30
|
+
readonly log?: (line: string) => void;
|
|
31
|
+
readonly error?: (line: string) => void;
|
|
32
|
+
/** Defaults to the bundled Intercom package's broker control. */
|
|
33
|
+
readonly loadControl?: () => Promise<IntercomBrokerControl>;
|
|
34
|
+
}
|
|
35
|
+
/** The status as the lines `atomic storage status` prints. */
|
|
36
|
+
export declare function formatStorageStatus(status: StorageStatus): string[];
|
|
37
|
+
/** Run `atomic storage <args>` and return the exit code. */
|
|
38
|
+
export declare function runStorageCommand(args: readonly string[], options: StorageCommandOptions): Promise<number>;
|
|
39
|
+
//# sourceMappingURL=storage-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-command.d.ts","sourceRoot":"","sources":["../../src/cli/storage-command.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAOhF,OAAO,EAKN,KAAK,aAAa,EAClB,MAAM,mCAAmC,CAAC;AAE3C,yFAAyF;AACzF,eAAO,MAAM,sBAAsB,mCAAmC,CAAC;AACvE,uGAAuG;AACvG,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAyBlD,MAAM,MAAM,cAAc,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1G,qBAAa,mBAAoB,SAAQ,KAAK;CAAG;AAYjD,2CAA2C;AAC3C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,cAAc,CA+D3E;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,iEAAiE;IACjE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC5D;AA4BD,8DAA8D;AAC9D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,EAAE,CAuDnE;AAsKD,4DAA4D;AAC5D,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBhH"}
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `atomic storage status` shows which storage each domain (sessions, workflow runs, Intercom) selects, where the
|
|
3
|
+
* selection comes from, whether its adapter loads and its database answers, and what the running Intercom broker
|
|
4
|
+
* uses. `atomic storage join` points this machine's global `storage` setting at a shared libSQL / Turso database.
|
|
5
|
+
*/
|
|
6
|
+
import { randomUUID } from "node:crypto";
|
|
7
|
+
import { chmodSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
9
|
+
import { APP_NAME } from "../config.js";
|
|
10
|
+
import { resolvePackageStorageAdapter } from "../core/package-manager-storage-adapters.js";
|
|
11
|
+
import { SettingsManager } from "../core/settings-manager.js";
|
|
12
|
+
import { validateStoragePrefix } from "../core/storage/prefix.js";
|
|
13
|
+
import { loadStorageAdapter } from "../core/storage/provider.js";
|
|
14
|
+
import { selectStorage } from "../core/storage/selection.js";
|
|
15
|
+
import { collectStorageStatus, describeStorageError, describeStorageSelection, } from "../core/storage/storage-status.js";
|
|
16
|
+
/** The first-party libSQL / Turso adapter package that `atomic storage join` selects. */
|
|
17
|
+
export const LIBSQL_ADAPTER_PACKAGE = "@bastani/atomic-storage-libsql";
|
|
18
|
+
/** Filename prefix for private token files created by `atomic storage join` in the agent directory. */
|
|
19
|
+
export const STORAGE_TOKEN_FILE = "storage-token";
|
|
20
|
+
const HELP = `Usage:
|
|
21
|
+
${APP_NAME} storage status [--json]
|
|
22
|
+
${APP_NAME} storage join <url> [--token-file <path>] [--prefix <prefix>]
|
|
23
|
+
|
|
24
|
+
Commands:
|
|
25
|
+
status Show, for sessions, workflow runs, and Intercom, the selected storage and where the
|
|
26
|
+
selection comes from (environment variable, project or global settings, or default),
|
|
27
|
+
whether its adapter loads, whether its database answers a SELECT 1, and what the running
|
|
28
|
+
Intercom broker uses. Exits 1 when a selection is invalid, an adapter cannot load, or a
|
|
29
|
+
database does not answer. Nothing is created or changed.
|
|
30
|
+
join Use a shared libSQL / Turso database on this machine: check the token and the connection
|
|
31
|
+
with ${LIBSQL_ADAPTER_PACKAGE}, store the token in the agent directory (mode 600), and
|
|
32
|
+
write only the global \`storage\` setting. Reports environment variables and settings that
|
|
33
|
+
override it. Creates no tables; Atomic creates them on first use.
|
|
34
|
+
|
|
35
|
+
Options:
|
|
36
|
+
--json Print the status as JSON
|
|
37
|
+
--token-file <path> File holding the database token, for example from \`turso db tokens create\`;
|
|
38
|
+
surrounding whitespace is removed. Required except for file: URLs
|
|
39
|
+
--prefix <prefix> Table prefix, to share one database between projects or teams`;
|
|
40
|
+
const HELP_HINT = `Use "${APP_NAME} storage --help" for usage.`;
|
|
41
|
+
export class StorageCommandError extends Error {
|
|
42
|
+
}
|
|
43
|
+
/** Whether a database URL holds the token itself: userinfo, or the `authToken` query parameter libSQL URLs accept. */
|
|
44
|
+
function carriesCredential(url) {
|
|
45
|
+
try {
|
|
46
|
+
const { username, password, searchParams } = new URL(url);
|
|
47
|
+
return username !== "" || password !== "" || searchParams.has("authToken");
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Parse the arguments after `storage`. */
|
|
54
|
+
export function parseStorageCommand(args) {
|
|
55
|
+
const [command, ...rest] = args;
|
|
56
|
+
if (command === undefined || command === "help" || args.includes("--help") || args.includes("-h")) {
|
|
57
|
+
return { kind: "help" };
|
|
58
|
+
}
|
|
59
|
+
const positional = [];
|
|
60
|
+
const values = new Map();
|
|
61
|
+
let json = false;
|
|
62
|
+
for (let index = 0; index < rest.length; index++) {
|
|
63
|
+
const arg = rest[index];
|
|
64
|
+
if (command === "status" && arg === "--json") {
|
|
65
|
+
json = true;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (command === "join" && (arg === "--token-file" || arg === "--prefix")) {
|
|
69
|
+
const value = rest[++index];
|
|
70
|
+
if (value === undefined)
|
|
71
|
+
throw new StorageCommandError(`${arg} needs a value.`);
|
|
72
|
+
values.set(arg, value);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (arg.startsWith("-"))
|
|
76
|
+
throw new StorageCommandError(`Unknown option ${arg} for "storage ${command}".\n${HELP_HINT}`);
|
|
77
|
+
positional.push(arg);
|
|
78
|
+
}
|
|
79
|
+
if (command === "status") {
|
|
80
|
+
if (positional.length > 0)
|
|
81
|
+
throw new StorageCommandError(`Usage: ${APP_NAME} storage status [--json]`);
|
|
82
|
+
return { kind: "status", json };
|
|
83
|
+
}
|
|
84
|
+
if (command === "join") {
|
|
85
|
+
const [url, ...extra] = positional;
|
|
86
|
+
if (url === undefined || extra.length > 0) {
|
|
87
|
+
throw new StorageCommandError(`Usage: ${APP_NAME} storage join <url> [--token-file <path>] [--prefix <prefix>]`);
|
|
88
|
+
}
|
|
89
|
+
if (!/^(libsql|https?|wss?):\/\/[^/]/.test(url) && !url.startsWith("file:")) {
|
|
90
|
+
throw new StorageCommandError(`Unsupported database URL "${url}". Use a libsql://, https://, wss://, or file: URL.`);
|
|
91
|
+
}
|
|
92
|
+
if (url.startsWith("file:") && !url.startsWith("file:/")) {
|
|
93
|
+
throw new StorageCommandError("Use an absolute file: URL (for example file:///path/to/shared.sqlite), so every working directory uses the same database.");
|
|
94
|
+
}
|
|
95
|
+
if (carriesCredential(url)) {
|
|
96
|
+
throw new StorageCommandError("The database URL carries a credential (user name, password, or authToken). Pass the token with --token-file instead, so it is kept in a private file and not in settings.");
|
|
97
|
+
}
|
|
98
|
+
const tokenFile = values.get("--token-file");
|
|
99
|
+
if (tokenFile === undefined && !url.startsWith("file:")) {
|
|
100
|
+
throw new StorageCommandError(`--token-file is required for ${url.split(":")[0]}: URLs.`);
|
|
101
|
+
}
|
|
102
|
+
const prefix = values.get("--prefix");
|
|
103
|
+
return {
|
|
104
|
+
kind: "join",
|
|
105
|
+
url,
|
|
106
|
+
...(tokenFile === undefined ? {} : { tokenFile }),
|
|
107
|
+
...(prefix === undefined ? {} : { prefix }),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
throw new StorageCommandError(`Unknown storage command "${command}".\n${HELP_HINT}`);
|
|
111
|
+
}
|
|
112
|
+
const errorText = describeStorageError;
|
|
113
|
+
async function loadControl(options) {
|
|
114
|
+
try {
|
|
115
|
+
if (options.loadControl)
|
|
116
|
+
return await options.loadControl();
|
|
117
|
+
const { loadIntercomBrokerControl } = await import("../core/intercom-broker-control.js");
|
|
118
|
+
return await loadIntercomBrokerControl();
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function failed(domain) {
|
|
125
|
+
return (domain.error !== undefined ||
|
|
126
|
+
domain.probe?.adapter?.loaded === false ||
|
|
127
|
+
domain.probe?.connection.status === "failed");
|
|
128
|
+
}
|
|
129
|
+
const DOMAIN_LABELS = {
|
|
130
|
+
sessions: "Sessions",
|
|
131
|
+
journal: "Workflow runs",
|
|
132
|
+
intercom: "Intercom",
|
|
133
|
+
};
|
|
134
|
+
/** The status as the lines `atomic storage status` prints. */
|
|
135
|
+
export function formatStorageStatus(status) {
|
|
136
|
+
const lines = [
|
|
137
|
+
`Agent directory: ${status.agentDir}`,
|
|
138
|
+
`Project: ${status.cwd}${status.projectTrusted ? "" : " (not trusted)"}`,
|
|
139
|
+
];
|
|
140
|
+
for (const domain of status.domains) {
|
|
141
|
+
lines.push("", `${DOMAIN_LABELS[domain.domain]}: ${domain.selection}`);
|
|
142
|
+
lines.push(` source: ${domain.source}`);
|
|
143
|
+
if (domain.overridden.length > 0)
|
|
144
|
+
lines.push(` overrides: ${domain.overridden.join(", ")}`);
|
|
145
|
+
if (domain.error !== undefined)
|
|
146
|
+
lines.push(` error: ${domain.error}`);
|
|
147
|
+
const probe = domain.probe;
|
|
148
|
+
if (probe?.sameAs !== undefined) {
|
|
149
|
+
lines.push(` connection: same as ${DOMAIN_LABELS[probe.sameAs].toLowerCase()}`);
|
|
150
|
+
}
|
|
151
|
+
else if (probe !== undefined) {
|
|
152
|
+
if (probe.adapter !== undefined) {
|
|
153
|
+
lines.push(` adapter: ${probe.adapter.loaded ? "loaded" : "failed to load"}${probe.adapter.detail === undefined ? "" : ` (${probe.adapter.detail})`}`);
|
|
154
|
+
}
|
|
155
|
+
lines.push(` connection: ${probe.connection.status} (${probe.connection.detail})`);
|
|
156
|
+
}
|
|
157
|
+
if (domain.multiNode !== undefined)
|
|
158
|
+
lines.push(` multi-node: ${domain.multiNode}`);
|
|
159
|
+
if (domain.liveBrokers !== undefined) {
|
|
160
|
+
lines.push(` brokers: ${domain.liveBrokers.length} live in the database${domain.liveBrokers.length === 0 ? "" : ` (${[...new Set(domain.liveBrokers)].join(", ")})`}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const broker = status.broker;
|
|
164
|
+
if (broker !== undefined) {
|
|
165
|
+
lines.push("");
|
|
166
|
+
if (broker.state === "stopped") {
|
|
167
|
+
lines.push("Intercom broker: not running (the next session that uses Intercom starts one with the selection above)");
|
|
168
|
+
}
|
|
169
|
+
else if (broker.state === "unknown") {
|
|
170
|
+
lines.push(`Intercom broker: unknown (${broker.error ?? "no answer"})`);
|
|
171
|
+
}
|
|
172
|
+
else if (broker.state === "legacy") {
|
|
173
|
+
lines.push(`Intercom broker: running${broker.pid === undefined ? "" : ` (pid ${broker.pid})`}, started by an older Atomic that does not report its storage; run \`${APP_NAME} intercom restart\``);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
lines.push(`Intercom broker: running (pid ${broker.pid}, ${broker.sessions} session${broker.sessions === 1 ? "" : "s"} connected)`);
|
|
177
|
+
lines.push(broker.matchesCurrent
|
|
178
|
+
? " storage: matches the selection above"
|
|
179
|
+
: ` storage: differs from the selection above${broker.source === "env" ? " (a session started it with ATOMIC_STORAGE or --storage)" : ""}; run \`${APP_NAME} intercom restart\` to use the current one`);
|
|
180
|
+
if (broker.multiNodeLine !== undefined)
|
|
181
|
+
lines.push(` multi-node: ${broker.multiNodeLine}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (status.notes.length > 0)
|
|
185
|
+
lines.push("", "Notes:", ...status.notes.map((note) => ` - ${note}`));
|
|
186
|
+
return lines;
|
|
187
|
+
}
|
|
188
|
+
async function status(json, options, log) {
|
|
189
|
+
const control = await loadControl(options);
|
|
190
|
+
const collected = await collectStorageStatus({
|
|
191
|
+
cwd: options.cwd,
|
|
192
|
+
agentDir: options.agentDir,
|
|
193
|
+
probe: true,
|
|
194
|
+
...(control instanceof Error ? {} : { control }),
|
|
195
|
+
});
|
|
196
|
+
const result = control instanceof Error ? { ...collected, broker: { state: "unknown", error: errorText(control) } } : collected;
|
|
197
|
+
if (json)
|
|
198
|
+
log(JSON.stringify(result, null, 2));
|
|
199
|
+
else
|
|
200
|
+
for (const line of formatStorageStatus(result))
|
|
201
|
+
log(line);
|
|
202
|
+
return result.domains.some(failed) ? 1 : 0;
|
|
203
|
+
}
|
|
204
|
+
/** Write `token` to `path` with mode 0600 without leaving a partly written file. */
|
|
205
|
+
function writePrivateFile(path, token) {
|
|
206
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
207
|
+
const temporary = `${path}.${process.pid}.tmp`;
|
|
208
|
+
try {
|
|
209
|
+
writeFileSync(temporary, token, { mode: 0o600 });
|
|
210
|
+
chmodSync(temporary, 0o600);
|
|
211
|
+
renameSync(temporary, path);
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
rmSync(temporary, { force: true });
|
|
215
|
+
throw error;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async function checkConnection(url, token, agentDir) {
|
|
219
|
+
const context = { agentDir, domain: "sessions" };
|
|
220
|
+
const adapter = await loadStorageAdapter(LIBSQL_ADAPTER_PACKAGE, context);
|
|
221
|
+
if (adapter.openDatabase === undefined)
|
|
222
|
+
throw new Error(`${LIBSQL_ADAPTER_PACKAGE} has no openDatabase hook`);
|
|
223
|
+
const database = await adapter.openDatabase({ url, ...(token === undefined ? {} : { authToken: token }) }, context);
|
|
224
|
+
try {
|
|
225
|
+
await database.get("SELECT 1 AS ok");
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
await database.close();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
async function joinStorage(command, options, log) {
|
|
232
|
+
const { agentDir, cwd } = options;
|
|
233
|
+
if (command.prefix !== undefined) {
|
|
234
|
+
try {
|
|
235
|
+
validateStoragePrefix(command.prefix);
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
throw new StorageCommandError(`Invalid --prefix "${command.prefix}": ${errorText(error)}.`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
let token;
|
|
242
|
+
let tokenSource;
|
|
243
|
+
if (command.tokenFile !== undefined) {
|
|
244
|
+
tokenSource = resolve(cwd, command.tokenFile);
|
|
245
|
+
try {
|
|
246
|
+
token = readFileSync(tokenSource, "utf8").trim();
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
throw new StorageCommandError(`Cannot read the token file ${tokenSource}: ${errorText(error)}`);
|
|
250
|
+
}
|
|
251
|
+
if (token.length === 0)
|
|
252
|
+
throw new StorageCommandError(`The token file ${tokenSource} is empty.`);
|
|
253
|
+
}
|
|
254
|
+
const manager = SettingsManager.create(cwd, agentDir, { projectTrusted: false });
|
|
255
|
+
const settingsErrors = manager.drainErrors().filter(({ scope }) => scope === "global");
|
|
256
|
+
if (settingsErrors.length > 0) {
|
|
257
|
+
throw new StorageCommandError(`Cannot update the global settings: ${settingsErrors.map(({ error }) => error.message).join("; ")}. Fix ${join(agentDir, "settings.json")} first.`);
|
|
258
|
+
}
|
|
259
|
+
// An unreadable settings file looks like one with no packages installed, so report it before the adapter lookup.
|
|
260
|
+
if ((await resolvePackageStorageAdapter(LIBSQL_ADAPTER_PACKAGE, agentDir)) === undefined) {
|
|
261
|
+
throw new StorageCommandError(`The libSQL storage adapter is not installed for ${agentDir}. Install it, then run this command again:\n ${APP_NAME} install npm:${LIBSQL_ADAPTER_PACKAGE}`);
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
await checkConnection(command.url, token, agentDir);
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
throw new StorageCommandError(`Could not connect to ${command.url}: ${errorText(error)}. Nothing was changed.`);
|
|
268
|
+
}
|
|
269
|
+
log(`Connected to ${command.url}.`);
|
|
270
|
+
// Never replace a credential referenced by the previous selection or an already-running session.
|
|
271
|
+
// Publishing settings is the commit point; an unsuccessful join removes only its new token file.
|
|
272
|
+
const tokenPath = join(agentDir, `${STORAGE_TOKEN_FILE}.${randomUUID()}`);
|
|
273
|
+
if (token !== undefined)
|
|
274
|
+
writePrivateFile(tokenPath, token);
|
|
275
|
+
const previous = manager.getGlobalSettings().storage;
|
|
276
|
+
const storage = {
|
|
277
|
+
adapter: LIBSQL_ADAPTER_PACKAGE,
|
|
278
|
+
options: { url: command.url },
|
|
279
|
+
...(token === undefined
|
|
280
|
+
? {}
|
|
281
|
+
: { secrets: { authToken: { file: relative(dirname(agentDir), tokenPath).split(sep).join("/") } } }),
|
|
282
|
+
...(command.prefix === undefined ? {} : { prefix: command.prefix }),
|
|
283
|
+
};
|
|
284
|
+
try {
|
|
285
|
+
manager.setStorage(storage);
|
|
286
|
+
await manager.flush();
|
|
287
|
+
const writeErrors = manager.drainErrors();
|
|
288
|
+
if (writeErrors.length > 0) {
|
|
289
|
+
throw new StorageCommandError(`Could not write the global settings: ${writeErrors.map(({ error }) => error.message).join("; ")}`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
if (token !== undefined)
|
|
294
|
+
rmSync(tokenPath, { force: true });
|
|
295
|
+
throw error;
|
|
296
|
+
}
|
|
297
|
+
if (token !== undefined)
|
|
298
|
+
log(`Stored the token in ${tokenPath} (mode 600).`);
|
|
299
|
+
log(`Set \`storage\` in ${join(agentDir, "settings.json")}; other settings are unchanged.`);
|
|
300
|
+
if (previous !== undefined && JSON.stringify(previous) !== JSON.stringify(storage)) {
|
|
301
|
+
const described = (() => {
|
|
302
|
+
try {
|
|
303
|
+
return describeStorageSelection(selectStorage(previous, "settings", "storage", ""));
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
return "an invalid selection";
|
|
307
|
+
}
|
|
308
|
+
})();
|
|
309
|
+
log(`It replaces the previous selection: ${described}.`);
|
|
310
|
+
}
|
|
311
|
+
const control = await loadControl(options);
|
|
312
|
+
let collected;
|
|
313
|
+
try {
|
|
314
|
+
collected = await collectStorageStatus({
|
|
315
|
+
cwd,
|
|
316
|
+
agentDir,
|
|
317
|
+
probe: false,
|
|
318
|
+
...(control instanceof Error ? {} : { control }),
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
catch (error) {
|
|
322
|
+
// Settings and the token are already committed; optional diagnostics cannot undo that success.
|
|
323
|
+
log(`Storage was saved, but could not report overrides: ${errorText(error)}.`);
|
|
324
|
+
log(`Run \`${APP_NAME} storage status\` after fixing the reported settings error.`);
|
|
325
|
+
return 0;
|
|
326
|
+
}
|
|
327
|
+
const overridden = collected.domains.filter((domain) => domain.source !== "global settings: storage" && domain.source !== "default");
|
|
328
|
+
if (overridden.length > 0) {
|
|
329
|
+
log("", "These take precedence over the new selection here:");
|
|
330
|
+
for (const domain of overridden)
|
|
331
|
+
log(` - ${DOMAIN_LABELS[domain.domain]}: ${domain.source}`);
|
|
332
|
+
}
|
|
333
|
+
for (const note of collected.notes)
|
|
334
|
+
log(`Note: ${note}`);
|
|
335
|
+
const broker = collected.broker;
|
|
336
|
+
if (broker?.state === "running" && !broker.matchesCurrent) {
|
|
337
|
+
log(`The running Intercom broker (pid ${broker.pid}) still uses its previous selection. Run \`${APP_NAME} intercom restart\` so it uses the new one.`);
|
|
338
|
+
}
|
|
339
|
+
else if (broker?.state === "legacy") {
|
|
340
|
+
log(`An Intercom broker from an older ${APP_NAME} is running. Run \`${APP_NAME} intercom restart\` to replace it.`);
|
|
341
|
+
}
|
|
342
|
+
log(`Run \`${APP_NAME} storage status\` to check each domain.`);
|
|
343
|
+
return 0;
|
|
344
|
+
}
|
|
345
|
+
/** Run `atomic storage <args>` and return the exit code. */
|
|
346
|
+
export async function runStorageCommand(args, options) {
|
|
347
|
+
const log = options.log ?? ((line) => console.log(line));
|
|
348
|
+
const error = options.error ?? ((line) => console.error(line));
|
|
349
|
+
try {
|
|
350
|
+
const command = parseStorageCommand(args);
|
|
351
|
+
if (command.kind === "help") {
|
|
352
|
+
log(HELP);
|
|
353
|
+
return 0;
|
|
354
|
+
}
|
|
355
|
+
if (command.kind === "status")
|
|
356
|
+
return await status(command.json, options, log);
|
|
357
|
+
return await joinStorage(command, options, (...lines) => {
|
|
358
|
+
for (const line of lines)
|
|
359
|
+
log(line);
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
catch (caught) {
|
|
363
|
+
error(caught instanceof StorageCommandError ? caught.message : `Error: ${errorText(caught)}`);
|
|
364
|
+
return 1;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
//# sourceMappingURL=storage-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-command.js","sourceRoot":"","sources":["../../src/cli/storage-command.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAChG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,4BAA4B,EAAE,MAAM,6CAA6C,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACN,oBAAoB,EAEpB,oBAAoB,EACpB,wBAAwB,GAExB,MAAM,mCAAmC,CAAC;AAE3C,yFAAyF;AACzF,MAAM,CAAC,MAAM,sBAAsB,GAAG,gCAAgC,CAAC;AACvE,uGAAuG;AACvG,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAElD,MAAM,IAAI,GAAG;IACT,QAAQ;IACR,QAAQ;;;;;;;;;kBASM,sBAAsB;;;;;;;;sFAQ8C,CAAC;AAEvF,MAAM,SAAS,GAAG,QAAQ,QAAQ,6BAA6B,CAAC;AAOhE,MAAM,OAAO,mBAAoB,SAAQ,KAAK;CAAG;AAEjD,sHAAsH;AACtH,SAAS,iBAAiB,CAAC,GAAW;IACrC,IAAI,CAAC;QACJ,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1D,OAAO,QAAQ,KAAK,EAAE,IAAI,QAAQ,KAAK,EAAE,IAAI,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC5E,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,mBAAmB,CAAC,IAAuB;IAC1D,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAChC,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACzB,CAAC;IACD,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAClD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAE,CAAC;QACzB,IAAI,OAAO,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC9C,IAAI,GAAG,IAAI,CAAC;YACZ,SAAS;QACV,CAAC;QACD,IAAI,OAAO,KAAK,MAAM,IAAI,CAAC,GAAG,KAAK,cAAc,IAAI,GAAG,KAAK,UAAU,CAAC,EAAE,CAAC;YAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;YAC5B,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM,IAAI,mBAAmB,CAAC,GAAG,GAAG,iBAAiB,CAAC,CAAC;YAChF,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACvB,SAAS;QACV,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YACtB,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,GAAG,iBAAiB,OAAO,OAAO,SAAS,EAAE,CAAC,CAAC;QAChG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IACD,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC1B,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,IAAI,mBAAmB,CAAC,UAAU,QAAQ,0BAA0B,CAAC,CAAC;QACvG,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACjC,CAAC;IACD,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,UAAU,CAAC;QACnC,IAAI,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,mBAAmB,CAC5B,UAAU,QAAQ,+DAA+D,CACjF,CAAC;QACH,CAAC;QACD,IAAI,CAAC,gCAAgC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7E,MAAM,IAAI,mBAAmB,CAC5B,6BAA6B,GAAG,qDAAqD,CACrF,CAAC;QACH,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1D,MAAM,IAAI,mBAAmB,CAC5B,2HAA2H,CAC3H,CAAC;QACH,CAAC;QACD,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,mBAAmB,CAC5B,2KAA2K,CAC3K,CAAC;QACH,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC7C,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,mBAAmB,CAAC,gCAAgC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC3F,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACtC,OAAO;YACN,IAAI,EAAE,MAAM;YACZ,GAAG;YACH,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;YACjD,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;SAC3C,CAAC;IACH,CAAC;IACD,MAAM,IAAI,mBAAmB,CAAC,4BAA4B,OAAO,OAAO,SAAS,EAAE,CAAC,CAAC;AACtF,CAAC;AAWD,MAAM,SAAS,GAAG,oBAAoB,CAAC;AAEvC,KAAK,UAAU,WAAW,CAAC,OAA8B;IACxD,IAAI,CAAC;QACJ,IAAI,OAAO,CAAC,WAAW;YAAE,OAAO,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;QAC5D,MAAM,EAAE,yBAAyB,EAAE,GAAG,MAAM,MAAM,CAAC,oCAAoC,CAAC,CAAC;QACzF,OAAO,MAAM,yBAAyB,EAAE,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,CAAC;AACF,CAAC;AAED,SAAS,MAAM,CAAC,MAAoB;IACnC,OAAO,CACN,MAAM,CAAC,KAAK,KAAK,SAAS;QAC1B,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,KAAK;QACvC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,KAAK,QAAQ,CAC5C,CAAC;AACH,CAAC;AAED,MAAM,aAAa,GAA2C;IAC7D,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,eAAe;IACxB,QAAQ,EAAE,UAAU;CACpB,CAAC;AAEF,8DAA8D;AAC9D,MAAM,UAAU,mBAAmB,CAAC,MAAqB;IACxD,MAAM,KAAK,GAAG;QACb,oBAAoB,MAAM,CAAC,QAAQ,EAAE;QACrC,YAAY,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,EAAE;KACxE,CAAC;IACF,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QACvE,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9C,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/F,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,KAAK,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,0BAA0B,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACnF,CAAC;aAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBACjC,KAAK,CAAC,IAAI,CACT,kBAAkB,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,CAC/I,CAAC;YACH,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,kBAAkB,KAAK,CAAC,UAAU,CAAC,MAAM,KAAK,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QACrF,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CACT,kBAAkB,MAAM,CAAC,WAAW,CAAC,MAAM,wBAAwB,MAAM,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAC/J,CAAC;QACH,CAAC;IACF,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CACT,wGAAwG,CACxG,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,6BAA6B,MAAM,CAAC,KAAK,IAAI,WAAW,GAAG,CAAC,CAAC;QACzE,CAAC;aAAM,IAAI,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CACT,2BAA2B,MAAM,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,GAAG,wEAAwE,QAAQ,qBAAqB,CACtL,CAAC;QACH,CAAC;aAAM,CAAC;YACP,KAAK,CAAC,IAAI,CACT,iCAAiC,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,QAAQ,WAAW,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,aAAa,CACvH,CAAC;YACF,KAAK,CAAC,IAAI,CACT,MAAM,CAAC,cAAc;gBACpB,CAAC,CAAC,4CAA4C;gBAC9C,CAAC,CAAC,kDAAkD,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,0DAA0D,CAAC,CAAC,CAAC,EAAE,WAAW,QAAQ,4CAA4C,CAC7M,CAAC;YACF,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS;gBAAE,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;QAC9F,CAAC;IACF,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IACpG,OAAO,KAAK,CAAC;AACd,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,IAAa,EAAE,OAA8B,EAAE,GAA2B;IAC/F,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC;QAC5C,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,IAAI;QACX,GAAG,CAAC,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;KAChD,CAAC,CAAC;IACH,MAAM,MAAM,GACX,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAClH,IAAI,IAAI;QAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;;QAC1C,KAAK,MAAM,IAAI,IAAI,mBAAmB,CAAC,MAAM,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/D,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,oFAAoF;AACpF,SAAS,gBAAgB,CAAC,IAAY,EAAE,KAAa;IACpD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;IAC/C,IAAI,CAAC;QACJ,aAAa,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACjD,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC5B,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACnC,MAAM,KAAK,CAAC;IACb,CAAC;AACF,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAW,EAAE,KAAyB,EAAE,QAAgB;IACtF,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAW,CAAC;IAC1D,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;IAC1E,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,sBAAsB,2BAA2B,CAAC,CAAC;IAC9G,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IACpH,IAAI,CAAC;QACJ,MAAM,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACtC,CAAC;YAAS,CAAC;QACV,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACF,CAAC;AAED,KAAK,UAAU,WAAW,CACzB,OAAkD,EAClD,OAA8B,EAC9B,GAAiC;IAEjC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAClC,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,CAAC;YACJ,qBAAqB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,mBAAmB,CAAC,qBAAqB,OAAO,CAAC,MAAM,MAAM,SAAS,CAAC,KAAc,CAAC,GAAG,CAAC,CAAC;QACtG,CAAC;IACF,CAAC;IACD,IAAI,KAAyB,CAAC;IAC9B,IAAI,WAA+B,CAAC;IACpC,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACrC,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,CAAC;YACJ,KAAK,GAAG,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,mBAAmB,CAAC,8BAA8B,WAAW,KAAK,SAAS,CAAC,KAAc,CAAC,EAAE,CAAC,CAAC;QAC1G,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,WAAW,YAAY,CAAC,CAAC;IAClG,CAAC;IACD,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IACjF,MAAM,cAAc,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC;IACvF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,mBAAmB,CAC5B,sCAAsC,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,SAAS,CAClJ,CAAC;IACH,CAAC;IACD,iHAAiH;IACjH,IAAI,CAAC,MAAM,4BAA4B,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QAC1F,MAAM,IAAI,mBAAmB,CAC5B,mDAAmD,QAAQ,iDAAiD,QAAQ,gBAAgB,sBAAsB,EAAE,CAC5J,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACJ,MAAM,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,mBAAmB,CAC5B,wBAAwB,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,KAAc,CAAC,wBAAwB,CACzF,CAAC;IACH,CAAC;IACD,GAAG,CAAC,gBAAgB,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;IAEpC,iGAAiG;IACjG,iGAAiG;IACjG,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,kBAAkB,IAAI,UAAU,EAAE,EAAE,CAAC,CAAC;IAC1E,IAAI,KAAK,KAAK,SAAS;QAAE,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAE5D,MAAM,QAAQ,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,OAAO,CAAC;IACrD,MAAM,OAAO,GAAqC;QACjD,OAAO,EAAE,sBAAsB;QAC/B,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAC7B,GAAG,CAAC,KAAK,KAAK,SAAS;YACtB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC;QACrG,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;KACnE,CAAC;IACF,IAAI,CAAC;QACJ,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC5B,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QAC1C,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,mBAAmB,CAC5B,wCAAwC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClG,CAAC;QACH,CAAC;IACF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,MAAM,KAAK,CAAC;IACb,CAAC;IACD,IAAI,KAAK,KAAK,SAAS;QAAE,GAAG,CAAC,uBAAuB,SAAS,cAAc,CAAC,CAAC;IAC7E,GAAG,CAAC,sBAAsB,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,iCAAiC,CAAC,CAAC;IAC5F,IAAI,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QACpF,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE;YACvB,IAAI,CAAC;gBACJ,OAAO,wBAAwB,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;YACrF,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,sBAAsB,CAAC;YAC/B,CAAC;QACF,CAAC,CAAC,EAAE,CAAC;QACL,GAAG,CAAC,uCAAuC,SAAS,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,SAAwB,CAAC;IAC7B,IAAI,CAAC;QACJ,SAAS,GAAG,MAAM,oBAAoB,CAAC;YACtC,GAAG;YACH,QAAQ;YACR,KAAK,EAAE,KAAK;YACZ,GAAG,CAAC,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;SAChD,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,+FAA+F;QAC/F,GAAG,CAAC,sDAAsD,SAAS,CAAC,KAAc,CAAC,GAAG,CAAC,CAAC;QACxF,GAAG,CAAC,SAAS,QAAQ,6DAA6D,CAAC,CAAC;QACpF,OAAO,CAAC,CAAC;IACV,CAAC;IACD,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAC1C,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,0BAA0B,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,CACvF,CAAC;IACF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,EAAE,EAAE,oDAAoD,CAAC,CAAC;QAC9D,KAAK,MAAM,MAAM,IAAI,UAAU;YAAE,GAAG,CAAC,OAAO,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/F,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,KAAK;QAAE,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;IAChC,IAAI,MAAM,EAAE,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAC3D,GAAG,CACF,oCAAoC,MAAM,CAAC,GAAG,8CAA8C,QAAQ,6CAA6C,CACjJ,CAAC;IACH,CAAC;SAAM,IAAI,MAAM,EAAE,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,GAAG,CACF,oCAAoC,QAAQ,sBAAsB,QAAQ,oCAAoC,CAC9G,CAAC;IACH,CAAC;IACD,GAAG,CAAC,SAAS,QAAQ,yCAAyC,CAAC,CAAC;IAChE,OAAO,CAAC,CAAC;AACV,CAAC;AAED,4DAA4D;AAC5D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAuB,EAAE,OAA8B;IAC9F,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACvE,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7B,GAAG,CAAC,IAAI,CAAC,CAAC;YACV,OAAO,CAAC,CAAC;QACV,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;QAC/E,OAAO,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,EAAE;YACvD,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QACjB,KAAK,CAAC,MAAM,YAAY,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,SAAS,CAAC,MAAe,CAAC,EAAE,CAAC,CAAC;QACvG,OAAO,CAAC,CAAC;IACV,CAAC;AACF,CAAC","sourcesContent":["/**\n * `atomic storage status` shows which storage each domain (sessions, workflow runs, Intercom) selects, where the\n * selection comes from, whether its adapter loads and its database answers, and what the running Intercom broker\n * uses. `atomic storage join` points this machine's global `storage` setting at a shared libSQL / Turso database.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { chmodSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\nimport { APP_NAME } from \"../config.js\";\nimport type { IntercomBrokerControl } from \"../core/intercom-broker-control.js\";\nimport { resolvePackageStorageAdapter } from \"../core/package-manager-storage-adapters.js\";\nimport { SettingsManager } from \"../core/settings-manager.ts\";\nimport type { Settings } from \"../core/settings-schema.ts\";\nimport { validateStoragePrefix } from \"../core/storage/prefix.js\";\nimport { loadStorageAdapter } from \"../core/storage/provider.js\";\nimport { selectStorage } from \"../core/storage/selection.js\";\nimport {\n\tcollectStorageStatus,\n\ttype DomainStatus,\n\tdescribeStorageError,\n\tdescribeStorageSelection,\n\ttype StorageStatus,\n} from \"../core/storage/storage-status.js\";\n\n/** The first-party libSQL / Turso adapter package that `atomic storage join` selects. */\nexport const LIBSQL_ADAPTER_PACKAGE = \"@bastani/atomic-storage-libsql\";\n/** Filename prefix for private token files created by `atomic storage join` in the agent directory. */\nexport const STORAGE_TOKEN_FILE = \"storage-token\";\n\nconst HELP = `Usage:\n ${APP_NAME} storage status [--json]\n ${APP_NAME} storage join <url> [--token-file <path>] [--prefix <prefix>]\n\nCommands:\n status Show, for sessions, workflow runs, and Intercom, the selected storage and where the\n selection comes from (environment variable, project or global settings, or default),\n whether its adapter loads, whether its database answers a SELECT 1, and what the running\n Intercom broker uses. Exits 1 when a selection is invalid, an adapter cannot load, or a\n database does not answer. Nothing is created or changed.\n join Use a shared libSQL / Turso database on this machine: check the token and the connection\n with ${LIBSQL_ADAPTER_PACKAGE}, store the token in the agent directory (mode 600), and\n write only the global \\`storage\\` setting. Reports environment variables and settings that\n override it. Creates no tables; Atomic creates them on first use.\n\nOptions:\n --json Print the status as JSON\n --token-file <path> File holding the database token, for example from \\`turso db tokens create\\`;\n surrounding whitespace is removed. Required except for file: URLs\n --prefix <prefix> Table prefix, to share one database between projects or teams`;\n\nconst HELP_HINT = `Use \"${APP_NAME} storage --help\" for usage.`;\n\nexport type StorageCommand =\n\t| { readonly kind: \"help\" }\n\t| { readonly kind: \"status\"; readonly json: boolean }\n\t| { readonly kind: \"join\"; readonly url: string; readonly tokenFile?: string; readonly prefix?: string };\n\nexport class StorageCommandError extends Error {}\n\n/** Whether a database URL holds the token itself: userinfo, or the `authToken` query parameter libSQL URLs accept. */\nfunction carriesCredential(url: string): boolean {\n\ttry {\n\t\tconst { username, password, searchParams } = new URL(url);\n\t\treturn username !== \"\" || password !== \"\" || searchParams.has(\"authToken\");\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Parse the arguments after `storage`. */\nexport function parseStorageCommand(args: readonly string[]): StorageCommand {\n\tconst [command, ...rest] = args;\n\tif (command === undefined || command === \"help\" || args.includes(\"--help\") || args.includes(\"-h\")) {\n\t\treturn { kind: \"help\" };\n\t}\n\tconst positional: string[] = [];\n\tconst values = new Map<string, string>();\n\tlet json = false;\n\tfor (let index = 0; index < rest.length; index++) {\n\t\tconst arg = rest[index]!;\n\t\tif (command === \"status\" && arg === \"--json\") {\n\t\t\tjson = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (command === \"join\" && (arg === \"--token-file\" || arg === \"--prefix\")) {\n\t\t\tconst value = rest[++index];\n\t\t\tif (value === undefined) throw new StorageCommandError(`${arg} needs a value.`);\n\t\t\tvalues.set(arg, value);\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg.startsWith(\"-\"))\n\t\t\tthrow new StorageCommandError(`Unknown option ${arg} for \"storage ${command}\".\\n${HELP_HINT}`);\n\t\tpositional.push(arg);\n\t}\n\tif (command === \"status\") {\n\t\tif (positional.length > 0) throw new StorageCommandError(`Usage: ${APP_NAME} storage status [--json]`);\n\t\treturn { kind: \"status\", json };\n\t}\n\tif (command === \"join\") {\n\t\tconst [url, ...extra] = positional;\n\t\tif (url === undefined || extra.length > 0) {\n\t\t\tthrow new StorageCommandError(\n\t\t\t\t`Usage: ${APP_NAME} storage join <url> [--token-file <path>] [--prefix <prefix>]`,\n\t\t\t);\n\t\t}\n\t\tif (!/^(libsql|https?|wss?):\\/\\/[^/]/.test(url) && !url.startsWith(\"file:\")) {\n\t\t\tthrow new StorageCommandError(\n\t\t\t\t`Unsupported database URL \"${url}\". Use a libsql://, https://, wss://, or file: URL.`,\n\t\t\t);\n\t\t}\n\t\tif (url.startsWith(\"file:\") && !url.startsWith(\"file:/\")) {\n\t\t\tthrow new StorageCommandError(\n\t\t\t\t\"Use an absolute file: URL (for example file:///path/to/shared.sqlite), so every working directory uses the same database.\",\n\t\t\t);\n\t\t}\n\t\tif (carriesCredential(url)) {\n\t\t\tthrow new StorageCommandError(\n\t\t\t\t\"The database URL carries a credential (user name, password, or authToken). Pass the token with --token-file instead, so it is kept in a private file and not in settings.\",\n\t\t\t);\n\t\t}\n\t\tconst tokenFile = values.get(\"--token-file\");\n\t\tif (tokenFile === undefined && !url.startsWith(\"file:\")) {\n\t\t\tthrow new StorageCommandError(`--token-file is required for ${url.split(\":\")[0]}: URLs.`);\n\t\t}\n\t\tconst prefix = values.get(\"--prefix\");\n\t\treturn {\n\t\t\tkind: \"join\",\n\t\t\turl,\n\t\t\t...(tokenFile === undefined ? {} : { tokenFile }),\n\t\t\t...(prefix === undefined ? {} : { prefix }),\n\t\t};\n\t}\n\tthrow new StorageCommandError(`Unknown storage command \"${command}\".\\n${HELP_HINT}`);\n}\n\nexport interface StorageCommandOptions {\n\treadonly cwd: string;\n\treadonly agentDir: string;\n\treadonly log?: (line: string) => void;\n\treadonly error?: (line: string) => void;\n\t/** Defaults to the bundled Intercom package's broker control. */\n\treadonly loadControl?: () => Promise<IntercomBrokerControl>;\n}\n\nconst errorText = describeStorageError;\n\nasync function loadControl(options: StorageCommandOptions): Promise<IntercomBrokerControl | Error> {\n\ttry {\n\t\tif (options.loadControl) return await options.loadControl();\n\t\tconst { loadIntercomBrokerControl } = await import(\"../core/intercom-broker-control.js\");\n\t\treturn await loadIntercomBrokerControl();\n\t} catch (error) {\n\t\treturn error instanceof Error ? error : new Error(String(error));\n\t}\n}\n\nfunction failed(domain: DomainStatus): boolean {\n\treturn (\n\t\tdomain.error !== undefined ||\n\t\tdomain.probe?.adapter?.loaded === false ||\n\t\tdomain.probe?.connection.status === \"failed\"\n\t);\n}\n\nconst DOMAIN_LABELS: Record<DomainStatus[\"domain\"], string> = {\n\tsessions: \"Sessions\",\n\tjournal: \"Workflow runs\",\n\tintercom: \"Intercom\",\n};\n\n/** The status as the lines `atomic storage status` prints. */\nexport function formatStorageStatus(status: StorageStatus): string[] {\n\tconst lines = [\n\t\t`Agent directory: ${status.agentDir}`,\n\t\t`Project: ${status.cwd}${status.projectTrusted ? \"\" : \" (not trusted)\"}`,\n\t];\n\tfor (const domain of status.domains) {\n\t\tlines.push(\"\", `${DOMAIN_LABELS[domain.domain]}: ${domain.selection}`);\n\t\tlines.push(` source: ${domain.source}`);\n\t\tif (domain.overridden.length > 0) lines.push(` overrides: ${domain.overridden.join(\", \")}`);\n\t\tif (domain.error !== undefined) lines.push(` error: ${domain.error}`);\n\t\tconst probe = domain.probe;\n\t\tif (probe?.sameAs !== undefined) {\n\t\t\tlines.push(` connection: same as ${DOMAIN_LABELS[probe.sameAs].toLowerCase()}`);\n\t\t} else if (probe !== undefined) {\n\t\t\tif (probe.adapter !== undefined) {\n\t\t\t\tlines.push(\n\t\t\t\t\t` adapter: ${probe.adapter.loaded ? \"loaded\" : \"failed to load\"}${probe.adapter.detail === undefined ? \"\" : ` (${probe.adapter.detail})`}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tlines.push(` connection: ${probe.connection.status} (${probe.connection.detail})`);\n\t\t}\n\t\tif (domain.multiNode !== undefined) lines.push(` multi-node: ${domain.multiNode}`);\n\t\tif (domain.liveBrokers !== undefined) {\n\t\t\tlines.push(\n\t\t\t\t` brokers: ${domain.liveBrokers.length} live in the database${domain.liveBrokers.length === 0 ? \"\" : ` (${[...new Set(domain.liveBrokers)].join(\", \")})`}`,\n\t\t\t);\n\t\t}\n\t}\n\tconst broker = status.broker;\n\tif (broker !== undefined) {\n\t\tlines.push(\"\");\n\t\tif (broker.state === \"stopped\") {\n\t\t\tlines.push(\n\t\t\t\t\"Intercom broker: not running (the next session that uses Intercom starts one with the selection above)\",\n\t\t\t);\n\t\t} else if (broker.state === \"unknown\") {\n\t\t\tlines.push(`Intercom broker: unknown (${broker.error ?? \"no answer\"})`);\n\t\t} else if (broker.state === \"legacy\") {\n\t\t\tlines.push(\n\t\t\t\t`Intercom broker: running${broker.pid === undefined ? \"\" : ` (pid ${broker.pid})`}, started by an older Atomic that does not report its storage; run \\`${APP_NAME} intercom restart\\``,\n\t\t\t);\n\t\t} else {\n\t\t\tlines.push(\n\t\t\t\t`Intercom broker: running (pid ${broker.pid}, ${broker.sessions} session${broker.sessions === 1 ? \"\" : \"s\"} connected)`,\n\t\t\t);\n\t\t\tlines.push(\n\t\t\t\tbroker.matchesCurrent\n\t\t\t\t\t? \" storage: matches the selection above\"\n\t\t\t\t\t: ` storage: differs from the selection above${broker.source === \"env\" ? \" (a session started it with ATOMIC_STORAGE or --storage)\" : \"\"}; run \\`${APP_NAME} intercom restart\\` to use the current one`,\n\t\t\t);\n\t\t\tif (broker.multiNodeLine !== undefined) lines.push(` multi-node: ${broker.multiNodeLine}`);\n\t\t}\n\t}\n\tif (status.notes.length > 0) lines.push(\"\", \"Notes:\", ...status.notes.map((note) => ` - ${note}`));\n\treturn lines;\n}\n\nasync function status(json: boolean, options: StorageCommandOptions, log: (line: string) => void): Promise<number> {\n\tconst control = await loadControl(options);\n\tconst collected = await collectStorageStatus({\n\t\tcwd: options.cwd,\n\t\tagentDir: options.agentDir,\n\t\tprobe: true,\n\t\t...(control instanceof Error ? {} : { control }),\n\t});\n\tconst result: StorageStatus =\n\t\tcontrol instanceof Error ? { ...collected, broker: { state: \"unknown\", error: errorText(control) } } : collected;\n\tif (json) log(JSON.stringify(result, null, 2));\n\telse for (const line of formatStorageStatus(result)) log(line);\n\treturn result.domains.some(failed) ? 1 : 0;\n}\n\n/** Write `token` to `path` with mode 0600 without leaving a partly written file. */\nfunction writePrivateFile(path: string, token: string): void {\n\tmkdirSync(dirname(path), { recursive: true });\n\tconst temporary = `${path}.${process.pid}.tmp`;\n\ttry {\n\t\twriteFileSync(temporary, token, { mode: 0o600 });\n\t\tchmodSync(temporary, 0o600);\n\t\trenameSync(temporary, path);\n\t} catch (error) {\n\t\trmSync(temporary, { force: true });\n\t\tthrow error;\n\t}\n}\n\nasync function checkConnection(url: string, token: string | undefined, agentDir: string): Promise<void> {\n\tconst context = { agentDir, domain: \"sessions\" } as const;\n\tconst adapter = await loadStorageAdapter(LIBSQL_ADAPTER_PACKAGE, context);\n\tif (adapter.openDatabase === undefined) throw new Error(`${LIBSQL_ADAPTER_PACKAGE} has no openDatabase hook`);\n\tconst database = await adapter.openDatabase({ url, ...(token === undefined ? {} : { authToken: token }) }, context);\n\ttry {\n\t\tawait database.get(\"SELECT 1 AS ok\");\n\t} finally {\n\t\tawait database.close();\n\t}\n}\n\nasync function joinStorage(\n\tcommand: Extract<StorageCommand, { kind: \"join\" }>,\n\toptions: StorageCommandOptions,\n\tlog: (...lines: string[]) => void,\n): Promise<number> {\n\tconst { agentDir, cwd } = options;\n\tif (command.prefix !== undefined) {\n\t\ttry {\n\t\t\tvalidateStoragePrefix(command.prefix);\n\t\t} catch (error) {\n\t\t\tthrow new StorageCommandError(`Invalid --prefix \"${command.prefix}\": ${errorText(error as Error)}.`);\n\t\t}\n\t}\n\tlet token: string | undefined;\n\tlet tokenSource: string | undefined;\n\tif (command.tokenFile !== undefined) {\n\t\ttokenSource = resolve(cwd, command.tokenFile);\n\t\ttry {\n\t\t\ttoken = readFileSync(tokenSource, \"utf8\").trim();\n\t\t} catch (error) {\n\t\t\tthrow new StorageCommandError(`Cannot read the token file ${tokenSource}: ${errorText(error as Error)}`);\n\t\t}\n\t\tif (token.length === 0) throw new StorageCommandError(`The token file ${tokenSource} is empty.`);\n\t}\n\tconst manager = SettingsManager.create(cwd, agentDir, { projectTrusted: false });\n\tconst settingsErrors = manager.drainErrors().filter(({ scope }) => scope === \"global\");\n\tif (settingsErrors.length > 0) {\n\t\tthrow new StorageCommandError(\n\t\t\t`Cannot update the global settings: ${settingsErrors.map(({ error }) => error.message).join(\"; \")}. Fix ${join(agentDir, \"settings.json\")} first.`,\n\t\t);\n\t}\n\t// An unreadable settings file looks like one with no packages installed, so report it before the adapter lookup.\n\tif ((await resolvePackageStorageAdapter(LIBSQL_ADAPTER_PACKAGE, agentDir)) === undefined) {\n\t\tthrow new StorageCommandError(\n\t\t\t`The libSQL storage adapter is not installed for ${agentDir}. Install it, then run this command again:\\n ${APP_NAME} install npm:${LIBSQL_ADAPTER_PACKAGE}`,\n\t\t);\n\t}\n\ttry {\n\t\tawait checkConnection(command.url, token, agentDir);\n\t} catch (error) {\n\t\tthrow new StorageCommandError(\n\t\t\t`Could not connect to ${command.url}: ${errorText(error as Error)}. Nothing was changed.`,\n\t\t);\n\t}\n\tlog(`Connected to ${command.url}.`);\n\n\t// Never replace a credential referenced by the previous selection or an already-running session.\n\t// Publishing settings is the commit point; an unsuccessful join removes only its new token file.\n\tconst tokenPath = join(agentDir, `${STORAGE_TOKEN_FILE}.${randomUUID()}`);\n\tif (token !== undefined) writePrivateFile(tokenPath, token);\n\n\tconst previous = manager.getGlobalSettings().storage;\n\tconst storage: NonNullable<Settings[\"storage\"]> = {\n\t\tadapter: LIBSQL_ADAPTER_PACKAGE,\n\t\toptions: { url: command.url },\n\t\t...(token === undefined\n\t\t\t? {}\n\t\t\t: { secrets: { authToken: { file: relative(dirname(agentDir), tokenPath).split(sep).join(\"/\") } } }),\n\t\t...(command.prefix === undefined ? {} : { prefix: command.prefix }),\n\t};\n\ttry {\n\t\tmanager.setStorage(storage);\n\t\tawait manager.flush();\n\t\tconst writeErrors = manager.drainErrors();\n\t\tif (writeErrors.length > 0) {\n\t\t\tthrow new StorageCommandError(\n\t\t\t\t`Could not write the global settings: ${writeErrors.map(({ error }) => error.message).join(\"; \")}`,\n\t\t\t);\n\t\t}\n\t} catch (error) {\n\t\tif (token !== undefined) rmSync(tokenPath, { force: true });\n\t\tthrow error;\n\t}\n\tif (token !== undefined) log(`Stored the token in ${tokenPath} (mode 600).`);\n\tlog(`Set \\`storage\\` in ${join(agentDir, \"settings.json\")}; other settings are unchanged.`);\n\tif (previous !== undefined && JSON.stringify(previous) !== JSON.stringify(storage)) {\n\t\tconst described = (() => {\n\t\t\ttry {\n\t\t\t\treturn describeStorageSelection(selectStorage(previous, \"settings\", \"storage\", \"\"));\n\t\t\t} catch {\n\t\t\t\treturn \"an invalid selection\";\n\t\t\t}\n\t\t})();\n\t\tlog(`It replaces the previous selection: ${described}.`);\n\t}\n\n\tconst control = await loadControl(options);\n\tlet collected: StorageStatus;\n\ttry {\n\t\tcollected = await collectStorageStatus({\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tprobe: false,\n\t\t\t...(control instanceof Error ? {} : { control }),\n\t\t});\n\t} catch (error) {\n\t\t// Settings and the token are already committed; optional diagnostics cannot undo that success.\n\t\tlog(`Storage was saved, but could not report overrides: ${errorText(error as Error)}.`);\n\t\tlog(`Run \\`${APP_NAME} storage status\\` after fixing the reported settings error.`);\n\t\treturn 0;\n\t}\n\tconst overridden = collected.domains.filter(\n\t\t(domain) => domain.source !== \"global settings: storage\" && domain.source !== \"default\",\n\t);\n\tif (overridden.length > 0) {\n\t\tlog(\"\", \"These take precedence over the new selection here:\");\n\t\tfor (const domain of overridden) log(` - ${DOMAIN_LABELS[domain.domain]}: ${domain.source}`);\n\t}\n\tfor (const note of collected.notes) log(`Note: ${note}`);\n\tconst broker = collected.broker;\n\tif (broker?.state === \"running\" && !broker.matchesCurrent) {\n\t\tlog(\n\t\t\t`The running Intercom broker (pid ${broker.pid}) still uses its previous selection. Run \\`${APP_NAME} intercom restart\\` so it uses the new one.`,\n\t\t);\n\t} else if (broker?.state === \"legacy\") {\n\t\tlog(\n\t\t\t`An Intercom broker from an older ${APP_NAME} is running. Run \\`${APP_NAME} intercom restart\\` to replace it.`,\n\t\t);\n\t}\n\tlog(`Run \\`${APP_NAME} storage status\\` to check each domain.`);\n\treturn 0;\n}\n\n/** Run `atomic storage <args>` and return the exit code. */\nexport async function runStorageCommand(args: readonly string[], options: StorageCommandOptions): Promise<number> {\n\tconst log = options.log ?? ((line: string) => console.log(line));\n\tconst error = options.error ?? ((line: string) => console.error(line));\n\ttry {\n\t\tconst command = parseStorageCommand(args);\n\t\tif (command.kind === \"help\") {\n\t\t\tlog(HELP);\n\t\t\treturn 0;\n\t\t}\n\t\tif (command.kind === \"status\") return await status(command.json, options, log);\n\t\treturn await joinStorage(command, options, (...lines) => {\n\t\t\tfor (const line of lines) log(line);\n\t\t});\n\t} catch (caught) {\n\t\terror(caught instanceof StorageCommandError ? caught.message : `Error: ${errorText(caught as Error)}`);\n\t\treturn 1;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-events.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAe,MAAM,uBAAuB,CAAC;AAEpF,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE9E,OAAO,KAAK,EAAE,2BAA2B,IAAI,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAW9F,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAI9B,MAAM,0BAA0B,CAAC;AAalC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-session-events.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAe,MAAM,uBAAuB,CAAC;AAEpF,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE9E,OAAO,KAAK,EAAE,2BAA2B,IAAI,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAW9F,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAI9B,MAAM,0BAA0B,CAAC;AAalC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAclE,wBAAgB,KAAK,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAIxE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAMzD;AAID,4EAA4E;AAE5E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CA0D7F;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CA6B1F;AAED,wBAAgB,4BAA4B,CAC3C,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,YAAY,EAAE,GACtB,gBAAgB,GAAG,SAAS,CAQ9B;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAuM7F;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CA0BvF;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAQvF;AAED,wCAAwC;AAExC,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAMtD;AAED,0CAA0C;AAE1C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAMhF;AAED,8EAA8E;AAE9E,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,YAAY,GAAG,gBAAgB,GAAG,SAAS,CAS1F;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,GAAG,IAAI,CAchH;AAED,kDAAkD;AAElD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAwE9F;AAED;;;;GAIG;AAEH,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAU7F;AAED,oDAAoD;AACpD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAK7D;AAWD,gFAAgF;AAChF,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,YAAY,EACrB,KAAK,GAAE,oBAAmE,EAC1E,gBAAgB,CAAC,EAAE,MAAM,IAAI,GAC3B,OAAO,CAAC,IAAI,CAAC,CA4Ff;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzD;AAMD,uBAAuB;AAEvB,eAAO,MAAM,yBAAyB;iBACxB,YAAY,SAAS,oBAAoB,qBAAqB,MAAM,IAAI;;;;;;;;;;;;;;;;;CAmBrF,CAAC"}
|