@gajae-code/coding-agent 0.10.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -2
- package/dist/types/append-only-mode.d.ts +1 -1
- package/dist/types/cli/args.d.ts +4 -5
- package/dist/types/cli/daemon-cli.d.ts +12 -1
- package/dist/types/cli/notify-cli.d.ts +21 -1
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/commands/daemon.d.ts +39 -0
- package/dist/types/commands/launch.d.ts +3 -0
- package/dist/types/commands/notify.d.ts +28 -1
- package/dist/types/commands/sdk.d.ts +33 -0
- package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
- package/dist/types/config/model-profile-activation.d.ts +35 -15
- package/dist/types/config/model-profiles.d.ts +11 -5
- package/dist/types/config/model-registry.d.ts +3 -3
- package/dist/types/config/model-resolver.d.ts +39 -6
- package/dist/types/config/model-selector-value.d.ts +17 -0
- package/dist/types/config/models-config-schema.d.ts +10 -6
- package/dist/types/config/settings-schema.d.ts +133 -6
- package/dist/types/config/settings.d.ts +63 -35
- package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
- package/dist/types/coordinator-mcp/server.d.ts +6 -49
- package/dist/types/daemon/builtin.d.ts +6 -5
- package/dist/types/daemon/control-types.d.ts +1 -1
- package/dist/types/discovery/mcp-json.d.ts +12 -1
- package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
- package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
- package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
- package/dist/types/extensibility/extensions/loader.d.ts +10 -1
- package/dist/types/extensibility/extensions/runner.d.ts +3 -3
- package/dist/types/extensibility/extensions/types.d.ts +141 -16
- package/dist/types/extensibility/hooks/types.d.ts +1 -1
- package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
- package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
- package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
- package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
- package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
- package/dist/types/harness-control-plane/operate.d.ts +5 -5
- package/dist/types/harness-control-plane/owner.d.ts +18 -4
- package/dist/types/harness-control-plane/receipts.d.ts +0 -1
- package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
- package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
- package/dist/types/harness-control-plane/types.d.ts +3 -4
- package/dist/types/lsp/index.d.ts +1 -1
- package/dist/types/main.d.ts +32 -38
- package/dist/types/modes/acp/acp-agent.d.ts +224 -53
- package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
- package/dist/types/modes/acp/acp-mode.d.ts +6 -15
- package/dist/types/modes/acp/permission-mode.d.ts +4 -0
- package/dist/types/modes/acp/startup-options.d.ts +6 -0
- package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
- package/dist/types/modes/components/model-selector.d.ts +1 -0
- package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
- package/dist/types/modes/components/settings-selector.d.ts +6 -4
- package/dist/types/modes/components/welcome.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
- package/dist/types/modes/index.d.ts +0 -4
- package/dist/types/modes/interactive-mode.d.ts +3 -0
- package/dist/types/modes/runtime-init.d.ts +2 -2
- package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
- package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
- package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
- package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
- package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +169 -30
- package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
- package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
- package/dist/types/modes/types.d.ts +5 -0
- package/dist/types/runtime-mcp/client.d.ts +2 -0
- package/dist/types/runtime-mcp/config.d.ts +5 -1
- package/dist/types/runtime-mcp/manager.d.ts +8 -1
- package/dist/types/runtime-mcp/types.d.ts +4 -0
- package/dist/types/sdk/acp/adapter.d.ts +67 -0
- package/dist/types/sdk/acp/index.d.ts +2 -0
- package/dist/types/sdk/broker/broker.d.ts +53 -0
- package/dist/types/sdk/broker/discovery.d.ts +30 -0
- package/dist/types/sdk/broker/ensure.d.ts +33 -0
- package/dist/types/sdk/broker/identity.d.ts +3 -0
- package/dist/types/sdk/broker/index.d.ts +8 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
- package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
- package/dist/types/sdk/broker/runtime.d.ts +33 -0
- package/dist/types/sdk/broker/session-index.d.ts +57 -0
- package/dist/types/sdk/broker/state-version.d.ts +8 -0
- package/dist/types/sdk/broker/transport.d.ts +9 -0
- package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
- package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
- package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
- package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
- package/dist/types/sdk/bus/config.d.ts +274 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
- package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
- package/dist/types/sdk/bus/discord-daemon.d.ts +45 -0
- package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
- package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
- package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
- package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
- package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
- package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
- package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
- package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
- package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
- package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
- package/dist/types/sdk/bus/session-control.d.ts +83 -0
- package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
- package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
- package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
- package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
- package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
- package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
- package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
- package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +55 -17
- package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
- package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
- package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
- package/dist/types/sdk/cli/index.d.ts +1 -0
- package/dist/types/sdk/cli/session-cli.d.ts +19 -0
- package/dist/types/sdk/client/client.d.ts +1 -0
- package/dist/types/sdk/client/discovery.d.ts +27 -0
- package/dist/types/sdk/client/index.d.ts +2 -0
- package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
- package/dist/types/sdk/host/control/index.d.ts +2 -0
- package/dist/types/sdk/host/control/operations.d.ts +65 -0
- package/dist/types/sdk/host/events.d.ts +35 -0
- package/dist/types/sdk/host/host.d.ts +35 -0
- package/dist/types/sdk/host/index.d.ts +4 -0
- package/dist/types/sdk/host/query/cursor.d.ts +62 -0
- package/dist/types/sdk/host/query/handlers.d.ts +70 -0
- package/dist/types/sdk/host/query/index.d.ts +3 -0
- package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
- package/dist/types/sdk/host/types.d.ts +32 -0
- package/dist/types/sdk/index.d.ts +6 -0
- package/dist/types/sdk/lifecycle-session.d.ts +14 -0
- package/dist/types/sdk/mcp/index.d.ts +1 -0
- package/dist/types/sdk/mcp/server.d.ts +37 -0
- package/dist/types/sdk/models.d.ts +44 -0
- package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
- package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
- package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
- package/dist/types/sdk/startup-capability.d.ts +50 -0
- package/dist/types/session/agent-session.d.ts +114 -21
- package/dist/types/session/default-model-selection.d.ts +25 -0
- package/dist/types/session/fallback-chain-controller.d.ts +52 -0
- package/dist/types/session/session-manager.d.ts +58 -1
- package/dist/types/setup/credential-auto-import.d.ts +36 -6
- package/dist/types/tools/ask-answer-registry.d.ts +1 -1
- package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
- package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
- package/dist/types/tools/browser/launch.d.ts +22 -0
- package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
- package/dist/types/tools/browser/profile-posture.d.ts +37 -0
- package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
- package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
- package/dist/types/tools/browser/registry.d.ts +19 -0
- package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
- package/dist/types/tools/index.d.ts +8 -8
- package/package.json +34 -13
- package/scripts/build-sdk-package-smoke.ts +94 -0
- package/scripts/capture-notifications-settings-showcase.ts +435 -0
- package/scripts/compile-args.ts +4 -2
- package/scripts/g005-daemon-smoke.ts +4 -5
- package/scripts/g011-daemon-path-smoke.ts +5 -5
- package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
- package/scripts/generate-sdk-operation-inventory.ts +867 -0
- package/scripts/generate-telegram-baseline-manifest.ts +128 -0
- package/scripts/manifest-schema.ts +124 -0
- package/scripts/run-test-manifest.ts +153 -0
- package/scripts/run-threat-model-check.ts +157 -0
- package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
- package/scripts/verify-gjc-sdk-rename.ts +90 -0
- package/src/append-only-mode.ts +1 -1
- package/src/cli/args.ts +43 -12
- package/src/cli/auth-gateway-cli.ts +2 -2
- package/src/cli/config-cli.ts +2 -1
- package/src/cli/daemon-cli.ts +63 -14
- package/src/cli/list-models.ts +1 -1
- package/src/cli/notify-cli.ts +288 -286
- package/src/cli.ts +21 -2
- package/src/commands/daemon.ts +50 -6
- package/src/commands/harness.ts +93 -36
- package/src/commands/launch.ts +5 -2
- package/src/commands/mcp-serve.ts +19 -12
- package/src/commands/notify.ts +36 -3
- package/src/commands/sdk.ts +426 -0
- package/src/commit/agentic/agent.ts +1 -0
- package/src/config/atomic-yaml-patch.ts +423 -0
- package/src/config/model-profile-activation.ts +240 -89
- package/src/config/model-profiles.ts +18 -15
- package/src/config/model-registry.ts +51 -26
- package/src/config/model-resolver.ts +138 -51
- package/src/config/model-selector-value.ts +50 -0
- package/src/config/models-config-schema.ts +14 -21
- package/src/config/settings-schema.ts +128 -10
- package/src/config/settings.ts +1120 -158
- package/src/coordinator-mcp/model-preset.ts +74 -20
- package/src/coordinator-mcp/server.ts +1597 -3052
- package/src/daemon/builtin.ts +8 -5
- package/src/daemon/control-types.ts +1 -1
- package/src/defaults/gjc/skills/team/SKILL.md +4 -4
- package/src/discovery/mcp-json.ts +327 -20
- package/src/extensibility/custom-tools/types.ts +1 -1
- package/src/extensibility/extensions/compact-handler.ts +3 -3
- package/src/extensibility/extensions/get-commands-handler.ts +2 -2
- package/src/extensibility/extensions/loader.ts +69 -5
- package/src/extensibility/extensions/runner.ts +112 -4
- package/src/extensibility/extensions/types.ts +176 -17
- package/src/extensibility/hooks/types.ts +1 -1
- package/src/gjc-runtime/launch-tmux.ts +170 -86
- package/src/gjc-runtime/psmux-detect.ts +82 -4
- package/src/gjc-runtime/session-state-sidecar.ts +41 -31
- package/src/gjc-runtime/team-runtime.ts +54 -35
- package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
- package/src/gjc-runtime/tmux-owner-isolation.ts +1 -1
- package/src/gjc-runtime/tmux-sessions.ts +19 -13
- package/src/gjc-runtime/ultragoal-guard.ts +53 -6
- package/src/gjc-runtime/ultragoal-runtime.ts +155 -3
- package/src/gjc-runtime/windows-powershell-command.ts +58 -0
- package/src/harness-control-plane/operate.ts +9 -9
- package/src/harness-control-plane/owner.ts +283 -39
- package/src/harness-control-plane/receipts.ts +0 -1
- package/src/harness-control-plane/sdk-transport.ts +395 -0
- package/src/harness-control-plane/session-transport.ts +94 -0
- package/src/harness-control-plane/types.ts +1 -1
- package/src/internal-urls/docs-index.generated.ts +34 -35
- package/src/lsp/client.ts +42 -6
- package/src/lsp/index.ts +2 -2
- package/src/main.ts +299 -204
- package/src/modes/DESIGN.md +258 -0
- package/src/modes/acp/acp-agent.ts +1228 -2612
- package/src/modes/acp/acp-client-bridge.ts +2 -20
- package/src/modes/acp/acp-event-mapper.ts +18 -2
- package/src/modes/acp/acp-mode.ts +8 -36
- package/src/modes/acp/permission-mode.ts +25 -0
- package/src/modes/acp/startup-options.ts +6 -0
- package/src/modes/components/agent-dashboard.ts +37 -17
- package/src/modes/components/model-selector.ts +93 -35
- package/src/modes/components/notifications-settings-editor.ts +1379 -0
- package/src/modes/components/settings-selector.ts +60 -11
- package/src/modes/components/welcome.ts +4 -4
- package/src/modes/controllers/command-controller.ts +1 -2
- package/src/modes/controllers/event-controller.ts +11 -16
- package/src/modes/controllers/extension-ui-controller.ts +348 -4
- package/src/modes/controllers/selector-controller.ts +674 -36
- package/src/modes/index.ts +0 -22
- package/src/modes/interactive-mode.ts +59 -20
- package/src/modes/runtime-init.ts +298 -6
- package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
- package/src/modes/shared/agent-wire/event-contract.ts +7 -8
- package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
- package/src/modes/shared/agent-wire/event-observation.ts +16 -7
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1254 -87
- package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
- package/src/modes/types.ts +5 -0
- package/src/runtime-mcp/client.ts +94 -19
- package/src/runtime-mcp/config.ts +27 -15
- package/src/runtime-mcp/manager.ts +343 -105
- package/src/runtime-mcp/oauth-flow.ts +42 -12
- package/src/runtime-mcp/transports/http.ts +49 -19
- package/src/runtime-mcp/transports/stdio.ts +47 -28
- package/src/runtime-mcp/types.ts +10 -0
- package/src/sdk/acp/adapter.ts +418 -0
- package/src/sdk/acp/index.ts +2 -0
- package/src/sdk/broker/broker.ts +642 -0
- package/src/sdk/broker/discovery.ts +94 -0
- package/src/sdk/broker/ensure.ts +249 -0
- package/src/sdk/broker/identity.ts +42 -0
- package/src/sdk/broker/index.ts +8 -0
- package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
- package/src/sdk/broker/internal-source.bunfig.toml +1 -0
- package/src/sdk/broker/lifecycle-ledger.ts +286 -0
- package/src/sdk/broker/lifecycle.ts +2157 -0
- package/src/sdk/broker/process-incarnation.ts +159 -0
- package/src/sdk/broker/runtime.ts +164 -0
- package/src/sdk/broker/session-index.ts +318 -0
- package/src/sdk/broker/state-version.ts +23 -0
- package/src/sdk/broker/transport.ts +125 -0
- package/src/sdk/bus/chat-command-policy.ts +107 -0
- package/src/sdk/bus/chat-daemon-cli.ts +214 -0
- package/src/sdk/bus/chat-daemon-control.ts +713 -0
- package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
- package/src/sdk/bus/chat-effect-journal.ts +353 -0
- package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
- package/src/sdk/bus/config.ts +433 -0
- package/src/sdk/bus/conversation-store.ts +391 -0
- package/src/sdk/bus/discord-conversation.ts +85 -0
- package/src/sdk/bus/discord-daemon.ts +2275 -0
- package/src/sdk/bus/discord-live-provider.ts +521 -0
- package/src/sdk/bus/discord-provider.ts +56 -0
- package/src/{notifications → sdk/bus}/html-format.ts +2 -2
- package/src/sdk/bus/index.ts +3943 -0
- package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
- package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
- package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
- package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
- package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
- package/src/sdk/bus/natives-augment.d.ts +38 -0
- package/src/sdk/bus/notification-orchestration.ts +535 -0
- package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
- package/src/sdk/bus/session-control.ts +333 -0
- package/src/sdk/bus/slack-conversation.ts +74 -0
- package/src/sdk/bus/slack-daemon.ts +2144 -0
- package/src/sdk/bus/slack-live-provider.ts +380 -0
- package/src/sdk/bus/slack-provider.ts +76 -0
- package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
- package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
- package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
- package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
- package/src/{notifications → sdk/bus}/telegram-daemon.ts +502 -54
- package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
- package/src/sdk/bus/telegram-setup.ts +663 -0
- package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
- package/src/sdk/cli/index.ts +1 -0
- package/src/sdk/cli/session-cli.ts +275 -0
- package/src/sdk/client/client.ts +1 -0
- package/src/sdk/client/discovery.ts +108 -0
- package/src/sdk/client/index.ts +2 -0
- package/src/sdk/host/control/dispatch.ts +367 -0
- package/src/sdk/host/control/index.ts +10 -0
- package/src/sdk/host/control/operations.ts +63 -0
- package/src/sdk/host/events.ts +91 -0
- package/src/sdk/host/host.ts +296 -0
- package/src/sdk/host/index.ts +4 -0
- package/src/sdk/host/query/cursor.ts +189 -0
- package/src/sdk/host/query/handlers.ts +533 -0
- package/src/sdk/host/query/index.ts +3 -0
- package/src/sdk/host/query/revision-store.ts +1126 -0
- package/src/sdk/host/reverse-leases.ts +325 -0
- package/src/sdk/host/types.ts +29 -0
- package/src/sdk/index.ts +13 -0
- package/src/sdk/lifecycle-session.ts +39 -0
- package/src/sdk/mcp/index.ts +1 -0
- package/src/sdk/mcp/server.ts +332 -0
- package/src/sdk/models.ts +168 -0
- package/src/sdk/protocol/adapter-validation.ts +48 -0
- package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
- package/src/sdk/protocol/operation-registry.ts +312 -0
- package/src/{sdk.ts → sdk/session.ts} +339 -212
- package/src/sdk/startup-capability.ts +189 -0
- package/src/session/agent-session.ts +2453 -894
- package/src/session/default-model-selection.ts +93 -0
- package/src/session/fallback-chain-controller.ts +136 -0
- package/src/session/session-manager.ts +438 -11
- package/src/session/session-storage.ts +8 -1
- package/src/setup/credential-auto-import.ts +290 -35
- package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
- package/src/slash-commands/builtin-registry.ts +2 -1
- package/src/task/executor.ts +62 -13
- package/src/tools/ask-answer-registry.ts +1 -1
- package/src/tools/ask.ts +13 -8
- package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
- package/src/tools/browser/benchmark/detector-report.ts +157 -0
- package/src/tools/browser/benchmark/run-suite.ts +39 -0
- package/src/tools/browser/launch.ts +124 -19
- package/src/tools/browser/profile-discovery.ts +63 -0
- package/src/tools/browser/profile-posture.ts +59 -0
- package/src/tools/browser/profile-reuse.ts +102 -0
- package/src/tools/browser/profile-warmup.ts +109 -0
- package/src/tools/browser/registry.ts +87 -11
- package/src/tools/browser/tab-protocol.ts +1 -0
- package/src/tools/browser/tab-supervisor.ts +1 -0
- package/src/tools/browser/tab-worker.ts +1 -1
- package/src/tools/browser.ts +6 -0
- package/src/tools/index.ts +8 -8
- package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
- package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
- package/src/tools/telegram-send.ts +2 -2
- package/vendor/insane-search/MANIFEST.json +2 -1
- package/vendor/insane-search/engine/bias_check.py +4 -1
- package/vendor/insane-search/engine/phase0.py +26 -1
- package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
- package/dist/types/modes/bridge/auth.d.ts +0 -12
- package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
- package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
- package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
- package/dist/types/modes/bridge/event-stream.d.ts +0 -8
- package/dist/types/modes/rpc/host-tools.d.ts +0 -1
- package/dist/types/modes/rpc/host-uris.d.ts +0 -1
- package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
- package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
- package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
- package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
- package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
- package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
- package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
- package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
- package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
- package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
- package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
- package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
- package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
- package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
- package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
- package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
- package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
- package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
- package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
- package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
- package/dist/types/notifications/config.d.ts +0 -132
- package/src/harness-control-plane/rpc-adapter.ts +0 -290
- package/src/modes/bridge/auth.ts +0 -41
- package/src/modes/bridge/bridge-client-bridge.ts +0 -47
- package/src/modes/bridge/bridge-mode.ts +0 -675
- package/src/modes/bridge/bridge-ui-context.ts +0 -200
- package/src/modes/bridge/event-stream.ts +0 -70
- package/src/modes/rpc/host-tools.ts +0 -1
- package/src/modes/rpc/host-uris.ts +0 -1
- package/src/modes/rpc/rpc-client.ts +0 -1166
- package/src/modes/rpc/rpc-mode.ts +0 -1029
- package/src/modes/rpc/rpc-socket-security.ts +0 -115
- package/src/modes/rpc/rpc-types.ts +0 -637
- package/src/modes/shared/agent-wire/command-contract.ts +0 -18
- package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
- package/src/modes/shared/agent-wire/command-validation.ts +0 -181
- package/src/modes/shared/agent-wire/handshake.ts +0 -157
- package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
- package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
- package/src/modes/shared/agent-wire/protocol.ts +0 -46
- package/src/modes/shared/agent-wire/responses.ts +0 -17
- package/src/modes/shared/agent-wire/scopes.ts +0 -94
- package/src/modes/shared/agent-wire/session-registry.ts +0 -109
- package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
- package/src/modes/shared/agent-wire/ui-result.ts +0 -48
- package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
- package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
- package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
- package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
- package/src/notifications/config.ts +0 -219
- package/src/notifications/index.ts +0 -1835
- package/src/notifications/telegram-daemon-cli.ts +0 -243
- package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
- /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
- /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
- /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
- /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
- /package/src/{notifications → sdk/bus}/engine.ts +0 -0
- /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
- /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
- /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
- /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
- /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
- /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
- /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
- /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
- /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
|
@@ -7,7 +7,10 @@ import { safeStderrWrite } from "@gajae-code/utils/safe-stderr";
|
|
|
7
7
|
import type { Args } from "../cli/args";
|
|
8
8
|
import { tmuxRuntimeSessionPath } from "./session-layout";
|
|
9
9
|
import {
|
|
10
|
+
GJC_COORDINATOR_SESSION_BRANCH_ENV,
|
|
10
11
|
GJC_COORDINATOR_SESSION_ID_ENV,
|
|
12
|
+
GJC_COORDINATOR_SESSION_LAUNCH_ID_ENV,
|
|
13
|
+
GJC_COORDINATOR_SESSION_READINESS_FILE_ENV,
|
|
11
14
|
GJC_COORDINATOR_SESSION_STATE_FILE_ENV,
|
|
12
15
|
GJC_TMUX_OWNER_GENERATION_ENV,
|
|
13
16
|
GJC_TMUX_OWNER_SERVER_KEY_ENV,
|
|
@@ -46,18 +49,25 @@ import {
|
|
|
46
49
|
type GjcTmuxSessionStatus,
|
|
47
50
|
proveGjcTmuxSessionMutationTarget,
|
|
48
51
|
} from "./tmux-sessions";
|
|
52
|
+
import {
|
|
53
|
+
buildWindowsPowerShellInnerCommand,
|
|
54
|
+
GJC_TMUX_LAUNCHED_ENV,
|
|
55
|
+
type WindowsPowerShellInnerCommandOptions,
|
|
56
|
+
} from "./windows-powershell-command";
|
|
49
57
|
|
|
58
|
+
export type { WindowsPowerShellInnerCommandOptions };
|
|
50
59
|
export {
|
|
51
60
|
buildGjcTmuxExactSessionTarget,
|
|
52
61
|
buildGjcTmuxProfileCommands,
|
|
62
|
+
buildWindowsPowerShellInnerCommand,
|
|
53
63
|
GJC_DEFAULT_TMUX_SESSION,
|
|
54
64
|
GJC_TMUX_COMMAND_ENV,
|
|
65
|
+
GJC_TMUX_LAUNCHED_ENV,
|
|
55
66
|
GJC_TMUX_MOUSE_ENV,
|
|
56
67
|
GJC_TMUX_PROFILE_ENV,
|
|
57
68
|
GJC_TMUX_SESSION_PREFIX,
|
|
58
69
|
};
|
|
59
70
|
|
|
60
|
-
export const GJC_TMUX_LAUNCHED_ENV = "GJC_TMUX_LAUNCHED";
|
|
61
71
|
export const GJC_LAUNCH_POLICY_ENV = "GJC_LAUNCH_POLICY";
|
|
62
72
|
export const GJC_TMUX_WINDOW_LABEL_MAX_WIDTH = 48;
|
|
63
73
|
|
|
@@ -163,6 +173,108 @@ function allowsExistingTmuxAttach(parsed: Args, env: NodeJS.ProcessEnv): boolean
|
|
|
163
173
|
// value-less resume can show the session picker and valued resume can honor the target.
|
|
164
174
|
return Boolean(parsed.continue || explicitTmuxSessionName(env));
|
|
165
175
|
}
|
|
176
|
+
type WindowsPsmuxCompatibilityState = "fresh" | "continuation" | "managed";
|
|
177
|
+
|
|
178
|
+
function windowsPsmuxCompatibilityState(plan: TmuxLaunchPlan, env: NodeJS.ProcessEnv): WindowsPsmuxCompatibilityState {
|
|
179
|
+
const marker = (value: string | undefined): boolean => Boolean(value?.trim());
|
|
180
|
+
if (
|
|
181
|
+
marker(env.GJC_SESSION_ID) ||
|
|
182
|
+
marker(env[GJC_COORDINATOR_SESSION_ID_ENV]) ||
|
|
183
|
+
marker(env[GJC_COORDINATOR_SESSION_BRANCH_ENV]) ||
|
|
184
|
+
marker(env[GJC_COORDINATOR_SESSION_LAUNCH_ID_ENV]) ||
|
|
185
|
+
marker(env[GJC_COORDINATOR_SESSION_READINESS_FILE_ENV]) ||
|
|
186
|
+
marker(env[GJC_COORDINATOR_SESSION_STATE_FILE_ENV]) ||
|
|
187
|
+
marker(env[GJC_TMUX_ACTIVE_SESSION_ENV]) ||
|
|
188
|
+
marker(env[GJC_TMUX_OWNER_GENERATION_ENV]) ||
|
|
189
|
+
marker(env[GJC_TMUX_OWNER_STATE_DIR_ENV]) ||
|
|
190
|
+
marker(env[GJC_TMUX_OWNER_SERVER_KEY_ENV]) ||
|
|
191
|
+
Object.entries(env).some(([key, value]) => key.startsWith("GJC_TEAM_") && marker(value))
|
|
192
|
+
)
|
|
193
|
+
return "managed";
|
|
194
|
+
return plan.attachSessionName ? "continuation" : "fresh";
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
type PsmuxSessionInventory =
|
|
198
|
+
| { kind: "available"; names: ReadonlySet<string> }
|
|
199
|
+
| { kind: "no-server" }
|
|
200
|
+
| { kind: "unverifiable"; result: TmuxSpawnResult };
|
|
201
|
+
|
|
202
|
+
function classifyPsmuxSessionInventory(result: TmuxSpawnResult): PsmuxSessionInventory {
|
|
203
|
+
if (result.exitCode === 0) {
|
|
204
|
+
const names = new Set(
|
|
205
|
+
(result.stdout ?? "")
|
|
206
|
+
.split(/\r?\n/)
|
|
207
|
+
.map(name => name.trim())
|
|
208
|
+
.filter(Boolean),
|
|
209
|
+
);
|
|
210
|
+
return { kind: "available", names };
|
|
211
|
+
}
|
|
212
|
+
const stderr = result.stderr?.trim() ?? "";
|
|
213
|
+
if (/\bno server running\b/i.test(stderr)) return { kind: "no-server" };
|
|
214
|
+
return { kind: "unverifiable", result };
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function launchWindowsPsmuxCompatibilitySession(
|
|
218
|
+
plan: TmuxLaunchPlan,
|
|
219
|
+
env: NodeJS.ProcessEnv,
|
|
220
|
+
spawnSync: TmuxSpawnSync,
|
|
221
|
+
diagnostic: (message: string) => void,
|
|
222
|
+
): boolean {
|
|
223
|
+
const options: TmuxSpawnOptions = {
|
|
224
|
+
cwd: plan.cwd,
|
|
225
|
+
env,
|
|
226
|
+
stdin: "pipe",
|
|
227
|
+
stdout: "pipe",
|
|
228
|
+
stderr: "pipe",
|
|
229
|
+
captureStderr: true,
|
|
230
|
+
};
|
|
231
|
+
const attachOptions: TmuxSpawnOptions = { ...options, stdin: "inherit", stdout: "inherit", stderr: "inherit" };
|
|
232
|
+
const state = windowsPsmuxCompatibilityState(plan, env);
|
|
233
|
+
if (state === "managed") {
|
|
234
|
+
diagnostic("psmux cannot provide immutable owner identity; refusing managed session creation.\n");
|
|
235
|
+
throw new Error("gjc_tmux_owner_isolation_native_session_identity_unavailable");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const targetName = plan.attachSessionName ?? plan.sessionName;
|
|
239
|
+
const inventory = (): PsmuxSessionInventory =>
|
|
240
|
+
classifyPsmuxSessionInventory(spawnSync(plan.tmuxCommand, ["list-sessions", "-F", "#{session_name}"], options));
|
|
241
|
+
|
|
242
|
+
if (state === "continuation") {
|
|
243
|
+
const existing = inventory();
|
|
244
|
+
const detail = existing.kind === "unverifiable" ? existing.result.stderr : undefined;
|
|
245
|
+
diagnostic(
|
|
246
|
+
formatTmuxLaunchDiagnostic(
|
|
247
|
+
existing.kind === "available" && existing.names.has(targetName)
|
|
248
|
+
? "existing psmux session is name-only and cannot be attached safely"
|
|
249
|
+
: "existing session target not found",
|
|
250
|
+
detail,
|
|
251
|
+
),
|
|
252
|
+
);
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const before = inventory();
|
|
257
|
+
if (before.kind === "unverifiable") {
|
|
258
|
+
diagnostic(formatTmuxLaunchDiagnostic("fresh session inventory failed", before.result.stderr));
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
if (before.kind === "available" && before.names.has(targetName)) {
|
|
262
|
+
diagnostic("tmux fresh session target already exists; preserving session without mutation.\n");
|
|
263
|
+
return true;
|
|
264
|
+
}
|
|
265
|
+
const detachedIndex = plan.newSessionArgs.indexOf("-d");
|
|
266
|
+
const foregroundArgs =
|
|
267
|
+
detachedIndex < 0
|
|
268
|
+
? plan.newSessionArgs
|
|
269
|
+
: [...plan.newSessionArgs.slice(0, detachedIndex), ...plan.newSessionArgs.slice(detachedIndex + 1)];
|
|
270
|
+
const created = spawnSync(plan.tmuxCommand, foregroundArgs, attachOptions);
|
|
271
|
+
if (created.exitCode !== 0) {
|
|
272
|
+
const wrapperWarning = detectCorruptedGjcWrapper();
|
|
273
|
+
const suffix = wrapperWarning ? ` Wrapper warning: ${wrapperWarning}` : "";
|
|
274
|
+
diagnostic(formatTmuxLaunchDiagnostic("foreground new-session failed", created.stderr) + suffix);
|
|
275
|
+
}
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
166
278
|
|
|
167
279
|
function findExistingSessionForLaunch(context: {
|
|
168
280
|
env: NodeJS.ProcessEnv;
|
|
@@ -214,20 +326,6 @@ function buildPosixTmuxExitMarkerPrefix(markerPath: string): string {
|
|
|
214
326
|
].join("; ");
|
|
215
327
|
}
|
|
216
328
|
|
|
217
|
-
function buildPowerShellTmuxExitMarkerFinally(markerPath: string): string {
|
|
218
|
-
const markerDir = path.win32.dirname(markerPath);
|
|
219
|
-
return [
|
|
220
|
-
"} finally {",
|
|
221
|
-
"\ttry {",
|
|
222
|
-
`\t\tNew-Item -ItemType Directory -Force -Path ${powershellQuote(markerDir)} -ErrorAction Stop | Out-Null`,
|
|
223
|
-
"\t\t$__gjcTmuxExitMarker = @{ schema_version = 1; source = 'tmux_inner_shell'; ended_at = (Get-Date).ToUniversalTime().ToString('o'); exit_code = $__gjcTmuxExitCode } | ConvertTo-Json -Compress",
|
|
224
|
-
`\t\tSet-Content -LiteralPath ${powershellQuote(markerPath)} -Value $__gjcTmuxExitMarker -Encoding UTF8 -ErrorAction Stop`,
|
|
225
|
-
"\t} catch {",
|
|
226
|
-
"\t}",
|
|
227
|
-
"}",
|
|
228
|
-
].join("\n");
|
|
229
|
-
}
|
|
230
|
-
|
|
231
329
|
interface CommandResolutionContext {
|
|
232
330
|
cwd: string;
|
|
233
331
|
argv: string[];
|
|
@@ -258,7 +356,13 @@ function isInteractiveRootLaunch(parsed: Args, tty: TtyState): boolean {
|
|
|
258
356
|
}
|
|
259
357
|
|
|
260
358
|
function isBunVirtualPath(value: string | undefined): boolean {
|
|
261
|
-
|
|
359
|
+
const normalized = value?.trim().replace(/\\/g, "/").toLowerCase();
|
|
360
|
+
return (
|
|
361
|
+
normalized === "/$bunfs" ||
|
|
362
|
+
normalized?.startsWith("/$bunfs/") === true ||
|
|
363
|
+
normalized === "b:/~bun" ||
|
|
364
|
+
normalized?.startsWith("b:/~bun/") === true
|
|
365
|
+
);
|
|
262
366
|
}
|
|
263
367
|
|
|
264
368
|
const MAX_TMUX_DIAGNOSTIC_DETAIL_CODE_POINTS = 240;
|
|
@@ -347,55 +451,10 @@ function buildEnvAssignments(values: Record<string, string> | undefined): string
|
|
|
347
451
|
const entries = Object.entries(values ?? {});
|
|
348
452
|
return entries.length === 0 ? "" : ` ${entries.map(([key, value]) => `${key}=${shellQuote(value)}`).join(" ")}`;
|
|
349
453
|
}
|
|
350
|
-
function powershellQuote(value: string): string {
|
|
351
|
-
return `'${value.replace(/'/g, "''")}'`;
|
|
352
|
-
}
|
|
353
454
|
function stripRootTmuxFlag(rawArgs: string[]): string[] {
|
|
354
455
|
return rawArgs.filter(arg => arg !== "--tmux");
|
|
355
456
|
}
|
|
356
457
|
|
|
357
|
-
function buildWindowsPowerShellInnerCommand(context: CommandResolutionContext, rawArgs: string[]): string {
|
|
358
|
-
const command = resolveCurrentGjcCommand(context);
|
|
359
|
-
const envLines = Object.entries({ [GJC_TMUX_LAUNCHED_ENV]: "1", ...(context.extraEnv ?? {}) }).map(
|
|
360
|
-
([key, value]) => `$env:${key} = ${powershellQuote(value)}`,
|
|
361
|
-
);
|
|
362
|
-
// Resolve the inner command and arguments. PowerShell's `&` call operator
|
|
363
|
-
// accepts a single command followed by its arguments directly (no script
|
|
364
|
-
// block needed). Wrapping the call in `& { ... }` would be invalid because
|
|
365
|
-
// adjacent single-quoted tokens inside a script block body are a parser
|
|
366
|
-
// error: `& { 'a' 'b' }` fails with "Unexpected token 'b'" because PowerShell
|
|
367
|
-
// only concatenates adjacent *double-quoted* strings, and even then only in
|
|
368
|
-
// expression position. Emitting the arguments as a comma-separated array
|
|
369
|
-
// (`& 'cmd' @('a','b')`) is also rejected because arrays are not valid as
|
|
370
|
-
// the second-and-later positional arguments to `&` in command position. The
|
|
371
|
-
// correct form is `& 'cmd' 'arg1' 'arg2'` — exactly what the joined
|
|
372
|
-
// resolvedCommand + innerArgs produces below.
|
|
373
|
-
const resolvedCommand = command.map(powershellQuote).join(" ");
|
|
374
|
-
const innerArgs = stripRootTmuxFlag(rawArgs).map(powershellQuote).join(" ");
|
|
375
|
-
const invocation = `& ${resolvedCommand} ${innerArgs}`;
|
|
376
|
-
const exitLine = "if ($null -ne $LASTEXITCODE) { exit $LASTEXITCODE } else { exit 1 }";
|
|
377
|
-
const script = context.tmuxExitMarkerPath
|
|
378
|
-
? [
|
|
379
|
-
...envLines,
|
|
380
|
-
"$__gjcTmuxExitCode = 1",
|
|
381
|
-
"try {",
|
|
382
|
-
`\t${invocation}`,
|
|
383
|
-
"\tif ($null -ne $LASTEXITCODE) { $__gjcTmuxExitCode = $LASTEXITCODE } else { $__gjcTmuxExitCode = 1 }",
|
|
384
|
-
buildPowerShellTmuxExitMarkerFinally(context.tmuxExitMarkerPath),
|
|
385
|
-
"exit $__gjcTmuxExitCode",
|
|
386
|
-
].join("\n")
|
|
387
|
-
: [...envLines, invocation, exitLine].join("\n");
|
|
388
|
-
// Encode the script as UTF-16LE base64 for pwsh -EncodedCommand. Do NOT
|
|
389
|
-
// prepend a UTF-16LE BOM (0xFF 0xFE): the BOM survives the decode and is
|
|
390
|
-
// inserted as a literal U+FEFF character in front of the first script
|
|
391
|
-
// token, which pwsh then reports as a "term not recognized" parse error
|
|
392
|
-
// (e.g. "$env:GJC_TMUX_LAUNCHED"). pwsh expects the decoded buffer to
|
|
393
|
-
// start with the first character of the script, not with a BOM.
|
|
394
|
-
const body = Buffer.from(script, "utf16le");
|
|
395
|
-
const encodedCommand = body.toString("base64");
|
|
396
|
-
return `pwsh -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand ${encodedCommand}`;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
458
|
export function applyGjcTmuxProfile(context: GjcTmuxProfileContext): GjcTmuxProfileResult {
|
|
400
459
|
const env = context.env ?? process.env;
|
|
401
460
|
const branchSlug = context.branch ? buildGjcTmuxSessionSlug(context.branch) : (context.branchSlug ?? null);
|
|
@@ -441,19 +500,41 @@ export function applyGjcTmuxProfile(context: GjcTmuxProfileContext): GjcTmuxProf
|
|
|
441
500
|
}
|
|
442
501
|
|
|
443
502
|
function resolveCurrentGjcCommand(context: CommandResolutionContext): string[] {
|
|
444
|
-
const entrypoint = context.argv[1];
|
|
445
|
-
if (!entrypoint) return ["gjc"];
|
|
446
|
-
if (isBunVirtualPath(entrypoint)) {
|
|
447
|
-
return isBunVirtualPath(context.execPath) ? ["gjc"] : [context.execPath];
|
|
448
|
-
}
|
|
449
503
|
const pathModule = pathModuleForPlatform(context.platform);
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
504
|
+
const isRealAbsolutePath = (value: string | undefined): value is string => {
|
|
505
|
+
const normalized = value?.trim();
|
|
506
|
+
if (!normalized || isBunVirtualPath(normalized)) return false;
|
|
507
|
+
return pathModule.isAbsolute(normalized) || path.isAbsolute(normalized);
|
|
508
|
+
};
|
|
509
|
+
const isGjcExecutable = (value: string | undefined): value is string =>
|
|
510
|
+
isRealAbsolutePath(value) && /^gjc(?:[._-]|$)/i.test(pathModule.basename(value.trim()));
|
|
511
|
+
|
|
512
|
+
const runtime = context.argv[0]?.trim();
|
|
513
|
+
const entrypoint = context.argv[1]?.trim();
|
|
514
|
+
if (entrypoint && !isBunVirtualPath(entrypoint) && /\.(?:[cm]?[jt]s)$/i.test(entrypoint)) {
|
|
515
|
+
const executable = isRealAbsolutePath(runtime)
|
|
516
|
+
? runtime
|
|
517
|
+
: isRealAbsolutePath(context.execPath)
|
|
518
|
+
? context.execPath.trim()
|
|
519
|
+
: undefined;
|
|
520
|
+
if (!executable)
|
|
521
|
+
throw new Error(
|
|
522
|
+
"Unable to determine the current GJC source runtime for tmux launch; invoke GJC through an absolute runtime path.",
|
|
523
|
+
);
|
|
524
|
+
const resolvedEntrypoint = pathModule.isAbsolute(entrypoint)
|
|
525
|
+
? entrypoint
|
|
526
|
+
: pathModule.resolve(context.cwd, entrypoint);
|
|
527
|
+
return [executable, resolvedEntrypoint];
|
|
455
528
|
}
|
|
456
|
-
|
|
529
|
+
|
|
530
|
+
const executable =
|
|
531
|
+
(isGjcExecutable(entrypoint) ? entrypoint : undefined) ??
|
|
532
|
+
(isGjcExecutable(runtime) ? runtime : undefined) ??
|
|
533
|
+
(isGjcExecutable(context.execPath) ? context.execPath.trim() : undefined);
|
|
534
|
+
if (executable) return [executable];
|
|
535
|
+
throw new Error(
|
|
536
|
+
"Unable to determine the current GJC executable for tmux launch; Bun virtual paths and PATH fallback are not accepted.",
|
|
537
|
+
);
|
|
457
538
|
}
|
|
458
539
|
function isWindowsPlatform(platform: NodeJS.Platform | undefined): boolean {
|
|
459
540
|
return platform === "win32";
|
|
@@ -463,7 +544,13 @@ function pathModuleForPlatform(platform: NodeJS.Platform | undefined): typeof pa
|
|
|
463
544
|
}
|
|
464
545
|
|
|
465
546
|
function buildInnerCommand(context: CommandResolutionContext, rawArgs: string[]): string {
|
|
466
|
-
if (isWindowsPlatform(context.platform))
|
|
547
|
+
if (isWindowsPlatform(context.platform))
|
|
548
|
+
return buildWindowsPowerShellInnerCommand({
|
|
549
|
+
command: resolveCurrentGjcCommand(context),
|
|
550
|
+
args: stripRootTmuxFlag(rawArgs),
|
|
551
|
+
environment: context.extraEnv,
|
|
552
|
+
tmuxExitMarkerPath: context.tmuxExitMarkerPath,
|
|
553
|
+
});
|
|
467
554
|
const command = resolveCurrentGjcCommand(context);
|
|
468
555
|
const quoted = [...command, ...stripRootTmuxFlag(rawArgs)].map(shellQuote).join(" ");
|
|
469
556
|
const invocation = `env ${GJC_TMUX_LAUNCHED_ENV}=1${buildEnvAssignments(context.extraEnv)} ${quoted}`;
|
|
@@ -1175,12 +1262,17 @@ export function launchDefaultTmuxIfNeeded(context: TmuxLaunchContext): boolean {
|
|
|
1175
1262
|
// window rename and provider refusal so inapplicable root launches reach main
|
|
1176
1263
|
// unchanged, while unsupported managed launches fail before any tmux mutation.
|
|
1177
1264
|
const plan = buildDefaultTmuxLaunchPlan(context);
|
|
1178
|
-
if (plan
|
|
1179
|
-
(
|
|
1180
|
-
|
|
1181
|
-
);
|
|
1182
|
-
throw new Error("gjc_tmux_owner_isolation_native_session_identity_unavailable");
|
|
1265
|
+
if (!plan && env.TMUX && (context.platform ?? process.platform) === "win32") {
|
|
1266
|
+
const ambientProvider = resolveGjcTmuxBinary({ platform: "win32", env });
|
|
1267
|
+
if (ambientProvider.isPsmux) return false;
|
|
1183
1268
|
}
|
|
1269
|
+
if (plan?.isPsmux && plan.platform === "win32" && !env.TMUX)
|
|
1270
|
+
return launchWindowsPsmuxCompatibilitySession(
|
|
1271
|
+
plan,
|
|
1272
|
+
env,
|
|
1273
|
+
context.spawnSync ?? defaultSpawnSync,
|
|
1274
|
+
context.diagnosticWriter ?? safeStderrWrite,
|
|
1275
|
+
);
|
|
1184
1276
|
// Direct launches inside an ambient tmux session retain their existing title
|
|
1185
1277
|
// behavior, but only after managed-launch applicability was ruled out.
|
|
1186
1278
|
renameExistingTmuxWindowIfNeeded(context);
|
|
@@ -1218,14 +1310,6 @@ export function launchDefaultTmuxIfNeeded(context: TmuxLaunchContext): boolean {
|
|
|
1218
1310
|
context.ownerIsolationProbe ?? defaultOwnerIsolationProbe(plan, env, rawSpawnSync, context.callerCgroupReader);
|
|
1219
1311
|
const spawnSync = rawSpawnSync;
|
|
1220
1312
|
const attachOptions: TmuxSpawnOptions = { ...options };
|
|
1221
|
-
// Psmux is rejected before planning any tmux mutation, including an ambient
|
|
1222
|
-
// TMUX window rename. Keep this defense in depth guard for future plan seams.
|
|
1223
|
-
if (plan.isPsmux) {
|
|
1224
|
-
(context.diagnosticWriter ?? safeStderrWrite)(
|
|
1225
|
-
"psmux cannot provide immutable owner identity; refusing managed session creation.\n",
|
|
1226
|
-
);
|
|
1227
|
-
throw new Error("gjc_tmux_owner_isolation_native_session_identity_unavailable");
|
|
1228
|
-
}
|
|
1229
1313
|
const controlOptions: TmuxSpawnOptions = {
|
|
1230
1314
|
...options,
|
|
1231
1315
|
stdin: "pipe",
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Windows psmux detection and tmux-binary resolution.
|
|
3
5
|
*
|
|
@@ -45,8 +47,7 @@ const DEFAULT_BINARY_RESOLVER: BinaryResolver = candidate => {
|
|
|
45
47
|
if (!candidate) return null;
|
|
46
48
|
const stripped = candidate.trim().replace(/^["']|["']$/g, "");
|
|
47
49
|
if (!stripped) return null;
|
|
48
|
-
|
|
49
|
-
return null;
|
|
50
|
+
return Bun.which(stripped);
|
|
50
51
|
};
|
|
51
52
|
|
|
52
53
|
let activeBinaryResolver: BinaryResolver = DEFAULT_BINARY_RESOLVER;
|
|
@@ -56,6 +57,25 @@ export function __setBinaryResolverForTests(resolver: BinaryResolver | null): vo
|
|
|
56
57
|
activeBinaryResolver = resolver ?? DEFAULT_BINARY_RESOLVER;
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
export type ExecutableIdentityResolver = (path: string) => string | null;
|
|
61
|
+
|
|
62
|
+
const DEFAULT_EXECUTABLE_IDENTITY_RESOLVER: ExecutableIdentityResolver = executablePath => {
|
|
63
|
+
try {
|
|
64
|
+
const realPath = fs.realpathSync.native(executablePath);
|
|
65
|
+
const stat = fs.statSync(realPath);
|
|
66
|
+
return stat.ino === 0 ? realPath.toLowerCase() : `${stat.dev}:${stat.ino}`;
|
|
67
|
+
} catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
let activeExecutableIdentityResolver: ExecutableIdentityResolver = DEFAULT_EXECUTABLE_IDENTITY_RESOLVER;
|
|
73
|
+
|
|
74
|
+
/** @internal Test-only seam; production code never calls this. */
|
|
75
|
+
export function __setExecutableIdentityResolverForTests(resolver: ExecutableIdentityResolver | null): void {
|
|
76
|
+
activeExecutableIdentityResolver = resolver ?? DEFAULT_EXECUTABLE_IDENTITY_RESOLVER;
|
|
77
|
+
}
|
|
78
|
+
|
|
59
79
|
interface CacheEntry {
|
|
60
80
|
command: string;
|
|
61
81
|
isPsmux: boolean;
|
|
@@ -140,6 +160,62 @@ function detectPsmuxForCommand(command: string, runner: PsmuxSpawnRunner): boole
|
|
|
140
160
|
return outputMentionsPsmux(output);
|
|
141
161
|
}
|
|
142
162
|
|
|
163
|
+
function classifyWindowsTmuxAlias(command: string, env: NodeJS.ProcessEnv, runner: PsmuxSpawnRunner): boolean {
|
|
164
|
+
if (isNamedPsmuxCommand(command)) return true;
|
|
165
|
+
try {
|
|
166
|
+
if (detectPsmuxForCommand(command, runner)) return true;
|
|
167
|
+
} catch {
|
|
168
|
+
throw new Error("gjc_tmux_provider_ambiguous: selected Windows tmux command resolution failed");
|
|
169
|
+
}
|
|
170
|
+
if (normalizedCommandBaseName(command) !== "tmux" && !env[GJC_PSMUX_COMMAND_ENV]?.trim()) return false;
|
|
171
|
+
|
|
172
|
+
let selectedPath: string | null;
|
|
173
|
+
try {
|
|
174
|
+
selectedPath = resolveBinaryPath(command);
|
|
175
|
+
} catch {
|
|
176
|
+
throw new Error("gjc_tmux_provider_ambiguous: selected Windows tmux command resolution failed");
|
|
177
|
+
}
|
|
178
|
+
if (!selectedPath) {
|
|
179
|
+
throw new Error("gjc_tmux_provider_ambiguous: selected Windows tmux command could not be resolved");
|
|
180
|
+
}
|
|
181
|
+
const selectedIdentity = activeExecutableIdentityResolver(selectedPath);
|
|
182
|
+
if (!selectedIdentity) {
|
|
183
|
+
throw new Error("gjc_tmux_provider_ambiguous: selected Windows tmux executable identity is unavailable");
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const explicitCompanion = env[GJC_PSMUX_COMMAND_ENV]?.trim();
|
|
187
|
+
const companions = [
|
|
188
|
+
...new Set([explicitCompanion, "psmux", "pmux"].filter((value): value is string => Boolean(value))),
|
|
189
|
+
];
|
|
190
|
+
let matched = false;
|
|
191
|
+
let distinct = false;
|
|
192
|
+
for (const companion of companions) {
|
|
193
|
+
let companionPath: string | null;
|
|
194
|
+
try {
|
|
195
|
+
companionPath = resolveBinaryPath(companion);
|
|
196
|
+
} catch {
|
|
197
|
+
throw new Error(`gjc_tmux_provider_ambiguous: Windows ${companion} command resolution failed`);
|
|
198
|
+
}
|
|
199
|
+
if (!companionPath) {
|
|
200
|
+
if (companion === explicitCompanion)
|
|
201
|
+
throw new Error("gjc_tmux_provider_ambiguous: GJC_PSMUX_COMMAND could not be resolved");
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const companionIdentity = activeExecutableIdentityResolver(companionPath);
|
|
205
|
+
if (!companionIdentity) {
|
|
206
|
+
throw new Error(`gjc_tmux_provider_ambiguous: Windows ${companion} executable identity is unavailable`);
|
|
207
|
+
}
|
|
208
|
+
if (companionIdentity === selectedIdentity) matched = true;
|
|
209
|
+
else {
|
|
210
|
+
distinct = true;
|
|
211
|
+
if (companion === explicitCompanion)
|
|
212
|
+
throw new Error("gjc_tmux_provider_ambiguous: GJC_PSMUX_COMMAND selects a different executable");
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (matched && distinct) throw new Error("gjc_tmux_provider_ambiguous: Windows psmux companion identities conflict");
|
|
216
|
+
return matched;
|
|
217
|
+
}
|
|
218
|
+
|
|
143
219
|
/**
|
|
144
220
|
* Decide whether command resolves to a psmux binary by probing its version
|
|
145
221
|
* output. The result is cached per process unless force is set or
|
|
@@ -209,13 +285,15 @@ export function resolveGjcTmuxBinary(options: ResolveGjcTmuxBinaryOptions = {}):
|
|
|
209
285
|
const explicit = env.GJC_TMUX_COMMAND?.trim() || env.GJC_TEAM_TMUX_COMMAND?.trim();
|
|
210
286
|
if (explicit) {
|
|
211
287
|
const isPsmux =
|
|
212
|
-
platform === "win32"
|
|
288
|
+
platform === "win32"
|
|
289
|
+
? classifyWindowsTmuxAlias(explicit, env, runner)
|
|
290
|
+
: detectPsmux(explicit, { env, runner });
|
|
213
291
|
return { command: explicit, isPsmux, viaExplicitOverride: true };
|
|
214
292
|
}
|
|
215
293
|
if (platform === "win32") {
|
|
216
294
|
for (const candidate of PSMUX_BINARY_NAMES) {
|
|
217
295
|
if (resolveBinaryPath(candidate)) {
|
|
218
|
-
const isPsmux =
|
|
296
|
+
const isPsmux = classifyWindowsTmuxAlias(candidate, env, runner);
|
|
219
297
|
return { command: candidate, isPsmux, viaExplicitOverride: false };
|
|
220
298
|
}
|
|
221
299
|
}
|
|
@@ -3,7 +3,7 @@ import * as fsSync from "node:fs";
|
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import type { AssistantMessage } from "@gajae-code/ai";
|
|
6
|
-
import { postmortem } from "@gajae-code/utils";
|
|
6
|
+
import { normalizePathForComparison, postmortem } from "@gajae-code/utils";
|
|
7
7
|
import { sessionRuntimeDir } from "./session-layout";
|
|
8
8
|
import {
|
|
9
9
|
isValidOwnerIntent,
|
|
@@ -76,6 +76,8 @@ export interface RuntimeStateContext {
|
|
|
76
76
|
sessionId: string;
|
|
77
77
|
cwd: string;
|
|
78
78
|
sessionFile?: string | null;
|
|
79
|
+
/** Optional platform seam for deterministic cross-platform path identity checks. */
|
|
80
|
+
platform?: NodeJS.Platform;
|
|
79
81
|
branch?: string | null;
|
|
80
82
|
/** Public-safe owner metadata used to persist the canonical terminal verdict. */
|
|
81
83
|
ownerTerminal?: OwnerTerminalContext | null;
|
|
@@ -83,6 +85,14 @@ export interface RuntimeStateContext {
|
|
|
83
85
|
ownerTerminalMetadataInvalid?: boolean;
|
|
84
86
|
}
|
|
85
87
|
|
|
88
|
+
interface RuntimeStateIdentity {
|
|
89
|
+
sessionId: string;
|
|
90
|
+
cwd: string;
|
|
91
|
+
workdir: string;
|
|
92
|
+
sessionFile: string | null;
|
|
93
|
+
platform: NodeJS.Platform;
|
|
94
|
+
}
|
|
95
|
+
|
|
86
96
|
interface RuntimeStateSidecarPayload {
|
|
87
97
|
schema_version?: unknown;
|
|
88
98
|
session_id?: unknown;
|
|
@@ -201,27 +211,27 @@ export async function persistCoordinatorRuntimeInputReady(): Promise<RuntimeInpu
|
|
|
201
211
|
}
|
|
202
212
|
}
|
|
203
213
|
|
|
204
|
-
function sameResolvedPath(left: string, right: string): boolean {
|
|
205
|
-
return
|
|
214
|
+
function sameResolvedPath(left: string, right: string, platform: NodeJS.Platform = process.platform): boolean {
|
|
215
|
+
return normalizePathForComparison(left, platform) === normalizePathForComparison(right, platform);
|
|
206
216
|
}
|
|
207
217
|
|
|
208
|
-
function normalizedIdentity(
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
workdir: string;
|
|
212
|
-
sessionFile: string | null;
|
|
213
|
-
} {
|
|
218
|
+
function normalizedIdentity(
|
|
219
|
+
context: Pick<RuntimeStateContext, "sessionId" | "cwd" | "sessionFile" | "platform">,
|
|
220
|
+
): RuntimeStateIdentity {
|
|
214
221
|
const explicitStateFile = process.env[GJC_COORDINATOR_SESSION_STATE_FILE_ENV]?.trim();
|
|
215
222
|
const sessionId = explicitStateFile
|
|
216
223
|
? process.env[GJC_COORDINATOR_SESSION_ID_ENV]?.trim() || context.sessionId.trim()
|
|
217
224
|
: context.sessionId.trim();
|
|
218
225
|
const cwd = context.cwd.trim();
|
|
226
|
+
const platform = context.platform ?? process.platform;
|
|
227
|
+
const pathApi = platform === "win32" ? path.win32 : path;
|
|
219
228
|
if (!sessionId || !cwd) throw new PreviousRuntimeStateReadError();
|
|
220
229
|
return {
|
|
221
230
|
sessionId,
|
|
222
|
-
cwd:
|
|
223
|
-
workdir:
|
|
224
|
-
sessionFile: context.sessionFile == null ? null :
|
|
231
|
+
cwd: pathApi.resolve(cwd),
|
|
232
|
+
workdir: pathApi.resolve(cwd),
|
|
233
|
+
sessionFile: context.sessionFile == null ? null : pathApi.resolve(context.sessionFile),
|
|
234
|
+
platform,
|
|
225
235
|
};
|
|
226
236
|
}
|
|
227
237
|
|
|
@@ -268,7 +278,10 @@ export async function readTerminalRuntimeStateMarker(input: {
|
|
|
268
278
|
sessionId?: string | null;
|
|
269
279
|
cwd?: string | null;
|
|
270
280
|
sessionFile?: string | null;
|
|
281
|
+
platform?: NodeJS.Platform;
|
|
271
282
|
}): Promise<TerminalRuntimeStateStatus> {
|
|
283
|
+
const platform = input.platform ?? process.platform;
|
|
284
|
+
const pathApi = platform === "win32" ? path.win32 : path;
|
|
272
285
|
const stateFile = input.stateFile?.trim();
|
|
273
286
|
const sessionId = input.sessionId?.trim();
|
|
274
287
|
const cwd = input.cwd?.trim();
|
|
@@ -287,15 +300,18 @@ export async function readTerminalRuntimeStateMarker(input: {
|
|
|
287
300
|
if (!validRuntimeStateMarker(value)) return { terminal: false, reason: "invalid_state_marker" };
|
|
288
301
|
const payload = value;
|
|
289
302
|
if (payload.session_id !== sessionId) return { terminal: false, reason: "session_id_mismatch" };
|
|
290
|
-
if (
|
|
303
|
+
if (
|
|
304
|
+
!sameResolvedPath(payload.cwd as string, cwd, platform) ||
|
|
305
|
+
!sameResolvedPath(payload.workdir as string, cwd, platform)
|
|
306
|
+
)
|
|
291
307
|
return { terminal: false, reason: "cwd_mismatch" };
|
|
292
|
-
const sessionFile = input.sessionFile == null ? null :
|
|
308
|
+
const sessionFile = input.sessionFile == null ? null : pathApi.resolve(input.sessionFile);
|
|
293
309
|
if (
|
|
294
310
|
payload.session_file !== sessionFile &&
|
|
295
311
|
!(
|
|
296
312
|
typeof payload.session_file === "string" &&
|
|
297
313
|
typeof sessionFile === "string" &&
|
|
298
|
-
sameResolvedPath(payload.session_file, sessionFile)
|
|
314
|
+
sameResolvedPath(payload.session_file, sessionFile, platform)
|
|
299
315
|
)
|
|
300
316
|
)
|
|
301
317
|
return { terminal: false, reason: "session_file_mismatch" };
|
|
@@ -484,41 +500,35 @@ function rememberWrittenPayload(stateFile: string, payload: Record<string, unkno
|
|
|
484
500
|
lastPayloadByStateFile.delete(stateFile);
|
|
485
501
|
}
|
|
486
502
|
}
|
|
487
|
-
function shouldPreserveTerminalPayload(
|
|
488
|
-
previous: RuntimeStateSidecarPayload,
|
|
489
|
-
input: { sessionId: string; cwd: string; sessionFile: string | null },
|
|
490
|
-
): boolean {
|
|
503
|
+
function shouldPreserveTerminalPayload(previous: RuntimeStateSidecarPayload, input: RuntimeStateIdentity): boolean {
|
|
491
504
|
if (!validRuntimeStateMarker(previous)) return false;
|
|
492
505
|
if (previous.state !== "completed" && previous.state !== "errored") return false;
|
|
493
506
|
const source = previous.final_response?.source;
|
|
494
507
|
if (source !== "agent_end" && source !== "launch_error") return false;
|
|
495
508
|
return (
|
|
496
509
|
previous.session_id === input.sessionId &&
|
|
497
|
-
sameResolvedPath(previous.cwd as string, input.cwd) &&
|
|
498
|
-
sameResolvedPath(previous.workdir as string, input.cwd) &&
|
|
510
|
+
sameResolvedPath(previous.cwd as string, input.cwd, input.platform) &&
|
|
511
|
+
sameResolvedPath(previous.workdir as string, input.cwd, input.platform) &&
|
|
499
512
|
(previous.session_file === input.sessionFile ||
|
|
500
513
|
(typeof previous.session_file === "string" &&
|
|
501
514
|
typeof input.sessionFile === "string" &&
|
|
502
|
-
sameResolvedPath(previous.session_file, input.sessionFile)))
|
|
515
|
+
sameResolvedPath(previous.session_file, input.sessionFile, input.platform)))
|
|
503
516
|
);
|
|
504
517
|
}
|
|
505
518
|
|
|
506
|
-
function assertPreviousRuntimeStateIdentity(
|
|
507
|
-
previous: Record<string, unknown>,
|
|
508
|
-
input: { sessionId: string; cwd: string; sessionFile: string | null },
|
|
509
|
-
): void {
|
|
519
|
+
function assertPreviousRuntimeStateIdentity(previous: Record<string, unknown>, input: RuntimeStateIdentity): void {
|
|
510
520
|
if (Object.keys(previous).length === 0) return;
|
|
511
521
|
if (
|
|
512
522
|
previous.session_id !== input.sessionId ||
|
|
513
523
|
typeof previous.cwd !== "string" ||
|
|
514
524
|
typeof previous.workdir !== "string" ||
|
|
515
|
-
!sameResolvedPath(previous.cwd, input.cwd) ||
|
|
516
|
-
!sameResolvedPath(previous.workdir, input.cwd) ||
|
|
525
|
+
!sameResolvedPath(previous.cwd, input.cwd, input.platform) ||
|
|
526
|
+
!sameResolvedPath(previous.workdir, input.cwd, input.platform) ||
|
|
517
527
|
(previous.session_file !== input.sessionFile &&
|
|
518
528
|
!(
|
|
519
529
|
typeof previous.session_file === "string" &&
|
|
520
530
|
typeof input.sessionFile === "string" &&
|
|
521
|
-
sameResolvedPath(previous.session_file, input.sessionFile)
|
|
531
|
+
sameResolvedPath(previous.session_file, input.sessionFile, input.platform)
|
|
522
532
|
))
|
|
523
533
|
)
|
|
524
534
|
throw new PreviousRuntimeStateReadError();
|
|
@@ -1112,7 +1122,7 @@ export async function persistCoordinatorRuntimeStateFromPostmortem(
|
|
|
1112
1122
|
if (shouldPreserveTerminalPayload(previous as RuntimeStateSidecarPayload, identity)) return;
|
|
1113
1123
|
// The immutable owner verdict remains in its lifecycle artifact; never replace a
|
|
1114
1124
|
// complete agent terminal payload merely to mirror that verdict here.
|
|
1115
|
-
if (
|
|
1125
|
+
if (context.ownerTerminalMetadataInvalid) {
|
|
1116
1126
|
await persistInvalidOwnerTerminalMetadata(
|
|
1117
1127
|
reason,
|
|
1118
1128
|
context,
|
|
@@ -1122,7 +1132,7 @@ export async function persistCoordinatorRuntimeStateFromPostmortem(
|
|
|
1122
1132
|
);
|
|
1123
1133
|
return;
|
|
1124
1134
|
}
|
|
1125
|
-
if (
|
|
1135
|
+
if (context.ownerTerminal) {
|
|
1126
1136
|
await persistCoordinatorRuntimeStateFromOwnerTerminalPostmortem(
|
|
1127
1137
|
reason,
|
|
1128
1138
|
context,
|