botmux 3.0.0 → 3.1.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/dist/adapters/backend/herdr-backend.d.ts +9 -7
- package/dist/adapters/backend/herdr-backend.d.ts.map +1 -1
- package/dist/adapters/backend/herdr-backend.js +63 -53
- package/dist/adapters/backend/herdr-backend.js.map +1 -1
- package/dist/adapters/backend/riff-backend.d.ts +6 -1
- package/dist/adapters/backend/riff-backend.d.ts.map +1 -1
- package/dist/adapters/backend/riff-backend.js +7 -2
- package/dist/adapters/backend/riff-backend.js.map +1 -1
- package/dist/adapters/backend/sandbox.d.ts +20 -16
- package/dist/adapters/backend/sandbox.d.ts.map +1 -1
- package/dist/adapters/backend/sandbox.js +193 -68
- package/dist/adapters/backend/sandbox.js.map +1 -1
- package/dist/adapters/backend/tmux-backend.d.ts +39 -2
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-backend.js +66 -6
- package/dist/adapters/backend/tmux-backend.js.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.js +2 -2
- package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
- package/dist/adapters/backend/zellij-backend.d.ts.map +1 -1
- package/dist/adapters/backend/zellij-backend.js +9 -3
- package/dist/adapters/backend/zellij-backend.js.map +1 -1
- package/dist/adapters/cli/claude-code.d.ts +25 -0
- package/dist/adapters/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +79 -9
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/adapters/cli/read-isolation.d.ts +2 -1
- package/dist/adapters/cli/read-isolation.d.ts.map +1 -1
- package/dist/adapters/cli/read-isolation.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +2 -2
- package/dist/adapters/hook-installer.d.ts +11 -0
- package/dist/adapters/hook-installer.d.ts.map +1 -1
- package/dist/adapters/hook-installer.js +72 -11
- package/dist/adapters/hook-installer.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +15 -4
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -0
- package/dist/config.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +354 -143
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +12 -5
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dashboard-rows.d.ts +5 -0
- package/dist/core/dashboard-rows.d.ts.map +1 -1
- package/dist/core/dashboard-rows.js +2 -0
- package/dist/core/dashboard-rows.js.map +1 -1
- package/dist/core/doc-comment-prompt.d.ts +2 -0
- package/dist/core/doc-comment-prompt.d.ts.map +1 -1
- package/dist/core/doc-comment-prompt.js +30 -0
- package/dist/core/doc-comment-prompt.js.map +1 -1
- package/dist/core/github-auth.d.ts +8 -0
- package/dist/core/github-auth.d.ts.map +1 -0
- package/dist/core/github-auth.js +44 -0
- package/dist/core/github-auth.js.map +1 -0
- package/dist/core/managed-origin-capability.d.ts +7 -0
- package/dist/core/managed-origin-capability.d.ts.map +1 -1
- package/dist/core/managed-origin-capability.js +12 -0
- package/dist/core/managed-origin-capability.js.map +1 -1
- package/dist/core/passthrough-commands.d.ts.map +1 -1
- package/dist/core/passthrough-commands.js +1 -1
- package/dist/core/passthrough-commands.js.map +1 -1
- package/dist/core/restart-report.d.ts +7 -1
- package/dist/core/restart-report.d.ts.map +1 -1
- package/dist/core/restart-report.js +19 -5
- package/dist/core/restart-report.js.map +1 -1
- package/dist/core/session-activity.d.ts +8 -0
- package/dist/core/session-activity.d.ts.map +1 -1
- package/dist/core/session-activity.js +16 -0
- package/dist/core/session-activity.js.map +1 -1
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +4 -2
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-marker.d.ts.map +1 -1
- package/dist/core/session-marker.js +5 -2
- package/dist/core/session-marker.js.map +1 -1
- package/dist/core/types.d.ts +48 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +55 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/update-check.d.ts +11 -0
- package/dist/core/update-check.d.ts.map +1 -1
- package/dist/core/update-check.js +6 -1
- package/dist/core/update-check.js.map +1 -1
- package/dist/core/vc-meeting-prepare-command.d.ts +22 -0
- package/dist/core/vc-meeting-prepare-command.d.ts.map +1 -0
- package/dist/core/vc-meeting-prepare-command.js +50 -0
- package/dist/core/vc-meeting-prepare-command.js.map +1 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +21 -10
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts +15 -5
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +645 -50
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.js +6 -1
- package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +34 -0
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/preferences.d.ts +1 -1
- package/dist/dashboard/web/preferences.d.ts.map +1 -1
- package/dist/dashboard/web/preferences.js +1 -1
- package/dist/dashboard/web/preferences.js.map +1 -1
- package/dist/dashboard/web/sessions-page.d.ts +19 -0
- package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
- package/dist/dashboard/web/sessions-page.js +66 -7
- package/dist/dashboard/web/sessions-page.js.map +1 -1
- package/dist/dashboard/web/sessions.d.ts +31 -0
- package/dist/dashboard/web/sessions.d.ts.map +1 -1
- package/dist/dashboard/web/sessions.js +82 -0
- package/dist/dashboard/web/sessions.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/{bot-defaults-page-MBORWWP7.js → bot-defaults-page-KLDCZNLP.js} +5 -5
- package/dist/dashboard-web/chunks/{chunk-G43RUPUN.js → chunk-EZAW2EPM.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-EIO5AWDA.js → chunk-FMJNOATE.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-4QTBR7UF.js → chunk-KEAOTUL3.js} +7 -7
- package/dist/dashboard-web/chunks/{chunk-7STGZ5BX.js → chunk-MLNI5BKE.js} +1 -1
- package/dist/dashboard-web/chunks/{connectors-page-LKDT4WBG.js → connectors-page-O32LFAL5.js} +1 -1
- package/dist/dashboard-web/chunks/{groups-page-XKIWJ2TP.js → groups-page-PSAFIZ6M.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-CBEZCYKV.js → insights-page-V23LLATX.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-AQTHAWXA.js → monitor-room-7X5AKYOF.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-2R4NCNBQ.js → monitoring-page-CBA3CQYL.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-5M6MQIIL.js → office-page-RL6QSEM7.js} +1 -1
- package/dist/dashboard-web/chunks/{overview-page-N22HDZ2V.js → overview-page-XQIPO6KH.js} +1 -1
- package/dist/dashboard-web/chunks/{roles-page-J6K2HWFX.js → roles-page-ACIWV7QS.js} +1 -1
- package/dist/dashboard-web/chunks/{schedules-page-CGAQCB4J.js → schedules-page-KJDUKOJV.js} +1 -1
- package/dist/dashboard-web/chunks/sessions-page-2WDWHSP4.js +3 -0
- package/dist/dashboard-web/chunks/{settings-page-GLRWV5KU.js → settings-page-6VX4OUGG.js} +1 -1
- package/dist/dashboard-web/chunks/{skills-page-KQVW42QU.js → skills-page-WXE3UYLT.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-5PYUOV5M.js → team-federation-page-PYTF4FLM.js} +1 -1
- package/dist/dashboard-web/chunks/{v3-page-DXPFILRZ.js → v3-page-G6CD6O3I.js} +1 -1
- package/dist/dashboard-web/chunks/{whiteboards-page-NUH6VZ4I.js → whiteboards-page-6SG33GP4.js} +1 -1
- package/dist/dashboard-web/style.css +167 -2
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +19 -3
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +19 -3
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +11 -2
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts +2 -0
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +219 -139
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +4 -0
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +249 -5
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/forward-followup-buffer.d.ts +26 -0
- package/dist/im/lark/forward-followup-buffer.d.ts.map +1 -0
- package/dist/im/lark/forward-followup-buffer.js +48 -0
- package/dist/im/lark/forward-followup-buffer.js.map +1 -0
- package/dist/im/lark/forward-followup-content.d.ts +6 -0
- package/dist/im/lark/forward-followup-content.d.ts.map +1 -0
- package/dist/im/lark/forward-followup-content.js +46 -0
- package/dist/im/lark/forward-followup-content.js.map +1 -0
- package/dist/im/lark/forward-followup-store.d.ts +9 -0
- package/dist/im/lark/forward-followup-store.d.ts.map +1 -0
- package/dist/im/lark/forward-followup-store.js +48 -0
- package/dist/im/lark/forward-followup-store.js.map +1 -0
- package/dist/im/lark/message-parser.d.ts +1 -1
- package/dist/im/lark/message-parser.d.ts.map +1 -1
- package/dist/im/lark/message-parser.js +1 -2
- package/dist/im/lark/message-parser.js.map +1 -1
- package/dist/platform/tunnel-client.js +3 -3
- package/dist/platform/tunnel-client.js.map +1 -1
- package/dist/services/local-cli-opener.d.ts +7 -0
- package/dist/services/local-cli-opener.d.ts.map +1 -1
- package/dist/services/local-cli-opener.js +111 -3
- package/dist/services/local-cli-opener.js.map +1 -1
- package/dist/services/skill-registry-store.d.ts.map +1 -1
- package/dist/services/skill-registry-store.js +15 -2
- package/dist/services/skill-registry-store.js.map +1 -1
- package/dist/services/vc-meeting-consumer-isolation.d.ts +7 -5
- package/dist/services/vc-meeting-consumer-isolation.d.ts.map +1 -1
- package/dist/services/vc-meeting-consumer-isolation.js +7 -5
- package/dist/services/vc-meeting-consumer-isolation.js.map +1 -1
- package/dist/services/vc-meeting-preparations-store.d.ts +22 -0
- package/dist/services/vc-meeting-preparations-store.d.ts.map +1 -0
- package/dist/services/vc-meeting-preparations-store.js +131 -0
- package/dist/services/vc-meeting-preparations-store.js.map +1 -0
- package/dist/services/vc-meeting-runtime-store.d.ts +9 -0
- package/dist/services/vc-meeting-runtime-store.d.ts.map +1 -1
- package/dist/services/vc-meeting-runtime-store.js +16 -0
- package/dist/services/vc-meeting-runtime-store.js.map +1 -1
- package/dist/setup/ensure-tmux.d.ts.map +1 -1
- package/dist/setup/ensure-tmux.js +9 -11
- package/dist/setup/ensure-tmux.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/child-env.d.ts +24 -8
- package/dist/utils/child-env.d.ts.map +1 -1
- package/dist/utils/child-env.js +49 -8
- package/dist/utils/child-env.js.map +1 -1
- package/dist/utils/daemon-discovery.d.ts +8 -0
- package/dist/utils/daemon-discovery.d.ts.map +1 -1
- package/dist/utils/daemon-discovery.js +19 -0
- package/dist/utils/daemon-discovery.js.map +1 -1
- package/dist/utils/ready-gate.d.ts +9 -3
- package/dist/utils/ready-gate.d.ts.map +1 -1
- package/dist/utils/ready-gate.js +12 -4
- package/dist/utils/ready-gate.js.map +1 -1
- package/dist/worker.js +141 -29
- package/dist/worker.js.map +1 -1
- package/dist/workflows/ops-projection.d.ts.map +1 -1
- package/dist/workflows/ops-projection.js +27 -5
- package/dist/workflows/ops-projection.js.map +1 -1
- package/dist/workflows/v3/distillation-runner.d.ts +4 -0
- package/dist/workflows/v3/distillation-runner.d.ts.map +1 -1
- package/dist/workflows/v3/distillation-runner.js +4 -2
- package/dist/workflows/v3/distillation-runner.js.map +1 -1
- package/package.json +1 -1
- package/dist/dashboard-web/chunks/sessions-page-WJ2QYTIE.js +0 -3
|
@@ -34,11 +34,16 @@
|
|
|
34
34
|
/**
|
|
35
35
|
* Decide whether the worker should ARM the ready-gate for a given spawn. The
|
|
36
36
|
* gate is only valid when a SessionStart hook will actually fire — i.e. a FRESH
|
|
37
|
-
*
|
|
37
|
+
* ready-gated spawn whose hook/transport preflight succeeded:
|
|
38
38
|
*
|
|
39
39
|
* - `injectsReadyHook` — the adapter injects the hook (claude / seed).
|
|
40
|
+
* - `readySignalAvailable` — the effective config contains the hook (or the
|
|
41
|
+
* CLI has a direct ready-command integration),
|
|
42
|
+
* and an isolated child has a usable callback
|
|
43
|
+
* route to the daemon.
|
|
40
44
|
* - NOT `adoptMode` — adopt panes are pre-existing, never spawned with
|
|
41
|
-
* our
|
|
45
|
+
* our ready integration, so they can't get a
|
|
46
|
+
* fresh SessionStart signal.
|
|
42
47
|
* - NOT `willReattachPersistent` — on daemon restart / worker recovery the
|
|
43
48
|
* worker re-attaches to an existing tmux/zellij/
|
|
44
49
|
* herdr session and does NOT re-run the CLI's
|
|
@@ -51,13 +56,14 @@
|
|
|
51
56
|
* exactly as before (readyPattern + quiescence).
|
|
52
57
|
*
|
|
53
58
|
* NB: `wrapperCli=aiden x claude` strips our process-level `--settings`, but the
|
|
54
|
-
* SessionStart hook is
|
|
59
|
+
* SessionStart hook is installed in the effective settings.json (see
|
|
55
60
|
* claude-code.ts hookInstall.sessionStartCommand), which aiden's Claude still
|
|
56
61
|
* reads. So the real signal fires there too → we KEEP arming for that case
|
|
57
62
|
* (no readyPattern fallback, which could misjudge).
|
|
58
63
|
*/
|
|
59
64
|
export declare function shouldArmReadyGate(state: {
|
|
60
65
|
injectsReadyHook: boolean;
|
|
66
|
+
readySignalAvailable: boolean;
|
|
61
67
|
adoptMode: boolean;
|
|
62
68
|
willReattachPersistent: boolean;
|
|
63
69
|
}): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ready-gate.d.ts","sourceRoot":"","sources":["../../src/utils/ready-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH
|
|
1
|
+
{"version":3,"file":"ready-gate.d.ts","sourceRoot":"","sources":["../../src/utils/ready-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,sBAAsB,EAAE,OAAO,CAAC;CACjC,GAAG,OAAO,CAKV;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IAEzB,oFAAoF;IACpF,GAAG,IAAI,IAAI;IAIX,qFAAqF;IACrF,UAAU,IAAI,OAAO;IAIrB;;;;;;OAMG;IACH,OAAO,IAAI,OAAO;IAOlB,qEAAqE;IACrE,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,gEAAgE;IAChE,IAAI,UAAU,IAAI,OAAO,CAExB;CACF"}
|
package/dist/utils/ready-gate.js
CHANGED
|
@@ -34,11 +34,16 @@
|
|
|
34
34
|
/**
|
|
35
35
|
* Decide whether the worker should ARM the ready-gate for a given spawn. The
|
|
36
36
|
* gate is only valid when a SessionStart hook will actually fire — i.e. a FRESH
|
|
37
|
-
*
|
|
37
|
+
* ready-gated spawn whose hook/transport preflight succeeded:
|
|
38
38
|
*
|
|
39
39
|
* - `injectsReadyHook` — the adapter injects the hook (claude / seed).
|
|
40
|
+
* - `readySignalAvailable` — the effective config contains the hook (or the
|
|
41
|
+
* CLI has a direct ready-command integration),
|
|
42
|
+
* and an isolated child has a usable callback
|
|
43
|
+
* route to the daemon.
|
|
40
44
|
* - NOT `adoptMode` — adopt panes are pre-existing, never spawned with
|
|
41
|
-
* our
|
|
45
|
+
* our ready integration, so they can't get a
|
|
46
|
+
* fresh SessionStart signal.
|
|
42
47
|
* - NOT `willReattachPersistent` — on daemon restart / worker recovery the
|
|
43
48
|
* worker re-attaches to an existing tmux/zellij/
|
|
44
49
|
* herdr session and does NOT re-run the CLI's
|
|
@@ -51,13 +56,16 @@
|
|
|
51
56
|
* exactly as before (readyPattern + quiescence).
|
|
52
57
|
*
|
|
53
58
|
* NB: `wrapperCli=aiden x claude` strips our process-level `--settings`, but the
|
|
54
|
-
* SessionStart hook is
|
|
59
|
+
* SessionStart hook is installed in the effective settings.json (see
|
|
55
60
|
* claude-code.ts hookInstall.sessionStartCommand), which aiden's Claude still
|
|
56
61
|
* reads. So the real signal fires there too → we KEEP arming for that case
|
|
57
62
|
* (no readyPattern fallback, which could misjudge).
|
|
58
63
|
*/
|
|
59
64
|
export function shouldArmReadyGate(state) {
|
|
60
|
-
return state.injectsReadyHook
|
|
65
|
+
return state.injectsReadyHook
|
|
66
|
+
&& state.readySignalAvailable
|
|
67
|
+
&& !state.adoptMode
|
|
68
|
+
&& !state.willReattachPersistent;
|
|
61
69
|
}
|
|
62
70
|
export class ReadyGate {
|
|
63
71
|
armed = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ready-gate.js","sourceRoot":"","sources":["../../src/utils/ready-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH
|
|
1
|
+
{"version":3,"file":"ready-gate.js","sourceRoot":"","sources":["../../src/utils/ready-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAKlC;IACC,OAAO,KAAK,CAAC,gBAAgB;WACxB,KAAK,CAAC,oBAAoB;WAC1B,CAAC,KAAK,CAAC,SAAS;WAChB,CAAC,KAAK,CAAC,sBAAsB,CAAC;AACrC,CAAC;AAED,MAAM,OAAO,SAAS;IACZ,KAAK,GAAG,KAAK,CAAC;IACd,QAAQ,GAAG,KAAK,CAAC;IAEzB,oFAAoF;IACpF,GAAG;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,qFAAqF;IACrF,UAAU;QACR,OAAO,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;IACtC,CAAC;IAED;;;;;;OAMG;IACH,OAAO;QACL,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,qEAAqE;IACrE,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,gEAAgE;IAChE,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF"}
|
package/dist/worker.js
CHANGED
|
@@ -72,7 +72,7 @@ import { createCliAdapterSync, locateOnPath } from './adapters/cli/registry.js';
|
|
|
72
72
|
import { buildWrappedLaunch, parseWrapperCli, isTtadkWrapper } from './setup/cli-selection.js';
|
|
73
73
|
import { cliUnavailableMessage } from './setup/cli-availability.js';
|
|
74
74
|
import { findLaunchedCliPid, scheduleWrapperRealCliPid, readComm, isBareShellComm, bareShellLaunchKind } from './core/session-discovery.js';
|
|
75
|
-
import { claudeJsonlPathForSession, resolveJsonlFromPid, findOpenClaudeSessionIds, DEFAULT_CLAUDE_DATA_DIR } from './adapters/cli/claude-code.js';
|
|
75
|
+
import { claudeJsonlPathForSession, resolveJsonlFromPid, findOpenClaudeSessionIds, syncClaudeResumeTargetToCwd, DEFAULT_CLAUDE_DATA_DIR } from './adapters/cli/claude-code.js';
|
|
76
76
|
import { sessionReadyHookCommand } from './adapters/hook-command.js';
|
|
77
77
|
import { mtrSessionIdForBotmuxSession } from './adapters/cli/mtr.js';
|
|
78
78
|
import { HerdrBackend } from './adapters/backend/herdr-backend.js';
|
|
@@ -83,7 +83,7 @@ import { ZellijObserveBackend } from './adapters/backend/zellij-observe-backend.
|
|
|
83
83
|
import { zellijEnv } from './setup/ensure-zellij.js';
|
|
84
84
|
import { isObserveBackend } from './adapters/backend/types.js';
|
|
85
85
|
import { selectSessionBackend, decideBackendGate, backendGateUserMessage } from './adapters/backend/session-backend-selector.js';
|
|
86
|
-
import { deriveRiffReposFromDirs, deriveRiffRepoFromWorkingDir, isValidRiffBaseUrl } from './adapters/backend/riff-backend.js';
|
|
86
|
+
import { deriveRiffReposFromDirs, deriveRiffRepoFromWorkingDir, isValidRiffBaseUrl, isValidRiffSandboxCluster, } from './adapters/backend/riff-backend.js';
|
|
87
87
|
import { prepareSandbox, attachSandboxOutbox, startOutboxWatcher, sandboxEnabled, sandboxedClaudeDataDir, localSandboxApplies } from './adapters/backend/sandbox.js';
|
|
88
88
|
import { tmuxEnv, probeTmuxFunctionalWithRetry } from './setup/ensure-tmux.js';
|
|
89
89
|
import { tmuxRestartJitterMs } from './core/tmux-recovery.js';
|
|
@@ -102,12 +102,13 @@ import { config, resolveChatBotDiscoveryConfig } from './config.js';
|
|
|
102
102
|
import * as sessionStore from './services/session-store.js';
|
|
103
103
|
import * as pty from 'node-pty';
|
|
104
104
|
import { createHash } from 'node:crypto';
|
|
105
|
-
import { installHook } from './adapters/hook-installer.js';
|
|
105
|
+
import { hasInstalledSessionReadyHook, installHook, } from './adapters/hook-installer.js';
|
|
106
106
|
import { hookCommandFor } from './adapters/hook-command.js';
|
|
107
|
+
import { parseDaemonIpcPort } from './utils/daemon-discovery.js';
|
|
107
108
|
import { withCodexAppContext } from './utils/codex-app-context.js';
|
|
108
109
|
import { resolveCodexAppFinalTurnIdentity } from './adapters/cli/codex-app-turn.js';
|
|
109
110
|
import { RunnerControlDecoder } from './adapters/cli/runner-control-channel.js';
|
|
110
|
-
import { managedOriginCapabilityPath, RELAY_ORIGIN_CAPABILITY_BASENAME, replaceManagedOriginCapabilityFile, } from './core/managed-origin-capability.js';
|
|
111
|
+
import { hasMatchingManagedOriginCapability, managedOriginCapabilityPath, RELAY_ORIGIN_CAPABILITY_BASENAME, replaceManagedOriginCapabilityFile, } from './core/managed-origin-capability.js';
|
|
111
112
|
// ─── State ───────────────────────────────────────────────────────────────────
|
|
112
113
|
let cliAdapter = null;
|
|
113
114
|
let backend = null;
|
|
@@ -186,6 +187,24 @@ function provisionIsolatedBotHome(botHome, workingDir, isClaude, cliId, hookInst
|
|
|
186
187
|
if (isClaude) {
|
|
187
188
|
const cdir = join(botHome, 'claude');
|
|
188
189
|
mkdirSync(cdir, { recursive: true });
|
|
190
|
+
// Settings: read-isolated Claude uses a fresh CLAUDE_CONFIG_DIR, so it
|
|
191
|
+
// otherwise loses provider auth/model/proxy values held in the shared
|
|
192
|
+
// ~/.claude/settings.json `env` map. Merge that map on EVERY cold spawn,
|
|
193
|
+
// then install botmux hooks into the same per-bot file. Global hooks and
|
|
194
|
+
// unrelated top-level settings are not inherited.
|
|
195
|
+
const isolatedSettingsPath = join(cdir, 'settings.json');
|
|
196
|
+
if (hookInstall) {
|
|
197
|
+
try {
|
|
198
|
+
installHook(cliId, {
|
|
199
|
+
...hookInstall,
|
|
200
|
+
configPath: isolatedSettingsPath,
|
|
201
|
+
inheritClaudeEnvFrom: join(homedir(), '.claude', 'settings.json'),
|
|
202
|
+
}, hookCommandFor(cliId));
|
|
203
|
+
}
|
|
204
|
+
catch (e) {
|
|
205
|
+
log(`[read-isolation] WARN per-bot settings/hook install failed: ${e.message}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
189
208
|
// Auth: a fresh CLAUDE_CONFIG_DIR does NOT inherit the shared account's OAuth
|
|
190
209
|
// token → keep <cdir>/.credentials.json synced to the FRESHEST valid credential
|
|
191
210
|
// on EVERY spawn (verified: Claude logs in from that file). Refreshing here (not
|
|
@@ -194,24 +213,14 @@ function provisionIsolatedBotHome(botHome, workingDir, isClaude, cliId, hookInst
|
|
|
194
213
|
const fresh = freshestClaudeCred();
|
|
195
214
|
if (fresh)
|
|
196
215
|
writeCredIfChanged(join(cdir, '.credentials.json'), fresh);
|
|
197
|
-
else if (!existsSync(join(cdir, '.credentials.json'))
|
|
198
|
-
|
|
216
|
+
else if (!existsSync(join(cdir, '.credentials.json'))
|
|
217
|
+
&& !claudeSettingsHasProviderAuth(isolatedSettingsPath)) {
|
|
218
|
+
log(`[read-isolation] WARN no Claude provider auth found (global settings env, keychain, or ~/.claude/.credentials.json) — bot may hit login screen`);
|
|
199
219
|
}
|
|
200
220
|
// State: seed <cdir>/.claude.json from the GLOBAL one MINUS `projects` (keeps the
|
|
201
221
|
// onboarding/promo "seen" flags + account so no dialogs appear, without leaking
|
|
202
222
|
// other projects' data), then trust this bot's cwd. Merge-safe on resume.
|
|
203
223
|
seedAndTrustClaudeState(join(cdir, '.claude.json'), workingDir, log);
|
|
204
|
-
// Hooks: install the SessionStart-ready + askUserQuestion hooks into the PER-BOT
|
|
205
|
-
// settings.json (global ~/.claude/settings.json is Seatbelt-denied), else the
|
|
206
|
-
// worker's ready gate falls back to a slow timeout and AskUserQuestion won't relay.
|
|
207
|
-
if (hookInstall) {
|
|
208
|
-
try {
|
|
209
|
-
installHook(cliId, { ...hookInstall, configPath: join(cdir, 'settings.json') }, hookCommandFor(cliId));
|
|
210
|
-
}
|
|
211
|
-
catch (e) {
|
|
212
|
-
log(`[read-isolation] WARN per-bot hook install failed: ${e.message}`);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
224
|
}
|
|
216
225
|
else {
|
|
217
226
|
const cdir = join(botHome, 'codex');
|
|
@@ -232,6 +241,22 @@ function provisionIsolatedBotHome(botHome, workingDir, isClaude, cliId, hookInst
|
|
|
232
241
|
log(`[read-isolation] WARN provisioning bot home failed: ${e.message}`);
|
|
233
242
|
}
|
|
234
243
|
}
|
|
244
|
+
function claudeSettingsHasProviderAuth(settingsPath) {
|
|
245
|
+
try {
|
|
246
|
+
const settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
|
|
247
|
+
const env = settings.env;
|
|
248
|
+
if (!env || typeof env !== 'object' || Array.isArray(env))
|
|
249
|
+
return false;
|
|
250
|
+
const record = env;
|
|
251
|
+
return ((typeof record.ANTHROPIC_AUTH_TOKEN === 'string' && record.ANTHROPIC_AUTH_TOKEN.length > 0)
|
|
252
|
+
|| (typeof record.ANTHROPIC_API_KEY === 'string' && record.ANTHROPIC_API_KEY.length > 0)
|
|
253
|
+
|| record.CLAUDE_CODE_USE_BEDROCK === '1'
|
|
254
|
+
|| record.CLAUDE_CODE_USE_VERTEX === '1');
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
235
260
|
/** Pick the FRESHEST valid Claude OAuth credential: macOS keychain vs the global
|
|
236
261
|
* `~/.claude/.credentials.json`, by `claudeAiOauth.expiresAt` (longest runway
|
|
237
262
|
* wins — a re-login updates one of the two, and this picks whichever is newer).
|
|
@@ -724,6 +749,15 @@ async function deliverRawInput(msg) {
|
|
|
724
749
|
const targetBackend = backend;
|
|
725
750
|
if (!targetBackend)
|
|
726
751
|
return;
|
|
752
|
+
// A passthrough is still an accepted input boundary. Rotate (or revoke) the
|
|
753
|
+
// marker immediately before the literal command reaches the CLI so it can
|
|
754
|
+
// never inherit a previous human turn. System-generated raw commands omit
|
|
755
|
+
// turnId and therefore publish an explicitly unattributed marker.
|
|
756
|
+
currentBotmuxTurnId = msg.turnId;
|
|
757
|
+
currentBotmuxDispatchAttempt = undefined;
|
|
758
|
+
currentVcMeetingImTurnOrigin = undefined;
|
|
759
|
+
writeCliPidMarker();
|
|
760
|
+
publishSandboxRelayCapability();
|
|
727
761
|
let sent = false;
|
|
728
762
|
try {
|
|
729
763
|
await sendRawCommandLineSerially(targetBackend, msg.content);
|
|
@@ -741,7 +775,7 @@ async function deliverRawInput(msg) {
|
|
|
741
775
|
// Enter lands. sendToPty also observes commandLineWritesPending, so another
|
|
742
776
|
// raw command's text -> Enter window cannot be interrupted by the follow-up.
|
|
743
777
|
if (sent && msg.followUpContent) {
|
|
744
|
-
sendToPty(msg.followUpContent,
|
|
778
|
+
sendToPty(msg.followUpContent, msg.followUpTurnId, {
|
|
745
779
|
codexAppInput: msg.followUpCodexAppInput,
|
|
746
780
|
});
|
|
747
781
|
log(`Enqueued follow-up after raw input (${msg.followUpContent.length} chars)`);
|
|
@@ -789,18 +823,28 @@ function publishSandboxRelayCapability(opts = {}) {
|
|
|
789
823
|
}]
|
|
790
824
|
: []),
|
|
791
825
|
];
|
|
826
|
+
let publishError;
|
|
792
827
|
for (const file of files) {
|
|
793
828
|
try {
|
|
794
829
|
replaceManagedOriginCapabilityFile(file.path, file.body);
|
|
795
830
|
}
|
|
796
831
|
catch (err) {
|
|
797
832
|
log(`Failed to publish managed origin capability: ${err?.message ?? err}`);
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
throw err;
|
|
801
|
-
}
|
|
833
|
+
publishError = err;
|
|
834
|
+
break;
|
|
802
835
|
}
|
|
803
836
|
}
|
|
837
|
+
if (publishError) {
|
|
838
|
+
// The disk/daemon/worker views must rotate as one authority generation. If
|
|
839
|
+
// the child-visible transport cannot publish the new token, revoke the old
|
|
840
|
+
// generation and leave no in-memory authority for ready/send preflights to
|
|
841
|
+
// mistake as usable. Any files written before a later failure are removed
|
|
842
|
+
// by the revocation helper as well.
|
|
843
|
+
completeManagedTurnOriginRevocation(sandboxRelayCapability, currentBotmuxTurnId, currentBotmuxDispatchAttempt);
|
|
844
|
+
if (opts.failClosed)
|
|
845
|
+
throw publishError;
|
|
846
|
+
return false;
|
|
847
|
+
}
|
|
804
848
|
sandboxRelayCapability = capability;
|
|
805
849
|
if (sessionId) {
|
|
806
850
|
send({
|
|
@@ -813,6 +857,7 @@ function publishSandboxRelayCapability(opts = {}) {
|
|
|
813
857
|
: {}),
|
|
814
858
|
});
|
|
815
859
|
}
|
|
860
|
+
return true;
|
|
816
861
|
}
|
|
817
862
|
function unlinkManagedOriginCapabilityFiles() {
|
|
818
863
|
const files = [
|
|
@@ -4381,8 +4426,14 @@ function detectBareShellLaunch() {
|
|
|
4381
4426
|
else {
|
|
4382
4427
|
message =
|
|
4383
4428
|
`⚠️ 会话没能启动:pane 里还停在 \`${comm}\`,${cli} 没真正跑起来——我没把消息打进去(否则会被当 shell 命令执行)。\n\n` +
|
|
4384
|
-
|
|
4385
|
-
|
|
4429
|
+
`最常见原因:rc 文件里有交互式提示卡住了 shell 启动,例如:\n` +
|
|
4430
|
+
`① Oh My Zsh 升级提示("Would you like to update Oh My Zsh? [Y/n]")——${comm} source ~/.zshrc 时弹出,等你按 Y/n,CLI 的启动命令没机会跑\n` +
|
|
4431
|
+
`② git 凭据弹窗(GIT_TERMINAL_PROMPT)或其它需要交互输入的启动脚本\n` +
|
|
4432
|
+
`③ ${cli} 的可执行文件不在 PATH 上(CLI 没找到)\n\n` +
|
|
4433
|
+
`修法(任选其一,改完重启 daemon 再发一条消息):\n` +
|
|
4434
|
+
`• 最省事:升级 botmux 到含自动注入 DISABLE_AUTO_UPDATE=true 的版本(仅 botmux 托管 shell 启动时跳过 oh-my-zsh 升级检查,不影响你自己的终端)\n` +
|
|
4435
|
+
`• 手动修:在 ~/.zshrc 的 source $ZSH/oh-my-zsh.sh 之前加一行 DISABLE_UPDATE_PROMPT="true"(自动升级不弹提示);或加 DISABLE_AUTO_UPDATE="true"(完全跳过升级检查)\n` +
|
|
4436
|
+
`• 在 web 终端里手动敲一下启动命令看报什么错;确认 CLI 二进制能在 PATH 上找到;或精简 rc 启动逻辑后重启 daemon 再试`;
|
|
4386
4437
|
}
|
|
4387
4438
|
send({ type: 'user_notify', turnId: currentBotmuxTurnId, dispatchAttempt: currentBotmuxDispatchAttempt, message });
|
|
4388
4439
|
return true;
|
|
@@ -5300,6 +5351,9 @@ function spawnCli(cfg) {
|
|
|
5300
5351
|
if (!isValidRiffBaseUrl(cfg.backendConfig.baseUrl)) {
|
|
5301
5352
|
throw new Error(`riff baseUrl 未配置或非法(需 http(s) URL,当前: ${JSON.stringify(cfg.backendConfig.baseUrl ?? null)})——请在 dashboard 的 Riff 配置中填写`);
|
|
5302
5353
|
}
|
|
5354
|
+
if (cfg.backendConfig.sandboxCluster !== undefined && !isValidRiffSandboxCluster(cfg.backendConfig.sandboxCluster)) {
|
|
5355
|
+
throw new Error(`riff sandboxCluster 非法(仅支持 boe/cn,当前: ${JSON.stringify(cfg.backendConfig.sandboxCluster)})——请在 dashboard 的 Riff 配置中重新选择`);
|
|
5356
|
+
}
|
|
5303
5357
|
const sessionEnv = {
|
|
5304
5358
|
BOTMUX_SESSION_ID: cfg.sessionId,
|
|
5305
5359
|
BOTMUX_CHAT_ID: cfg.chatId,
|
|
@@ -5372,6 +5426,7 @@ function spawnCli(cfg) {
|
|
|
5372
5426
|
// JSONL/pid/bridge gate below keys off it instead of `cliId === 'claude-code'`,
|
|
5373
5427
|
// so a fork inherits the whole submit-confirm + bridge-fallback machinery.
|
|
5374
5428
|
let claudeDataDir = cliAdapter.claudeDataDir;
|
|
5429
|
+
let effectiveReadyHookInstall = cliAdapter.hookInstall;
|
|
5375
5430
|
// When this session will be file-sandboxed, the CLI's session jsonl is written
|
|
5376
5431
|
// into the overlay's EPHEMERAL home upper (CLAUDE_CONFIG_DIR lives under $HOME),
|
|
5377
5432
|
// invisible at the real path the bridge normally watches → "Bridge mark expired"
|
|
@@ -5382,7 +5437,10 @@ function spawnCli(cfg) {
|
|
|
5382
5437
|
(effectiveBackendType === 'pty' || effectiveBackendType === 'tmux') &&
|
|
5383
5438
|
!!process.env.SESSION_DATA_DIR;
|
|
5384
5439
|
if (claudeDataDir && willFileSandbox) {
|
|
5385
|
-
const redirected = sandboxedClaudeDataDir(cfg.sessionId, claudeDataDir
|
|
5440
|
+
const redirected = sandboxedClaudeDataDir(cfg.sessionId, claudeDataDir, {
|
|
5441
|
+
sourceWorkingDir: cfg.workingDir,
|
|
5442
|
+
dataDir: process.env.SESSION_DATA_DIR,
|
|
5443
|
+
});
|
|
5386
5444
|
log(`[sandbox] redirecting Claude bridge dataDir → overlay upper: ${redirected}`);
|
|
5387
5445
|
claudeDataDir = redirected;
|
|
5388
5446
|
}
|
|
@@ -5465,6 +5523,12 @@ function spawnCli(cfg) {
|
|
|
5465
5523
|
// Provision the per-bot config dir (auth + onboarding/trust seed + hooks for claude;
|
|
5466
5524
|
// auth/config copy for codex) so the CLI starts fully set up under the Seatbelt wrapper.
|
|
5467
5525
|
provisionIsolatedBotHome(isolationBotHome, cfg.workingDir, isClaudeFam, cfg.cliId, cliAdapter.hookInstall, log);
|
|
5526
|
+
if (isClaudeFam && effectiveReadyHookInstall) {
|
|
5527
|
+
effectiveReadyHookInstall = {
|
|
5528
|
+
...effectiveReadyHookInstall,
|
|
5529
|
+
configPath: join(claudeDataDir, 'settings.json'),
|
|
5530
|
+
};
|
|
5531
|
+
}
|
|
5468
5532
|
if (cliAdapter.mcpGateway) {
|
|
5469
5533
|
const isolatedConfigPath = isClaudeFam
|
|
5470
5534
|
? join(claudeDataDir, '.claude.json')
|
|
@@ -5586,6 +5650,26 @@ function spawnCli(cfg) {
|
|
|
5586
5650
|
let effectiveResume = cfg.resume ?? false;
|
|
5587
5651
|
let effectiveCliSessionId = cfg.cliSessionId;
|
|
5588
5652
|
let effectiveAdapterSessionId = adapterSessionId;
|
|
5653
|
+
// Claude-family transcripts are scoped by cwd. `/cd` keeps the same Botmux /
|
|
5654
|
+
// CLI session id, so mirror the newest native transcript into the new cwd's
|
|
5655
|
+
// project directory before the adapter probes or launches `--resume`.
|
|
5656
|
+
// `claudeDataDir` is already the effective root here (global, per-bot read
|
|
5657
|
+
// isolation root, or a preserved sandbox upper), so this never crosses bot
|
|
5658
|
+
// isolation boundaries.
|
|
5659
|
+
if (effectiveResume && !willReattachPersistent && claudeDataDir) {
|
|
5660
|
+
const resumeSessionId = effectiveCliSessionId ?? effectiveAdapterSessionId;
|
|
5661
|
+
try {
|
|
5662
|
+
const synced = syncClaudeResumeTargetToCwd(resumeSessionId, cfg.workingDir, claudeDataDir);
|
|
5663
|
+
if (synced.copied && synced.sourcePath) {
|
|
5664
|
+
log(`Claude resume transcript synced for cwd change: ${synced.sourcePath} → ${synced.targetPath}`);
|
|
5665
|
+
}
|
|
5666
|
+
}
|
|
5667
|
+
catch (err) {
|
|
5668
|
+
// Preserve the existing fail-safe: the adapter probe / two-tier fallback
|
|
5669
|
+
// below still decides whether resume is possible.
|
|
5670
|
+
log(`WARN Claude resume transcript sync failed: ${err.message}`);
|
|
5671
|
+
}
|
|
5672
|
+
}
|
|
5589
5673
|
const tier2ForceFresh = effectiveResume && consecutiveInWorkerRestarts >= 2;
|
|
5590
5674
|
let tier1ProbeFalse = false;
|
|
5591
5675
|
if (effectiveResume && !tier2ForceFresh && !willReattachPersistent) {
|
|
@@ -6461,15 +6545,22 @@ function spawnCli(cfg) {
|
|
|
6461
6545
|
codexBridgeStartTimer();
|
|
6462
6546
|
}
|
|
6463
6547
|
}
|
|
6464
|
-
// Arm the ready-gate for FRESH
|
|
6465
|
-
// SessionStart hook via --settings; see claude-code.ts buildArgs). Until
|
|
6548
|
+
// Arm the ready-gate for FRESH ready-integrated spawns. Until
|
|
6466
6549
|
// `botmux session-ready` fires (daemon → 'session_ready' IPC → releaseReadyGate)
|
|
6467
6550
|
// we hold the first prompt so a cjadk-style startup selector's ❯ can't eat it.
|
|
6468
|
-
// shouldArmReadyGate() excludes adopt (pre-existing pane, no
|
|
6551
|
+
// shouldArmReadyGate() excludes adopt (pre-existing pane, no fresh hook) AND
|
|
6469
6552
|
// persistent-backend reattach (daemon restart re-attaches an already-running
|
|
6470
6553
|
// tmux/zellij/herdr Claude WITHOUT re-running its bin/args → no new
|
|
6471
6554
|
// SessionStart hook → arming would hold the first post-recovery message until
|
|
6472
|
-
// the timeout).
|
|
6555
|
+
// the timeout).
|
|
6556
|
+
//
|
|
6557
|
+
// Installation is best-effort, so verify the hook in the EFFECTIVE config
|
|
6558
|
+
// (global for ordinary sessions, per-bot CLAUDE_CONFIG_DIR under read
|
|
6559
|
+
// isolation) before arming. Isolated children also need the injected loopback
|
|
6560
|
+
// port plus a published rotating capability; without either the hook could
|
|
6561
|
+
// run but never reach the daemon. A failed preflight leaves the gate open and
|
|
6562
|
+
// immediately falls back to the adapter's normal readyPattern/quiescence path
|
|
6563
|
+
// instead of blindly waiting READY_SIGNAL_TIMEOUT_MS.
|
|
6473
6564
|
readyGate = new ReadyGate();
|
|
6474
6565
|
if (readySignalTimer) {
|
|
6475
6566
|
clearTimeout(readySignalTimer);
|
|
@@ -6483,8 +6574,29 @@ function spawnCli(cfg) {
|
|
|
6483
6574
|
promptReadyDetectedDuringSettle = false;
|
|
6484
6575
|
// Reset quiescence baseline so the settle measures silence from THIS spawn.
|
|
6485
6576
|
lastPtyOutputAtMs = Date.now();
|
|
6577
|
+
const readyHookAvailable = effectiveReadyHookInstall
|
|
6578
|
+
? hasInstalledSessionReadyHook(effectiveReadyHookInstall)
|
|
6579
|
+
: true; // Hermes emits BOTMUX_READY_COMMAND directly instead of a config hook.
|
|
6580
|
+
const isolatedReadyTransportRequired = sandboxOn || willReadIsolate;
|
|
6581
|
+
const readyPortAvailable = !isolatedReadyTransportRequired
|
|
6582
|
+
|| parseDaemonIpcPort(childEnv.BOTMUX_DAEMON_IPC_PORT) !== undefined;
|
|
6583
|
+
const readyCapabilityAvailable = !isolatedReadyTransportRequired
|
|
6584
|
+
|| hasMatchingManagedOriginCapability(process.env.SESSION_DATA_DIR ?? '', cfg.sessionId, sandboxRelayCapability?.token, sandboxRelayOutbox ?? undefined);
|
|
6585
|
+
const readySignalAvailable = readyHookAvailable && readyPortAvailable && readyCapabilityAvailable;
|
|
6586
|
+
const freshReadyGateCandidate = cliAdapter.injectsReadyHook === true
|
|
6587
|
+
&& cfg.adoptMode !== true
|
|
6588
|
+
&& !willReattachPersistent;
|
|
6589
|
+
if (freshReadyGateCandidate && !readySignalAvailable) {
|
|
6590
|
+
const reasons = [
|
|
6591
|
+
...(!readyHookAvailable ? ['SessionStart hook missing from effective config'] : []),
|
|
6592
|
+
...(!readyPortAvailable ? ['BOTMUX_DAEMON_IPC_PORT missing/invalid'] : []),
|
|
6593
|
+
...(!readyCapabilityAvailable ? ['ready capability transport missing, unreadable, or stale'] : []),
|
|
6594
|
+
];
|
|
6595
|
+
log(`Ready gate skipped — preflight failed: ${reasons.join('; ')}`);
|
|
6596
|
+
}
|
|
6486
6597
|
if (shouldArmReadyGate({
|
|
6487
6598
|
injectsReadyHook: cliAdapter.injectsReadyHook === true,
|
|
6599
|
+
readySignalAvailable,
|
|
6488
6600
|
adoptMode: cfg.adoptMode === true,
|
|
6489
6601
|
willReattachPersistent,
|
|
6490
6602
|
})) {
|