@cydm/happy-elves 0.1.0-beta.312 → 0.1.0-beta.313
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/apps/cli/dist/commands/app.js +8 -0
- package/apps/cli/dist/commands/artifact.d.ts +2 -0
- package/apps/cli/dist/commands/artifact.js +97 -0
- package/apps/cli/dist/commands/daemon.js +9 -10
- package/apps/cli/dist/commands/dispatch.d.ts +2 -0
- package/apps/cli/dist/commands/dispatch.js +130 -0
- package/apps/cli/dist/commands/lib/args.js +25 -2
- package/apps/cli/dist/commands/lib/bootstrap-daemon.js +9 -2
- package/apps/cli/dist/commands/lib/config.js +52 -0
- package/apps/cli/dist/commands/lib/index.d.ts +1 -0
- package/apps/cli/dist/commands/lib/index.js +1 -0
- package/apps/cli/dist/commands/lib/local-daemon.js +25 -9
- package/apps/cli/dist/commands/lib/loop-store.js +7 -16
- package/apps/cli/dist/commands/lib/relay-db-audit.js +19 -32
- package/apps/cli/dist/commands/lib/relay-debug.d.ts +84 -0
- package/apps/cli/dist/commands/lib/relay-debug.js +190 -0
- package/apps/cli/dist/commands/lib/scope.js +2 -2
- package/apps/cli/dist/commands/lib/session-output.js +99 -3
- package/apps/cli/dist/commands/lib/types.d.ts +12 -2
- package/apps/cli/dist/commands/lib/usage.js +67 -72
- package/apps/cli/dist/commands/lib/workspace.js +3 -10
- package/apps/cli/dist/commands/loop.js +2 -2
- package/apps/cli/dist/commands/queue.d.ts +2 -0
- package/apps/cli/dist/commands/queue.js +95 -0
- package/apps/cli/dist/commands/relay.d.ts +1 -1
- package/apps/cli/dist/commands/relay.js +302 -2
- package/apps/cli/dist/commands/session.js +11 -199
- package/apps/cli/dist/commands/sidechat.d.ts +2 -0
- package/apps/cli/dist/commands/sidechat.js +72 -0
- package/apps/cli/dist/commands/token.js +26 -10
- package/apps/cli/dist/commands/turn.js +92 -14
- package/apps/cli/package.json +1 -1
- package/apps/daemon/dist/artifact/handler.d.ts +17 -0
- package/apps/daemon/dist/artifact/handler.js +858 -0
- package/apps/daemon/dist/artifact/pitch-review-sdk.d.ts +1 -0
- package/apps/daemon/dist/artifact/pitch-review-sdk.js +63 -0
- package/apps/daemon/dist/artifact/store.d.ts +141 -0
- package/apps/daemon/dist/artifact/store.js +652 -0
- package/apps/daemon/dist/artifact/vendor/lavish-axi/LICENSE +21 -0
- package/apps/daemon/dist/artifact/vendor/lavish-axi/artifact-sdk.js +2729 -0
- package/apps/daemon/dist/artifact/vendor/lavish-axi/mermaid-node.js +83 -0
- package/apps/daemon/dist/artifact/vendor/lavish-axi/table-cell.js +168 -0
- package/apps/daemon/dist/config.js +34 -0
- package/apps/daemon/dist/direct/server.d.ts +8 -0
- package/apps/daemon/dist/direct/server.js +1118 -0
- package/apps/daemon/dist/direct/state.d.ts +10 -0
- package/apps/daemon/dist/direct/state.js +8 -0
- package/apps/daemon/dist/direct/tickets.d.ts +65 -0
- package/apps/daemon/dist/direct/tickets.js +242 -0
- package/apps/daemon/dist/gateway/handler.js +18 -7
- package/apps/daemon/dist/loop/runner.js +70 -5
- package/apps/daemon/dist/loop/store.js +7 -16
- package/apps/daemon/dist/memory/handler.js +38 -16
- package/apps/daemon/dist/memory/settings.d.ts +11 -0
- package/apps/daemon/dist/memory/settings.js +56 -0
- package/apps/daemon/dist/orchestration/crew-queue.d.ts +28 -0
- package/apps/daemon/dist/orchestration/crew-queue.js +834 -0
- package/apps/daemon/dist/orchestration/handler.d.ts +31 -0
- package/apps/daemon/dist/orchestration/handler.js +1456 -0
- package/apps/daemon/dist/orchestration/queue-state.d.ts +49 -0
- package/apps/daemon/dist/orchestration/queue-state.js +172 -0
- package/apps/daemon/dist/orchestration/runner.d.ts +2 -0
- package/apps/daemon/dist/orchestration/runner.js +449 -0
- package/apps/daemon/dist/orchestration/store-file.d.ts +3 -0
- package/apps/daemon/dist/orchestration/store-file.js +20 -0
- package/apps/daemon/dist/orchestration/store.d.ts +285 -0
- package/apps/daemon/dist/orchestration/store.js +1529 -0
- package/apps/daemon/dist/orchestration/wake-identity.d.ts +13 -0
- package/apps/daemon/dist/orchestration/wake-identity.js +20 -0
- package/apps/daemon/dist/orchestration/watcher.d.ts +22 -0
- package/apps/daemon/dist/orchestration/watcher.js +302 -0
- package/apps/daemon/dist/pair.js +1 -1
- package/apps/daemon/dist/paths.d.ts +4 -1
- package/apps/daemon/dist/paths.js +4 -1
- package/apps/daemon/dist/process.d.ts +1 -0
- package/apps/daemon/dist/process.js +11 -4
- package/apps/daemon/dist/relay/admission.d.ts +14 -0
- package/apps/daemon/dist/relay/admission.js +231 -24
- package/apps/daemon/dist/relay/connection.d.ts +2 -0
- package/apps/daemon/dist/relay/connection.js +468 -18
- package/apps/daemon/dist/relay/devtools.js +78 -2
- package/apps/daemon/dist/relay/inbound-prompt.d.ts +14 -0
- package/apps/daemon/dist/relay/inbound-prompt.js +151 -0
- package/apps/daemon/dist/relay/prompt-admission-store.d.ts +49 -0
- package/apps/daemon/dist/relay/prompt-admission-store.js +348 -0
- package/apps/daemon/dist/relay/register.js +65 -27
- package/apps/daemon/dist/relay/remote-command.d.ts +22 -0
- package/apps/daemon/dist/relay/remote-command.js +128 -0
- package/apps/daemon/dist/relay/send.d.ts +10 -2
- package/apps/daemon/dist/relay/send.js +311 -8
- package/apps/daemon/dist/runtime/headless-binding.d.ts +13 -0
- package/apps/daemon/dist/runtime/headless-binding.js +32 -0
- package/apps/daemon/dist/runtime/headless-event-projector.d.ts +38 -0
- package/apps/daemon/dist/runtime/headless-event-projector.js +1018 -0
- package/apps/daemon/dist/runtime/headless-history-reader.d.ts +13 -0
- package/apps/daemon/dist/runtime/headless-history-reader.js +64 -0
- package/apps/daemon/dist/runtime/headless-manager.d.ts +50 -0
- package/apps/daemon/dist/runtime/headless-manager.js +238 -0
- package/apps/daemon/dist/runtime/headless-official-tool-bridge.d.ts +4 -0
- package/apps/daemon/dist/runtime/headless-official-tool-bridge.js +95 -0
- package/apps/daemon/dist/runtime/headless-server-request.d.ts +17 -0
- package/apps/daemon/dist/runtime/headless-server-request.js +32 -0
- package/apps/daemon/dist/runtime/headless-session-context.d.ts +11 -0
- package/apps/daemon/dist/runtime/headless-session-context.js +41 -0
- package/apps/daemon/dist/runtime/headless-session-history.d.ts +13 -0
- package/apps/daemon/dist/runtime/headless-session-history.js +271 -0
- package/apps/daemon/dist/runtime/headless-session-primitives.d.ts +33 -0
- package/apps/daemon/dist/runtime/headless-session-primitives.js +64 -0
- package/apps/daemon/dist/runtime/headless-turn-inspector.d.ts +8 -0
- package/apps/daemon/dist/runtime/headless-turn-inspector.js +116 -0
- package/apps/daemon/dist/runtime/headless-turn-runner.d.ts +27 -0
- package/apps/daemon/dist/runtime/headless-turn-runner.js +387 -0
- package/apps/daemon/dist/runtime.d.ts +9 -4
- package/apps/daemon/dist/runtime.js +83 -61
- package/apps/daemon/dist/schedule/handler.js +18 -7
- package/apps/daemon/dist/session/create-session.js +7 -1
- package/apps/daemon/dist/session/events.d.ts +7 -1
- package/apps/daemon/dist/session/events.js +111 -14
- package/apps/daemon/dist/session/he-official/approval.d.ts +12 -0
- package/apps/daemon/dist/session/he-official/approval.js +52 -0
- package/apps/daemon/dist/session/he-official/artifact-commands.d.ts +6 -0
- package/apps/daemon/dist/session/he-official/artifact-commands.js +293 -0
- package/apps/daemon/dist/session/he-official/common.d.ts +390 -0
- package/apps/daemon/dist/session/he-official/common.js +311 -0
- package/apps/daemon/dist/session/he-official/delegate-commands.d.ts +5 -0
- package/apps/daemon/dist/session/he-official/delegate-commands.js +424 -0
- package/apps/daemon/dist/session/he-official/options.d.ts +4 -0
- package/apps/daemon/dist/session/he-official/options.js +72 -0
- package/apps/daemon/dist/session/he-official/orchestration-commands.d.ts +74 -0
- package/apps/daemon/dist/session/he-official/orchestration-commands.js +381 -0
- package/apps/daemon/dist/session/he-official/result.d.ts +34 -0
- package/apps/daemon/dist/session/he-official/result.js +292 -0
- package/apps/daemon/dist/session/he-official/session-commands.d.ts +20 -0
- package/apps/daemon/dist/session/he-official/session-commands.js +132 -0
- package/apps/daemon/dist/session/he-official/trace.d.ts +65 -0
- package/apps/daemon/dist/session/he-official/trace.js +210 -0
- package/apps/daemon/dist/session/he-official/turn-commands.d.ts +31 -0
- package/apps/daemon/dist/session/he-official/turn-commands.js +315 -0
- package/apps/daemon/dist/session/he-official-tools.d.ts +6 -0
- package/apps/daemon/dist/session/he-official-tools.js +97 -0
- package/apps/daemon/dist/session/history-backfill.d.ts +45 -0
- package/apps/daemon/dist/session/history-backfill.js +139 -0
- package/apps/daemon/dist/session/lifecycle.d.ts +8 -35
- package/apps/daemon/dist/session/lifecycle.js +406 -434
- package/apps/daemon/dist/session/metadata.d.ts +3 -2
- package/apps/daemon/dist/session/metadata.js +82 -10
- package/apps/daemon/dist/session/primitives.js +67 -65
- package/apps/daemon/dist/session/prompt.d.ts +16 -3
- package/apps/daemon/dist/session/prompt.js +637 -48
- package/apps/daemon/dist/session/reconcile.d.ts +1 -1
- package/apps/daemon/dist/session/reconcile.js +108 -107
- package/apps/daemon/dist/session/runtime-read.d.ts +7 -0
- package/apps/daemon/dist/session/runtime-read.js +23 -0
- package/apps/daemon/dist/session/runtime-truth.d.ts +26 -0
- package/apps/daemon/dist/session/runtime-truth.js +453 -0
- package/apps/daemon/dist/session/sidechat.d.ts +11 -0
- package/apps/daemon/dist/session/sidechat.js +231 -0
- package/apps/daemon/dist/session/store.d.ts +20 -0
- package/apps/daemon/dist/session/store.js +219 -0
- package/apps/daemon/dist/start.js +31 -2
- package/apps/daemon/dist/state.d.ts +21 -1
- package/apps/daemon/dist/state.js +35 -0
- package/apps/daemon/dist/types.d.ts +50 -12
- package/apps/daemon/package.json +1 -1
- package/apps/relay/dist/auth.js +12 -0
- package/apps/relay/dist/control-plane-store.d.ts +229 -0
- package/apps/relay/dist/control-plane-store.js +263 -0
- package/apps/relay/dist/db.d.ts +1 -2
- package/apps/relay/dist/db.js +53 -391
- package/apps/relay/dist/direct-ticket-grants.d.ts +1 -0
- package/apps/relay/dist/direct-ticket-grants.js +16 -0
- package/apps/relay/dist/http-routes.js +182 -925
- package/apps/relay/dist/http-schemas.d.ts +57 -172
- package/apps/relay/dist/http-schemas.js +48 -112
- package/apps/relay/dist/index.js +50 -5
- package/apps/relay/dist/packet-store.d.ts +73 -0
- package/apps/relay/dist/packet-store.js +265 -0
- package/apps/relay/dist/relay-context.d.ts +57 -120
- package/apps/relay/dist/relay-context.js +154 -650
- package/apps/relay/dist/relay-migration.d.ts +26 -0
- package/apps/relay/dist/relay-migration.js +315 -0
- package/apps/relay/dist/retention.js +1 -2
- package/apps/relay/dist/types.d.ts +36 -133
- package/apps/relay/dist/websocket.d.ts +24 -0
- package/apps/relay/dist/websocket.js +707 -99
- package/package.json +7 -5
- package/packages/agent-sdk/dist/index.d.ts +7 -420
- package/packages/agent-sdk/dist/index.js +12 -183
- package/packages/client/dist/account.d.ts +5 -21
- package/packages/client/dist/account.js +142 -74
- package/packages/client/dist/client.d.ts +29 -5
- package/packages/client/dist/client.js +619 -89
- package/packages/client/dist/command-contracts.d.ts +6 -0
- package/packages/client/dist/command-contracts.js +20 -0
- package/packages/client/dist/direct.d.ts +12 -0
- package/packages/client/dist/direct.js +427 -0
- package/packages/client/dist/index.d.ts +1 -1
- package/packages/client/dist/parsers.d.ts +2 -1
- package/packages/client/dist/parsers.js +31 -17
- package/packages/client/dist/product-materializer.d.ts +27 -0
- package/packages/client/dist/product-materializer.js +465 -0
- package/packages/client/dist/transport.d.ts +31 -0
- package/packages/client/dist/transport.js +388 -153
- package/packages/client/dist/types.d.ts +216 -10
- package/packages/client/dist/validation.d.ts +0 -1
- package/packages/client/dist/validation.js +0 -9
- package/packages/client/dist/workspace-shared-config.d.ts +23 -0
- package/packages/client/dist/workspace-shared-config.js +487 -0
- package/packages/headless-runtime/dist/claude-provider.d.ts +20 -0
- package/packages/headless-runtime/dist/claude-provider.js +1092 -0
- package/packages/{runtime-cli → headless-runtime}/dist/claude-session-store.d.ts +1 -1
- package/packages/{runtime-cli → headless-runtime}/dist/claude-session-store.js +33 -12
- package/packages/headless-runtime/dist/cli.d.ts +3 -0
- package/packages/headless-runtime/dist/cli.js +1243 -0
- package/packages/headless-runtime/dist/client.d.ts +75 -0
- package/packages/headless-runtime/dist/client.js +490 -0
- package/packages/headless-runtime/dist/codex-provider.d.ts +9 -0
- package/packages/headless-runtime/dist/codex-provider.js +1278 -0
- package/packages/headless-runtime/dist/core.d.ts +304 -0
- package/packages/headless-runtime/dist/core.js +2589 -0
- package/packages/headless-runtime/dist/event-log.d.ts +11 -0
- package/packages/headless-runtime/dist/event-log.js +257 -0
- package/packages/headless-runtime/dist/history-index.d.ts +28 -0
- package/packages/headless-runtime/dist/history-index.js +72 -0
- package/packages/headless-runtime/dist/host-tools.d.ts +21 -0
- package/packages/headless-runtime/dist/host-tools.js +252 -0
- package/packages/headless-runtime/dist/host.d.ts +63 -0
- package/packages/headless-runtime/dist/host.js +423 -0
- package/packages/headless-runtime/dist/index.d.ts +44 -0
- package/packages/headless-runtime/dist/index.js +487 -0
- package/packages/headless-runtime/dist/ipc.d.ts +4 -0
- package/packages/headless-runtime/dist/ipc.js +28 -0
- package/packages/headless-runtime/dist/mock-scenario.d.ts +7 -0
- package/packages/headless-runtime/dist/mock-scenario.js +65 -0
- package/packages/headless-runtime/dist/model-catalog.d.ts +21 -0
- package/packages/headless-runtime/dist/model-catalog.js +271 -0
- package/packages/headless-runtime/dist/provider-command.d.ts +10 -0
- package/packages/headless-runtime/dist/provider-command.js +432 -0
- package/packages/headless-runtime/dist/provider-turn-metadata.d.ts +9 -0
- package/packages/headless-runtime/dist/provider-turn-metadata.js +76 -0
- package/packages/headless-runtime/dist/public-response.d.ts +9 -0
- package/packages/headless-runtime/dist/public-response.js +112 -0
- package/packages/headless-runtime/dist/runtime-projection-store.d.ts +49 -0
- package/packages/headless-runtime/dist/runtime-projection-store.js +318 -0
- package/packages/headless-runtime/dist/trace-log.d.ts +31 -0
- package/packages/headless-runtime/dist/trace-log.js +106 -0
- package/packages/pie-provider/dist/index.js +919 -692
- package/packages/runtime/dist/headless.d.ts +575 -0
- package/packages/runtime/dist/headless.js +3 -0
- package/packages/runtime/dist/index.d.ts +68 -112
- package/packages/shared/dist/crypto.d.ts +1 -0
- package/packages/shared/dist/crypto.js +5 -0
- package/packages/shared/dist/diagnostics.d.ts +31 -0
- package/packages/shared/dist/diagnostics.js +81 -0
- package/packages/shared/dist/file-lock.d.ts +29 -0
- package/packages/shared/dist/file-lock.js +301 -0
- package/packages/shared/dist/he-official-tools.d.ts +78 -0
- package/packages/shared/dist/he-official-tools.js +737 -0
- package/packages/shared/dist/index.d.ts +5 -0
- package/packages/shared/dist/index.js +5 -0
- package/packages/shared/dist/orchestration-routing.d.ts +10 -0
- package/packages/shared/dist/orchestration-routing.js +113 -0
- package/packages/shared/dist/packet-relay.d.ts +220 -0
- package/packages/shared/dist/packet-relay.js +120 -0
- package/packages/shared/dist/protocol-schemas.d.ts +1838 -61
- package/packages/shared/dist/protocol-schemas.js +599 -7
- package/packages/shared/dist/protocol-types.d.ts +510 -7
- package/packages/shared/dist/protocol.d.ts +558 -3
- package/packages/shared/dist/protocol.js +651 -4
- package/packages/shared/dist/relay-scope.d.ts +32 -0
- package/packages/shared/dist/relay-scope.js +23 -0
- package/packages/shared/dist/session-state.d.ts +1 -1
- package/apps/daemon/dist/runtime/external-provider.d.ts +0 -20
- package/apps/daemon/dist/runtime/external-provider.js +0 -920
- package/apps/daemon/dist/session/runtime-handle.d.ts +0 -7
- package/apps/daemon/dist/session/runtime-handle.js +0 -48
- package/apps/relay/dist/connections.d.ts +0 -13
- package/apps/relay/dist/connections.js +0 -11
- package/apps/relay/dist/controller-handlers.d.ts +0 -79
- package/apps/relay/dist/controller-handlers.js +0 -777
- package/apps/relay/dist/machine-handlers.d.ts +0 -58
- package/apps/relay/dist/machine-handlers.js +0 -975
- package/apps/relay/dist/projections.d.ts +0 -7
- package/apps/relay/dist/projections.js +0 -125
- package/apps/relay/dist/repositories.d.ts +0 -13
- package/apps/relay/dist/repositories.js +0 -98
- package/apps/relay/dist/runtime-bindings.d.ts +0 -25
- package/apps/relay/dist/runtime-bindings.js +0 -49
- package/apps/relay/dist/scope.d.ts +0 -20
- package/apps/relay/dist/scope.js +0 -60
- package/packages/runtime-acpx/dist/index.d.ts +0 -11
- package/packages/runtime-acpx/dist/index.js +0 -120
- package/packages/runtime-cli/dist/async-queue.d.ts +0 -10
- package/packages/runtime-cli/dist/async-queue.js +0 -32
- package/packages/runtime-cli/dist/claude-history.d.ts +0 -7
- package/packages/runtime-cli/dist/claude-history.js +0 -344
- package/packages/runtime-cli/dist/claude-json.d.ts +0 -29
- package/packages/runtime-cli/dist/claude-json.js +0 -29
- package/packages/runtime-cli/dist/claude-rename.d.ts +0 -6
- package/packages/runtime-cli/dist/claude-rename.js +0 -15
- package/packages/runtime-cli/dist/claude-turn.d.ts +0 -14
- package/packages/runtime-cli/dist/claude-turn.js +0 -122
- package/packages/runtime-cli/dist/codex-app-server.d.ts +0 -59
- package/packages/runtime-cli/dist/codex-app-server.js +0 -418
- package/packages/runtime-cli/dist/codex-approvals.d.ts +0 -8
- package/packages/runtime-cli/dist/codex-approvals.js +0 -33
- package/packages/runtime-cli/dist/codex-history.d.ts +0 -17
- package/packages/runtime-cli/dist/codex-history.js +0 -711
- package/packages/runtime-cli/dist/codex-json-rpc.d.ts +0 -30
- package/packages/runtime-cli/dist/codex-json-rpc.js +0 -150
- package/packages/runtime-cli/dist/codex-lifecycle.d.ts +0 -25
- package/packages/runtime-cli/dist/codex-lifecycle.js +0 -72
- package/packages/runtime-cli/dist/codex-protocol.d.ts +0 -6
- package/packages/runtime-cli/dist/codex-protocol.js +0 -53
- package/packages/runtime-cli/dist/command-resolver.d.ts +0 -24
- package/packages/runtime-cli/dist/command-resolver.js +0 -101
- package/packages/runtime-cli/dist/history-merge.d.ts +0 -18
- package/packages/runtime-cli/dist/history-merge.js +0 -274
- package/packages/runtime-cli/dist/index.d.ts +0 -11
- package/packages/runtime-cli/dist/index.js +0 -350
- package/packages/runtime-cli/dist/permissions.d.ts +0 -6
- package/packages/runtime-cli/dist/permissions.js +0 -22
- package/packages/runtime-cli/dist/session-store.d.ts +0 -33
- package/packages/runtime-cli/dist/session-store.js +0 -93
|
@@ -4,15 +4,19 @@ import { handleAccount } from "./account.js";
|
|
|
4
4
|
import { handleCollect } from "./collect.js";
|
|
5
5
|
import { handleConfig } from "./config.js";
|
|
6
6
|
import { handleDaemon } from "./daemon.js";
|
|
7
|
+
import { handleDispatch } from "./dispatch.js";
|
|
8
|
+
import { handleArtifact } from "./artifact.js";
|
|
7
9
|
import { handleGateway } from "./gateway.js";
|
|
8
10
|
import { handleLoop } from "./loop.js";
|
|
9
11
|
import { handleMachine } from "./machine.js";
|
|
10
12
|
import { handleMemory } from "./memory.js";
|
|
13
|
+
import { handleQueue } from "./queue.js";
|
|
11
14
|
import { handleRelay } from "./relay.js";
|
|
12
15
|
import { handleRelease } from "./release.js";
|
|
13
16
|
import { handleSchedule } from "./schedule.js";
|
|
14
17
|
import { handleRemote } from "./remote.js";
|
|
15
18
|
import { handleSession } from "./session.js";
|
|
19
|
+
import { handleSidechat } from "./sidechat.js";
|
|
16
20
|
import { handleToken } from "./token.js";
|
|
17
21
|
import { handleTurn } from "./turn.js";
|
|
18
22
|
import { handleWorkspace } from "./workspace.js";
|
|
@@ -25,6 +29,10 @@ const domainHandlers = [
|
|
|
25
29
|
handleToken,
|
|
26
30
|
handleGateway,
|
|
27
31
|
handleLoop,
|
|
32
|
+
handleDispatch,
|
|
33
|
+
handleQueue,
|
|
34
|
+
handleArtifact,
|
|
35
|
+
handleSidechat,
|
|
28
36
|
handleDaemon,
|
|
29
37
|
handleRelay,
|
|
30
38
|
handleRelease,
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { CliError, ControllerClient, ok, readConfig, requirePositional, requireString, wantsJson, } from "./lib/index.js";
|
|
2
|
+
export async function handleArtifact({ domain, action, positional, flags }) {
|
|
3
|
+
if (domain !== "artifact")
|
|
4
|
+
return false;
|
|
5
|
+
const config = await readConfig(flags);
|
|
6
|
+
const client = new ControllerClient(config);
|
|
7
|
+
if (action === "register") {
|
|
8
|
+
const machineId = requireString(flags, "machine");
|
|
9
|
+
const consumerSessionId = requireString(flags, "consumer-session");
|
|
10
|
+
const file = requireString(flags, "file");
|
|
11
|
+
const publish = typeof flags.publish === "string" ? flags.publish : undefined;
|
|
12
|
+
if (publish !== undefined && publish !== "relay") {
|
|
13
|
+
throw new CliError(`Unsupported --publish value: ${publish}`, "INVALID_ARGUMENT");
|
|
14
|
+
}
|
|
15
|
+
const result = await client.artifactRegister({
|
|
16
|
+
machineId,
|
|
17
|
+
consumerSessionId,
|
|
18
|
+
file,
|
|
19
|
+
...(typeof flags["artifact-id"] === "string" ? { artifactId: flags["artifact-id"] } : {}),
|
|
20
|
+
...(typeof flags["task-id"] === "string" ? { taskId: flags["task-id"] } : {}),
|
|
21
|
+
...(typeof flags["crew-session"] === "string" ? { crewSessionId: flags["crew-session"] } : {}),
|
|
22
|
+
...(typeof flags["turn-id"] === "string" ? { turnId: flags["turn-id"] } : {}),
|
|
23
|
+
...(typeof flags.title === "string" ? { title: flags.title } : {}),
|
|
24
|
+
...(typeof flags["request-id"] === "string" ? { requestId: flags["request-id"] } : {}),
|
|
25
|
+
...(publish === "relay" ? { publish: "relay" } : {}),
|
|
26
|
+
});
|
|
27
|
+
if (!wantsJson(flags)) {
|
|
28
|
+
console.log(`${result.artifactId} rev:${result.revision} ${result.admission}/${result.publishState} ${result.url}`);
|
|
29
|
+
if (result.publishState === "failed")
|
|
30
|
+
process.exitCode = 1;
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
ok("artifact.register", result, { requestId: result.requestId, machineId }, result.publishState !== "failed");
|
|
34
|
+
if (result.publishState === "failed")
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
if (action === "list") {
|
|
39
|
+
const machineId = requireString(flags, "machine");
|
|
40
|
+
const result = await client.artifactList({
|
|
41
|
+
machineId,
|
|
42
|
+
...(typeof flags["consumer-session"] === "string" ? { consumerSessionId: flags["consumer-session"] } : {}),
|
|
43
|
+
...(typeof flags["task-id"] === "string" ? { taskId: flags["task-id"] } : {}),
|
|
44
|
+
...(typeof flags["request-id"] === "string" ? { requestId: flags["request-id"] } : {}),
|
|
45
|
+
});
|
|
46
|
+
if (!wantsJson(flags)) {
|
|
47
|
+
if (result.records.length === 0)
|
|
48
|
+
console.log("No artifacts.");
|
|
49
|
+
else
|
|
50
|
+
for (const record of result.records) {
|
|
51
|
+
console.log(`${record.artifactId} rev:${record.revision} ${record.publishState} consumer:${record.consumerSessionId} task:${record.taskId ?? "-"}`);
|
|
52
|
+
}
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
ok("artifact.list", result, { requestId: result.requestId, machineId });
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
if (action === "status") {
|
|
59
|
+
const machineId = requireString(flags, "machine");
|
|
60
|
+
const artifactId = requirePositional(positional[0], "artifactId");
|
|
61
|
+
const result = await client.artifactStatus({
|
|
62
|
+
machineId,
|
|
63
|
+
artifactId,
|
|
64
|
+
...(typeof flags["request-id"] === "string" ? { requestId: flags["request-id"] } : {}),
|
|
65
|
+
});
|
|
66
|
+
if (!wantsJson(flags)) {
|
|
67
|
+
const artifact = result.artifact;
|
|
68
|
+
console.log(artifact ? `${artifact.artifactId} rev:${artifact.revision} ${artifact.publishState} feedback:${artifact.feedbackCursor ?? "-"}` : "Artifact not found.");
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
ok("artifact.status", result, { requestId: result.requestId, machineId });
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
if (action === "feedback" && positional[0] === "list") {
|
|
75
|
+
const machineId = requireString(flags, "machine");
|
|
76
|
+
const artifactId = requirePositional(positional[1], "artifactId");
|
|
77
|
+
const result = await client.artifactFeedbackList({
|
|
78
|
+
machineId,
|
|
79
|
+
artifactId,
|
|
80
|
+
...(typeof flags.after === "string" ? { after: flags.after } : {}),
|
|
81
|
+
...(typeof flags["request-id"] === "string" ? { requestId: flags["request-id"] } : {}),
|
|
82
|
+
});
|
|
83
|
+
if (!wantsJson(flags)) {
|
|
84
|
+
if (result.records.length === 0)
|
|
85
|
+
console.log("No feedback.");
|
|
86
|
+
else
|
|
87
|
+
for (const record of result.records) {
|
|
88
|
+
console.log(`${record.feedbackCursor} ${record.kind} rev:${record.revision} ${record.prompt}`);
|
|
89
|
+
}
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
ok("artifact.feedback.list", result, { requestId: result.requestId, machineId });
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=artifact.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import os from "node:os";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { CliError, compactText, ControllerClient, configDir, configPath,
|
|
3
|
+
import { CliError, compactText, ControllerClient, configDir, configPath, deriveOrchestration, ensureDaemonRunning, idleSessionStatuses, localDaemonStatus, ok, parsePairingClaimResponse, randomId, readConfig, readDaemonConfig, readLocalAuditLog, readRelayJson, redactedDaemonConfig, requirePositional, requireRelayUrl, requireString, restartDaemonForNewConfig, showMachine, stopLocalDaemon, throwRelayHttpError, waitForMachineProjection, wantsJson, writeDaemonConfig } from "./lib/index.js";
|
|
4
4
|
export async function handleDaemon({ domain, action, flags }) {
|
|
5
5
|
if (domain === "daemon" && action === "pair") {
|
|
6
6
|
const relayUrl = requireRelayUrl(flags);
|
|
@@ -205,10 +205,10 @@ export async function handleDaemon({ domain, action, flags }) {
|
|
|
205
205
|
ok("daemon.start", { ...status, started: false });
|
|
206
206
|
return true;
|
|
207
207
|
}
|
|
208
|
-
await readDaemonConfig();
|
|
209
|
-
const
|
|
210
|
-
const
|
|
211
|
-
ok("daemon.start", {
|
|
208
|
+
const daemonConfig = await readDaemonConfig();
|
|
209
|
+
const relayUrl = typeof flags.relay === "string" ? requireRelayUrl(flags) : daemonConfig.relayUrl;
|
|
210
|
+
const started = await ensureDaemonRunning(relayUrl);
|
|
211
|
+
ok("daemon.start", { ...started.local, started: started.started, startedPid: started.startedPid, startupLogPath: path.join(configDir, "daemon.startup.log") });
|
|
212
212
|
return true;
|
|
213
213
|
}
|
|
214
214
|
if (domain === "daemon" && action === "stop") {
|
|
@@ -216,11 +216,10 @@ export async function handleDaemon({ domain, action, flags }) {
|
|
|
216
216
|
return true;
|
|
217
217
|
}
|
|
218
218
|
if (domain === "daemon" && action === "restart") {
|
|
219
|
-
await readDaemonConfig();
|
|
220
|
-
const
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
ok("daemon.restart", { stop, startedPid: pid, pidPath: daemonPidPath });
|
|
219
|
+
const daemonConfig = await readDaemonConfig();
|
|
220
|
+
const relayUrl = typeof flags.relay === "string" ? requireRelayUrl(flags) : daemonConfig.relayUrl;
|
|
221
|
+
const restarted = await restartDaemonForNewConfig(relayUrl);
|
|
222
|
+
ok("daemon.restart", { stop: restarted.stopped, ...restarted.local, startedPid: restarted.startedPid, startupLogPath: path.join(configDir, "daemon.startup.log") });
|
|
224
223
|
return true;
|
|
225
224
|
}
|
|
226
225
|
if (domain === "daemon" && action === "status" && flags.local === true) {
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { CliError, ControllerClient, ok, parsePermissionMode, readConfig, readPromptTextFile, requirePositional, requireString, wantsJson, } from "./lib/index.js";
|
|
2
|
+
export async function handleDispatch({ domain, action, positional, flags }) {
|
|
3
|
+
if (domain !== "dispatch")
|
|
4
|
+
return false;
|
|
5
|
+
const config = await readConfig(flags);
|
|
6
|
+
const client = new ControllerClient(config);
|
|
7
|
+
if (action === "run") {
|
|
8
|
+
const machineId = requireString(flags, "machine");
|
|
9
|
+
const consumerSessionId = requireString(flags, "consumer-session");
|
|
10
|
+
const agent = requireString(flags, "agent");
|
|
11
|
+
const cwd = requireString(flags, "cwd");
|
|
12
|
+
const briefFile = requireString(flags, "brief-file");
|
|
13
|
+
const brief = await readPromptTextFile(briefFile);
|
|
14
|
+
if (!brief.trim())
|
|
15
|
+
throw new CliError("--brief-file is empty", "MISSING_ARGUMENT");
|
|
16
|
+
if (typeof flags["crew-session"] === "string" && typeof flags["fork-from-crew"] === "string") {
|
|
17
|
+
throw new CliError("--crew-session and --fork-from-crew are mutually exclusive", "INVALID_ARGUMENT");
|
|
18
|
+
}
|
|
19
|
+
const routeDecision = routeDecisionFromFlags(flags);
|
|
20
|
+
const permissionMode = parsePermissionMode(flags["permission-mode"] ?? flags.permission);
|
|
21
|
+
const result = await client.dispatchRun({
|
|
22
|
+
machineId,
|
|
23
|
+
consumerSessionId,
|
|
24
|
+
agent,
|
|
25
|
+
cwd,
|
|
26
|
+
brief,
|
|
27
|
+
...(typeof flags["task-id"] === "string" ? { taskId: flags["task-id"] } : {}),
|
|
28
|
+
...(typeof flags["request-id"] === "string" ? { requestId: flags["request-id"] } : {}),
|
|
29
|
+
...(typeof flags["crew-session"] === "string" ? { crewSessionId: flags["crew-session"] } : {}),
|
|
30
|
+
...(typeof flags["fork-from-crew"] === "string" ? { forkFromCrewSessionId: flags["fork-from-crew"] } : {}),
|
|
31
|
+
...(typeof flags["fork-checkpoint"] === "string" ? { forkCheckpointId: flags["fork-checkpoint"] } : {}),
|
|
32
|
+
...(routeDecision ? { routeDecision } : {}),
|
|
33
|
+
...(permissionMode ? { permissionMode } : {}),
|
|
34
|
+
...(typeof flags.model === "string" ? { model: flags.model } : {}),
|
|
35
|
+
...(typeof flags["thinking-level"] === "string" ? { thinkingLevel: flags["thinking-level"] } : {}),
|
|
36
|
+
subscribe: flags.subscribe !== false,
|
|
37
|
+
});
|
|
38
|
+
if (!wantsJson(flags)) {
|
|
39
|
+
console.log(`${result.taskId} ${result.admission}/${result.dispatch} owner:${result.consumerMachineId ?? "-"} crewMachine:${result.crewMachineId ?? machineId} crew:${result.crewSessionId ?? "-"} turn:${result.turnId ?? "-"}`);
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
ok("dispatch.run", result, {
|
|
43
|
+
requestId: result.requestId,
|
|
44
|
+
machineId: result.consumerMachineId ?? machineId,
|
|
45
|
+
consumerMachineId: result.consumerMachineId ?? machineId,
|
|
46
|
+
crewMachineId: result.crewMachineId ?? machineId,
|
|
47
|
+
sessionId: result.crewSessionId,
|
|
48
|
+
turnId: result.turnId,
|
|
49
|
+
}, result.dispatch !== "failed");
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
if (action === "status") {
|
|
53
|
+
const machineId = requireString(flags, "machine");
|
|
54
|
+
const taskId = requirePositional(positional[0], "taskId");
|
|
55
|
+
const result = await client.dispatchStatus({
|
|
56
|
+
machineId,
|
|
57
|
+
taskId,
|
|
58
|
+
...(typeof flags["request-id"] === "string" ? { requestId: flags["request-id"] } : {}),
|
|
59
|
+
});
|
|
60
|
+
if (!wantsJson(flags)) {
|
|
61
|
+
const admission = result.admission;
|
|
62
|
+
const attention = result.attention;
|
|
63
|
+
console.log(`${result.taskId} admission:${admission?.admission ?? "-"} dispatch:${admission?.dispatch ?? "-"} attention:${attention?.status ?? "-"}`);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
ok("dispatch.status", result, { requestId: result.requestId, machineId });
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
if (action === "list") {
|
|
70
|
+
const machineId = requireString(flags, "machine");
|
|
71
|
+
const result = await client.dispatchList({
|
|
72
|
+
machineId,
|
|
73
|
+
...(typeof flags["consumer-session"] === "string" ? { consumerSessionId: flags["consumer-session"] } : {}),
|
|
74
|
+
...(typeof flags["request-id"] === "string" ? { requestId: flags["request-id"] } : {}),
|
|
75
|
+
});
|
|
76
|
+
if (!wantsJson(flags)) {
|
|
77
|
+
for (const record of result.records) {
|
|
78
|
+
const attention = record.attention;
|
|
79
|
+
const reason = attention?.reasons.at(-1) ?? record.error ?? record.briefPreview ?? "";
|
|
80
|
+
console.log([
|
|
81
|
+
record.taskId,
|
|
82
|
+
`dispatch:${record.dispatch}`,
|
|
83
|
+
`attention:${attention?.status ?? "-"}`,
|
|
84
|
+
`crew:${record.crewSessionId ?? "-"}`,
|
|
85
|
+
reason ? `reason:${reason}` : "",
|
|
86
|
+
].filter(Boolean).join(" "));
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
ok("dispatch.list", result, { requestId: result.requestId, machineId });
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
function routeDecisionFromFlags(flags) {
|
|
96
|
+
const raw = flags["route-decision"];
|
|
97
|
+
const ifBusy = flags["if-busy"];
|
|
98
|
+
if (ifBusy !== undefined && ifBusy !== "queue") {
|
|
99
|
+
throw new CliError("--if-busy must be queue", "INVALID_ARGUMENT");
|
|
100
|
+
}
|
|
101
|
+
if (typeof raw !== "string") {
|
|
102
|
+
if (ifBusy === "queue" && typeof flags["crew-session"] === "string" && typeof flags["fork-from-crew"] !== "string") {
|
|
103
|
+
return { kind: "reuse", crewSessionId: flags["crew-session"], ifBusy };
|
|
104
|
+
}
|
|
105
|
+
if (ifBusy === "queue")
|
|
106
|
+
throw new CliError("--if-busy queue requires --crew-session or --route-decision reuse", "INVALID_ARGUMENT");
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
if (raw === "new") {
|
|
110
|
+
if (ifBusy === "queue")
|
|
111
|
+
throw new CliError("--if-busy queue is only valid with --route-decision reuse", "INVALID_ARGUMENT");
|
|
112
|
+
return { kind: "new" };
|
|
113
|
+
}
|
|
114
|
+
if (raw === "reuse") {
|
|
115
|
+
const crewSessionId = requireString(flags, "crew-session");
|
|
116
|
+
return { kind: "reuse", crewSessionId, ...(ifBusy === "queue" ? { ifBusy } : {}) };
|
|
117
|
+
}
|
|
118
|
+
if (ifBusy === "queue")
|
|
119
|
+
throw new CliError("--if-busy queue is only valid with --route-decision reuse", "INVALID_ARGUMENT");
|
|
120
|
+
if (raw === "fork") {
|
|
121
|
+
const crewSessionId = requireString(flags, "fork-from-crew");
|
|
122
|
+
return {
|
|
123
|
+
kind: "fork",
|
|
124
|
+
crewSessionId,
|
|
125
|
+
...(typeof flags["fork-checkpoint"] === "string" ? { forkCheckpointId: flags["fork-checkpoint"] } : {}),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
throw new CliError("--route-decision must be one of new, reuse, or fork", "INVALID_ARGUMENT");
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=dispatch.js.map
|
|
@@ -2,21 +2,28 @@ import { parseFlags as parseSharedFlags } from "../../../../../packages/shared/d
|
|
|
2
2
|
import { CliError } from "../../errors.js";
|
|
3
3
|
const valueFlags = new Set([
|
|
4
4
|
"agent",
|
|
5
|
+
"account",
|
|
5
6
|
"app-id",
|
|
7
|
+
"artifact-id",
|
|
6
8
|
"at",
|
|
7
9
|
"channel",
|
|
8
10
|
"code",
|
|
9
11
|
"conversation",
|
|
12
|
+
"consumer-session",
|
|
10
13
|
"cron",
|
|
11
14
|
"controller",
|
|
15
|
+
"crew-session",
|
|
12
16
|
"cwd",
|
|
13
17
|
"date",
|
|
14
18
|
"device-id",
|
|
15
19
|
"device-name",
|
|
20
|
+
"brief-file",
|
|
16
21
|
"every-ms",
|
|
17
22
|
"execution",
|
|
23
|
+
"file",
|
|
18
24
|
"from",
|
|
19
25
|
"host",
|
|
26
|
+
"if-busy",
|
|
20
27
|
"domain",
|
|
21
28
|
"invite-secret",
|
|
22
29
|
"inbound",
|
|
@@ -33,6 +40,7 @@ const valueFlags = new Set([
|
|
|
33
40
|
"memory-top-n",
|
|
34
41
|
"name",
|
|
35
42
|
"model",
|
|
43
|
+
"thinking-level",
|
|
36
44
|
"mode",
|
|
37
45
|
"output",
|
|
38
46
|
"path",
|
|
@@ -40,18 +48,20 @@ const valueFlags = new Set([
|
|
|
40
48
|
"permission",
|
|
41
49
|
"permission-mode",
|
|
42
50
|
"profile",
|
|
51
|
+
"prefix",
|
|
43
52
|
"project",
|
|
53
|
+
"publish",
|
|
44
54
|
"query",
|
|
45
55
|
"prompt",
|
|
46
56
|
"prompt-file",
|
|
47
57
|
"every",
|
|
48
58
|
"reason",
|
|
59
|
+
"request-id",
|
|
49
60
|
"release-tag",
|
|
50
61
|
"reaction-emoji",
|
|
51
62
|
"relay",
|
|
63
|
+
"route-decision",
|
|
52
64
|
"root",
|
|
53
|
-
"runtime-limit",
|
|
54
|
-
"runtime-session",
|
|
55
65
|
"shell",
|
|
56
66
|
"actions",
|
|
57
67
|
"ack-timeout",
|
|
@@ -65,16 +75,23 @@ const valueFlags = new Set([
|
|
|
65
75
|
"session",
|
|
66
76
|
"secret",
|
|
67
77
|
"since",
|
|
78
|
+
"slot",
|
|
79
|
+
"slot-secret",
|
|
68
80
|
"source",
|
|
81
|
+
"status",
|
|
82
|
+
"stream",
|
|
69
83
|
"stop-on",
|
|
84
|
+
"strategy",
|
|
70
85
|
"tail",
|
|
71
86
|
"tag",
|
|
72
87
|
"tags",
|
|
88
|
+
"task-id",
|
|
73
89
|
"text",
|
|
74
90
|
"text-file",
|
|
75
91
|
"timeout",
|
|
76
92
|
"timeout-ms",
|
|
77
93
|
"timezone",
|
|
94
|
+
"through",
|
|
78
95
|
"wait-timeout-ms",
|
|
79
96
|
"inactivity-timeout",
|
|
80
97
|
"runtime-timeout",
|
|
@@ -84,7 +101,9 @@ const valueFlags = new Set([
|
|
|
84
101
|
"title",
|
|
85
102
|
"url",
|
|
86
103
|
"turn",
|
|
104
|
+
"turn-id",
|
|
87
105
|
"until",
|
|
106
|
+
"import-token",
|
|
88
107
|
"reviewer-tag",
|
|
89
108
|
"dogfood-tag",
|
|
90
109
|
]);
|
|
@@ -107,11 +126,15 @@ const booleanFlags = new Set([
|
|
|
107
126
|
"no-open",
|
|
108
127
|
"no-start",
|
|
109
128
|
"no-wait",
|
|
129
|
+
"preserve-secret",
|
|
110
130
|
"repair-head",
|
|
131
|
+
"skip-local-daemon",
|
|
111
132
|
"strict",
|
|
112
133
|
"summary",
|
|
134
|
+
"subscribe",
|
|
113
135
|
"verbose",
|
|
114
136
|
"wait",
|
|
137
|
+
"decode",
|
|
115
138
|
"manual",
|
|
116
139
|
]);
|
|
117
140
|
const knownFlags = new Set([...valueFlags, ...booleanFlags]);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import path from "node:path";
|
|
1
2
|
import { CliError } from "../../errors.js";
|
|
2
|
-
import { startDaemonTimeoutMs } from "./paths.js";
|
|
3
|
+
import { configDir, startDaemonTimeoutMs } from "./paths.js";
|
|
3
4
|
import { readDaemonConfig } from "./config.js";
|
|
4
5
|
import { daemonBinaryUpdatedAfterStart, daemonConfigUpdatedAfterStart, localDaemonStatus, spawnDaemonStart, stopLocalDaemon } from "./local-daemon.js";
|
|
5
6
|
export async function ensureDaemonRunning(relayUrl, cwd = process.cwd()) {
|
|
@@ -19,9 +20,15 @@ export async function ensureDaemonRunning(relayUrl, cwd = process.cwd()) {
|
|
|
19
20
|
const local = await localDaemonStatus();
|
|
20
21
|
if (local.running)
|
|
21
22
|
return { local, started: true, startedPid };
|
|
23
|
+
try {
|
|
24
|
+
process.kill(startedPid, 0);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
throw new CliError(`Daemon exited before becoming locally ready. Startup output: ${path.join(configDir, "daemon.startup.log")}`, "DAEMON_START_FAILED");
|
|
28
|
+
}
|
|
22
29
|
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
23
30
|
}
|
|
24
|
-
throw new CliError(
|
|
31
|
+
throw new CliError(`Daemon did not become locally ready in time. Startup output: ${path.join(configDir, "daemon.startup.log")}`, "DAEMON_START_FAILED");
|
|
25
32
|
}
|
|
26
33
|
export async function restartDaemonForNewConfig(relayUrl, cwd = process.cwd()) {
|
|
27
34
|
const stopped = await stopLocalDaemon();
|
|
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { CliError } from "../../errors.js";
|
|
4
4
|
import { configDir, configPath } from "./paths.js";
|
|
5
|
+
const daemonProviderKinds = new Set(["mock", "codex", "claude", "pie"]);
|
|
5
6
|
export function requireString(flags, key) {
|
|
6
7
|
const value = flags[key];
|
|
7
8
|
if (typeof value !== "string" || !value.trim()) {
|
|
@@ -53,10 +54,41 @@ function assertControllerConfigShape(value) {
|
|
|
53
54
|
throw new CliError("Controller config is invalid.", "CONFIG_INVALID");
|
|
54
55
|
}
|
|
55
56
|
const candidate = value;
|
|
57
|
+
const previousRelayUrls = Array.isArray(candidate.previousRelayUrls)
|
|
58
|
+
? candidate.previousRelayUrls.filter((item) => typeof item === "string" && item.length > 0)
|
|
59
|
+
: undefined;
|
|
60
|
+
const relayMigration = parseRelayMigrationConfig(candidate.relayMigration);
|
|
56
61
|
return {
|
|
57
62
|
relayUrl: assertRelayUrl(assertStringField(candidate, "relayUrl", "Controller"), "Controller"),
|
|
58
63
|
controllerToken: assertStringField(candidate, "controllerToken", "Controller"),
|
|
59
64
|
accountSecret: assertStringField(candidate, "accountSecret", "Controller"),
|
|
65
|
+
...(previousRelayUrls && previousRelayUrls.length > 0 ? { previousRelayUrls } : {}),
|
|
66
|
+
...(relayMigration ? { relayMigration } : {}),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function parseRelayMigrationConfig(value) {
|
|
70
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
71
|
+
return undefined;
|
|
72
|
+
const candidate = value;
|
|
73
|
+
const migrationId = candidate.migrationId;
|
|
74
|
+
const state = candidate.state;
|
|
75
|
+
const fromRelayUrl = candidate.fromRelayUrl;
|
|
76
|
+
const toRelayUrl = candidate.toRelayUrl;
|
|
77
|
+
const updatedAt = candidate.updatedAt;
|
|
78
|
+
if (typeof migrationId !== "string" ||
|
|
79
|
+
typeof state !== "string" ||
|
|
80
|
+
!["rebound", "migrated", "draining", "drained", "cutover"].includes(state) ||
|
|
81
|
+
typeof fromRelayUrl !== "string" ||
|
|
82
|
+
typeof toRelayUrl !== "string" ||
|
|
83
|
+
typeof updatedAt !== "string") {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
migrationId,
|
|
88
|
+
state: state,
|
|
89
|
+
fromRelayUrl,
|
|
90
|
+
toRelayUrl,
|
|
91
|
+
updatedAt,
|
|
60
92
|
};
|
|
61
93
|
}
|
|
62
94
|
function assertDaemonConfigShape(value) {
|
|
@@ -72,6 +104,7 @@ function assertDaemonConfigShape(value) {
|
|
|
72
104
|
runtimeEnv[key] = runtimeValue;
|
|
73
105
|
}
|
|
74
106
|
}
|
|
107
|
+
const providers = parseProviders(candidate.providers);
|
|
75
108
|
return {
|
|
76
109
|
relayUrl: assertRelayUrl(assertStringField(candidate, "relayUrl", "Daemon"), "Daemon"),
|
|
77
110
|
accountId: assertStringField(candidate, "accountId", "Daemon"),
|
|
@@ -79,9 +112,26 @@ function assertDaemonConfigShape(value) {
|
|
|
79
112
|
machineName: assertStringField(candidate, "machineName", "Daemon"),
|
|
80
113
|
machineToken: assertStringField(candidate, "machineToken", "Daemon"),
|
|
81
114
|
accountSecret: assertStringField(candidate, "accountSecret", "Daemon"),
|
|
115
|
+
...(providers ? { providers } : {}),
|
|
82
116
|
...(Object.keys(runtimeEnv).length > 0 ? { runtimeEnv } : {}),
|
|
83
117
|
};
|
|
84
118
|
}
|
|
119
|
+
function parseProviders(value) {
|
|
120
|
+
if (value === undefined)
|
|
121
|
+
return undefined;
|
|
122
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
123
|
+
throw new CliError("Daemon config providers must be a non-empty array.", "CONFIG_INVALID");
|
|
124
|
+
}
|
|
125
|
+
const providers = [];
|
|
126
|
+
for (const item of value) {
|
|
127
|
+
if (typeof item !== "string" || !daemonProviderKinds.has(item)) {
|
|
128
|
+
throw new CliError("Daemon config providers must contain only mock, codex, claude, or pie.", "CONFIG_INVALID");
|
|
129
|
+
}
|
|
130
|
+
if (!providers.includes(item))
|
|
131
|
+
providers.push(item);
|
|
132
|
+
}
|
|
133
|
+
return providers;
|
|
134
|
+
}
|
|
85
135
|
async function readJsonConfigFile(filePath, label) {
|
|
86
136
|
try {
|
|
87
137
|
return JSON.parse(stripJsonBom(await fs.readFile(filePath, "utf8")));
|
|
@@ -108,6 +158,7 @@ export async function readConfig(flags) {
|
|
|
108
158
|
}
|
|
109
159
|
const stored = assertControllerConfigShape(await readJsonConfigFile(configPath, "Controller"));
|
|
110
160
|
return {
|
|
161
|
+
...stored,
|
|
111
162
|
relayUrl: assertRelayUrl(relayUrl ?? stored.relayUrl, "Controller"),
|
|
112
163
|
controllerToken: controllerToken ?? stored.controllerToken,
|
|
113
164
|
accountSecret: accountSecret ?? stored.accountSecret,
|
|
@@ -129,6 +180,7 @@ export function redactedDaemonConfig(config) {
|
|
|
129
180
|
accountId: config.accountId,
|
|
130
181
|
machineId: config.machineId,
|
|
131
182
|
machineName: config.machineName,
|
|
183
|
+
...(config.providers && config.providers.length > 0 ? { providers: config.providers } : {}),
|
|
132
184
|
hasMachineToken: Boolean(config.machineToken),
|
|
133
185
|
hasAccountSecret: Boolean(config.accountSecret),
|
|
134
186
|
...(config.runtimeEnv ? { runtimeEnv: Object.fromEntries(Object.keys(config.runtimeEnv).map((key) => [key, true])) } : {}),
|
|
@@ -16,6 +16,7 @@ export * from "./local-daemon.js";
|
|
|
16
16
|
export * from "./loop-store.js";
|
|
17
17
|
export * from "./paths.js";
|
|
18
18
|
export * from "./relay-db-audit.js";
|
|
19
|
+
export * from "./relay-debug.js";
|
|
19
20
|
export * from "./relay-http.js";
|
|
20
21
|
export * from "./scope.js";
|
|
21
22
|
export * from "./session-output.js";
|
|
@@ -16,6 +16,7 @@ export * from "./local-daemon.js";
|
|
|
16
16
|
export * from "./loop-store.js";
|
|
17
17
|
export * from "./paths.js";
|
|
18
18
|
export * from "./relay-db-audit.js";
|
|
19
|
+
export * from "./relay-debug.js";
|
|
19
20
|
export * from "./relay-http.js";
|
|
20
21
|
export * from "./scope.js";
|
|
21
22
|
export * from "./session-output.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { execFileSync, spawn } from "node:child_process";
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
|
+
import { appendFileSync, closeSync, mkdirSync, openSync } from "node:fs";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { configDir, daemonPidPath } from "./paths.js";
|
|
5
6
|
function daemonCliPath() {
|
|
@@ -117,15 +118,30 @@ export async function daemonConfigUpdatedAfterStart(status) {
|
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
120
|
export function spawnDaemonStart(args, cwd = process.cwd()) {
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
121
|
+
const logPath = path.join(configDir, "daemon.startup.log");
|
|
122
|
+
mkdirSync(configDir, { recursive: true });
|
|
123
|
+
const logFd = openSync(logPath, "a", 0o600);
|
|
124
|
+
try {
|
|
125
|
+
appendFileSync(logFd, `\n[${new Date().toISOString()}] Starting daemon (${process.version})\n`);
|
|
126
|
+
const child = spawn(process.execPath, [daemonCliPath(), "start", ...args], {
|
|
127
|
+
cwd,
|
|
128
|
+
env: { ...process.env, HAPPY_ELVES_HOME: configDir },
|
|
129
|
+
detached: true,
|
|
130
|
+
stdio: ["ignore", logFd, logFd],
|
|
131
|
+
windowsHide: true,
|
|
132
|
+
});
|
|
133
|
+
child.once("error", (error) => {
|
|
134
|
+
try {
|
|
135
|
+
appendFileSync(logPath, `Daemon spawn failed: ${error.message}\n`);
|
|
136
|
+
}
|
|
137
|
+
catch { /* Parent still reports a failed start. */ }
|
|
138
|
+
});
|
|
139
|
+
child.unref();
|
|
140
|
+
return child.pid ?? 0;
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
closeSync(logFd);
|
|
144
|
+
}
|
|
129
145
|
}
|
|
130
146
|
export async function stopLocalDaemon(timeoutMs = 5000) {
|
|
131
147
|
const status = await localDaemonStatus();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
+
import { RecoverableFileLockError, withRecoverableFileLock } from "../../../../../packages/shared/dist/file-lock.js";
|
|
2
3
|
import { CliError } from "../../errors.js";
|
|
3
4
|
import { configDir, loopStoreLockPath, loopStorePath } from "./paths.js";
|
|
4
5
|
function emptyLoopStore() {
|
|
@@ -28,24 +29,14 @@ async function writeLoopStore(store) {
|
|
|
28
29
|
}
|
|
29
30
|
async function withLoopStoreLock(operation) {
|
|
30
31
|
await fs.mkdir(configDir, { recursive: true });
|
|
31
|
-
const deadline = Date.now() + 5000;
|
|
32
|
-
let handle;
|
|
33
|
-
while (!handle) {
|
|
34
|
-
try {
|
|
35
|
-
handle = await fs.open(loopStoreLockPath, "wx", 0o600);
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
if (error.code !== "EEXIST" || Date.now() > deadline)
|
|
39
|
-
throw error;
|
|
40
|
-
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
await handle.close();
|
|
44
32
|
try {
|
|
45
|
-
return await operation
|
|
33
|
+
return await withRecoverableFileLock({ lockPath: loopStoreLockPath, label: "happy-elves loop store" }, operation);
|
|
46
34
|
}
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (error instanceof RecoverableFileLockError) {
|
|
37
|
+
throw new CliError(error.message, error.code);
|
|
38
|
+
}
|
|
39
|
+
throw error;
|
|
49
40
|
}
|
|
50
41
|
}
|
|
51
42
|
export function parseStopOn(value) {
|