@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
|
@@ -2,7 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { getWorktreesDir } from "@gajae-code/utils/dirs";
|
|
5
|
-
import { SPAWN_PROVENANCE_ENV } from "../
|
|
5
|
+
import { SPAWN_PROVENANCE_ENV } from "../sdk/bus/config";
|
|
6
6
|
import type { WorkflowHudSummary } from "../skill-state/active-state";
|
|
7
7
|
import { buildTeamHudSummary as buildWorkflowTeamHudSummary } from "../skill-state/workflow-hud";
|
|
8
8
|
import { WORKFLOW_STATE_VERSION } from "../skill-state/workflow-state-contract";
|
|
@@ -208,7 +208,7 @@ export type GjcTeamNotificationDeliveryState =
|
|
|
208
208
|
| "acknowledged";
|
|
209
209
|
|
|
210
210
|
export type GjcTeamPaneAttemptResult = "sent" | "queued" | "deferred" | "failed";
|
|
211
|
-
export type GjcTeamMailboxDeliveryTransportKind = "
|
|
211
|
+
export type GjcTeamMailboxDeliveryTransportKind = "sdk" | "pane";
|
|
212
212
|
|
|
213
213
|
export interface GjcTeamNotification {
|
|
214
214
|
id: string;
|
|
@@ -235,7 +235,7 @@ export interface GjcTeamMailboxDeliveryInput {
|
|
|
235
235
|
env: NodeJS.ProcessEnv;
|
|
236
236
|
}
|
|
237
237
|
export type GjcTeamMailboxDeliveryResult =
|
|
238
|
-
| { transport: "
|
|
238
|
+
| { transport: "sdk"; state: GjcTeamNotificationDeliveryState; reason?: string }
|
|
239
239
|
| { transport: "pane"; state: GjcTeamPaneAttemptResult; reason?: string };
|
|
240
240
|
export interface GjcTeamMailboxDeliveryTransport {
|
|
241
241
|
deliverMailboxMessage(input: GjcTeamMailboxDeliveryInput): Promise<GjcTeamMailboxDeliveryResult | null>;
|
|
@@ -1995,25 +1995,32 @@ function readCurrentTmuxLeaderContext(tmuxCommand: string, env: NodeJS.ProcessEn
|
|
|
1995
1995
|
}
|
|
1996
1996
|
return { sessionName, windowIndex, leaderPaneId, target: `${sessionName}:${windowIndex}` };
|
|
1997
1997
|
}
|
|
1998
|
-
type CommandPathResolver = (command: string) => string | null;
|
|
1999
|
-
|
|
2000
1998
|
function isBunVirtualPath(candidate: string | undefined): boolean {
|
|
2001
|
-
const normalized = candidate?.trim().replace(/\\/g, "/");
|
|
2002
|
-
return
|
|
1999
|
+
const normalized = candidate?.trim().replace(/\\/g, "/").toLowerCase();
|
|
2000
|
+
return (
|
|
2001
|
+
normalized === "/$bunfs" ||
|
|
2002
|
+
normalized?.startsWith("/$bunfs/") === true ||
|
|
2003
|
+
normalized === "b:/~bun" ||
|
|
2004
|
+
normalized?.startsWith("b:/~bun/") === true
|
|
2005
|
+
);
|
|
2003
2006
|
}
|
|
2004
2007
|
|
|
2005
|
-
function
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
): string {
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2008
|
+
function isAbsoluteRealPath(candidate: string | undefined, pathModule: typeof path): candidate is string {
|
|
2009
|
+
const normalized = candidate?.trim();
|
|
2010
|
+
return Boolean(normalized && !isBunVirtualPath(normalized) && pathModule.isAbsolute(normalized));
|
|
2011
|
+
}
|
|
2012
|
+
function isGjcExecutablePath(candidate: string | undefined, pathModule: typeof path): candidate is string {
|
|
2013
|
+
return isAbsoluteRealPath(candidate, pathModule) && /^gjc(?:[._-]|$)/i.test(pathModule.basename(candidate.trim()));
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
function formatWorkerExecutable(platform: NodeJS.Platform, executable: string): string {
|
|
2017
|
+
return (platform === "win32" ? powershellQuote : shellQuote)(executable);
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
function unresolvedWorkerAuthorityError(): Error {
|
|
2021
|
+
return new Error(
|
|
2022
|
+
"Unable to determine the GJC worker executable from this invocation. Set GJC_TEAM_WORKER_COMMAND to the exact GJC command, or launch GJC from a real executable path instead of a Bun virtual path.",
|
|
2023
|
+
);
|
|
2017
2024
|
}
|
|
2018
2025
|
|
|
2019
2026
|
export function resolveGjcWorkerCommand(
|
|
@@ -2022,24 +2029,36 @@ export function resolveGjcWorkerCommand(
|
|
|
2022
2029
|
platform: NodeJS.Platform = process.platform,
|
|
2023
2030
|
argv: string[] = process.argv,
|
|
2024
2031
|
execPath = process.execPath,
|
|
2025
|
-
which: CommandPathResolver = Bun.which,
|
|
2026
2032
|
): string {
|
|
2027
2033
|
const explicit = env.GJC_TEAM_WORKER_COMMAND?.trim();
|
|
2028
|
-
if (explicit)
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
const
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2034
|
+
if (explicit) {
|
|
2035
|
+
if (isBunVirtualPath(explicit)) throw unresolvedWorkerAuthorityError();
|
|
2036
|
+
return explicit;
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
const pathModule = platform === "win32" ? path.win32 : path.posix;
|
|
2040
|
+
const runtime = argv[0]?.trim();
|
|
2041
|
+
const entrypoint = argv[1]?.trim();
|
|
2042
|
+
const sourceEntrypoint = entrypoint && !isBunVirtualPath(entrypoint) && /\.(?:[cm]?[jt]s)$/i.test(entrypoint);
|
|
2043
|
+
|
|
2044
|
+
if (sourceEntrypoint) {
|
|
2045
|
+
const sourceRuntime = isAbsoluteRealPath(runtime, pathModule)
|
|
2046
|
+
? runtime
|
|
2047
|
+
: isAbsoluteRealPath(execPath, pathModule)
|
|
2048
|
+
? execPath.trim()
|
|
2049
|
+
: undefined;
|
|
2050
|
+
if (!sourceRuntime) throw unresolvedWorkerAuthorityError();
|
|
2051
|
+
const absoluteEntrypoint = pathModule.isAbsolute(entrypoint) ? entrypoint : pathModule.resolve(cwd, entrypoint);
|
|
2052
|
+
if (!isAbsoluteRealPath(absoluteEntrypoint, pathModule)) throw unresolvedWorkerAuthorityError();
|
|
2053
|
+
return `${formatWorkerExecutable(platform, sourceRuntime)} ${formatWorkerExecutable(platform, absoluteEntrypoint)}`;
|
|
2039
2054
|
}
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2055
|
+
|
|
2056
|
+
const executable =
|
|
2057
|
+
(isGjcExecutablePath(entrypoint, pathModule) ? entrypoint : undefined) ??
|
|
2058
|
+
(isGjcExecutablePath(execPath, pathModule) ? execPath.trim() : undefined) ??
|
|
2059
|
+
(isGjcExecutablePath(runtime, pathModule) ? runtime : undefined);
|
|
2060
|
+
if (!executable) throw unresolvedWorkerAuthorityError();
|
|
2061
|
+
return formatWorkerExecutable(platform, executable);
|
|
2043
2062
|
}
|
|
2044
2063
|
/** @internal Exported for unit tests. */
|
|
2045
2064
|
export function buildWorkerCommand(
|
|
@@ -4010,7 +4029,7 @@ async function attemptConfiguredMailboxTransport(
|
|
|
4010
4029
|
env,
|
|
4011
4030
|
});
|
|
4012
4031
|
if (!result) return null;
|
|
4013
|
-
if (result.transport === "
|
|
4032
|
+
if (result.transport === "sdk" && result.state === "failed") return null;
|
|
4014
4033
|
return writeNotificationRecord(dir, {
|
|
4015
4034
|
...notification,
|
|
4016
4035
|
delivery_state: result.state,
|
|
@@ -53,27 +53,63 @@ function isKnownNoServerDiagnostic(stderr: string): boolean {
|
|
|
53
53
|
);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
interface TmuxListSessionsResult {
|
|
57
|
+
exitCode: number | null;
|
|
58
|
+
stdout: string;
|
|
59
|
+
stderr: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
interface TmuxServerProofOptions {
|
|
63
|
+
platform?: NodeJS.Platform;
|
|
64
|
+
runListSessions?: (argv: string[]) => TmuxListSessionsResult;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function runTmuxListSessions(controlArgv: string[]): TmuxListSessionsResult {
|
|
60
68
|
const subprocess = Bun.spawnSync([...controlArgv, "list-sessions", "-F", "#{pid}\t#{session_name}"], {
|
|
61
69
|
stdout: "pipe",
|
|
62
70
|
stderr: "pipe",
|
|
63
71
|
});
|
|
64
|
-
|
|
72
|
+
return {
|
|
73
|
+
exitCode: subprocess.exitCode,
|
|
74
|
+
stdout: Buffer.from(subprocess.stdout).toString(),
|
|
75
|
+
stderr: Buffer.from(subprocess.stderr).toString(),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function parseTmuxSessionRows(stdout: string): { pid: number; sessionNames: string[] } | null {
|
|
80
|
+
const lines = stdout.split("\n");
|
|
81
|
+
if (lines[lines.length - 1] === "") lines.pop();
|
|
82
|
+
let pid: number | undefined;
|
|
83
|
+
const sessionNames: string[] = [];
|
|
84
|
+
for (const rawLine of lines) {
|
|
85
|
+
const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
|
|
86
|
+
const columns = line.split("\t");
|
|
87
|
+
if (columns.length !== 2 || !/^[1-9]\d*$/.test(columns[0]) || !columns[1].trim()) return null;
|
|
88
|
+
const rowPid = Number(columns[0]);
|
|
89
|
+
if (!Number.isSafeInteger(rowPid) || (pid !== undefined && pid !== rowPid)) return null;
|
|
90
|
+
pid = rowPid;
|
|
91
|
+
sessionNames.push(columns[1]);
|
|
92
|
+
}
|
|
93
|
+
return pid === undefined ? null : { pid, sessionNames };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Probes a tmux server using an injectable list-sessions runner for platform-bounded callers. */
|
|
97
|
+
export async function tmuxServerProof(
|
|
98
|
+
socketKey: string,
|
|
99
|
+
tmuxControlArgv?: string[],
|
|
100
|
+
options: TmuxServerProofOptions = {},
|
|
101
|
+
): Promise<TmuxServerProof> {
|
|
102
|
+
void socketKey;
|
|
103
|
+
if (!tmuxControlArgv?.length) return { state: "unverifiable" };
|
|
104
|
+
const platform = options.platform ?? process.platform;
|
|
105
|
+
const subprocess = options.runListSessions?.(tmuxControlArgv) ?? runTmuxListSessions(tmuxControlArgv);
|
|
65
106
|
if (subprocess.exitCode !== 0)
|
|
66
|
-
return isKnownNoServerDiagnostic(stderr) ? { state: "absent" } : { state: "unverifiable" };
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const [pidText] = lines[0]?.split("\t") ?? [];
|
|
73
|
-
const pid = Number(pidText);
|
|
74
|
-
const sessionNames = lines.map(line => line.split("\t")[1]).filter((name): name is string => Boolean(name));
|
|
75
|
-
if (!Number.isSafeInteger(pid) || pid <= 0) return { state: "unverifiable" };
|
|
76
|
-
if (process.platform !== "linux") {
|
|
107
|
+
return isKnownNoServerDiagnostic(subprocess.stderr) ? { state: "absent" } : { state: "unverifiable" };
|
|
108
|
+
if (!subprocess.stdout.trim()) return { state: "absent" };
|
|
109
|
+
const rows = parseTmuxSessionRows(subprocess.stdout);
|
|
110
|
+
if (!rows) return { state: "unverifiable" };
|
|
111
|
+
const { pid, sessionNames } = rows;
|
|
112
|
+
if (platform !== "linux") {
|
|
77
113
|
return {
|
|
78
114
|
state: "safe",
|
|
79
115
|
pid,
|
|
@@ -82,7 +118,7 @@ async function tmuxServerProof(socketKey: string, tmuxControlArgv?: string[]): P
|
|
|
82
118
|
sessionNames,
|
|
83
119
|
};
|
|
84
120
|
}
|
|
85
|
-
const cgroup = classifyCgroup({ platform
|
|
121
|
+
const cgroup = classifyCgroup({ platform, cgroupText: await readCgroup(String(pid)) });
|
|
86
122
|
const startTime = await readProcessStartTime(pid);
|
|
87
123
|
if (!startTime) return { state: "unverifiable", pid, cgroup, sessionNames };
|
|
88
124
|
return {
|
|
@@ -1524,7 +1524,7 @@ export function isValidOwnerIntent(intent: unknown, request?: ObserveTerminalReq
|
|
|
1524
1524
|
intent.generation === request.owner_generation &&
|
|
1525
1525
|
intent.session_id === request.session_id &&
|
|
1526
1526
|
intent.server_key === request.socket_key &&
|
|
1527
|
-
intent.dispatch_id === request.operator_dispatch_id &&
|
|
1527
|
+
(request.operator_dispatch_id === undefined || intent.dispatch_id === request.operator_dispatch_id) &&
|
|
1528
1528
|
request.signal === "SIGTERM"
|
|
1529
1529
|
);
|
|
1530
1530
|
}
|
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
type TmuxOwnerIsolationExecutionResult,
|
|
50
50
|
type TmuxServerProof,
|
|
51
51
|
} from "./tmux-owner-isolation";
|
|
52
|
+
import { buildWindowsPowerShellInnerCommand } from "./windows-powershell-command";
|
|
52
53
|
|
|
53
54
|
export interface GjcTmuxSessionStatus {
|
|
54
55
|
name: string;
|
|
@@ -128,6 +129,10 @@ export interface ForceCloseOwnerDependencies {
|
|
|
128
129
|
const FORCE_CLOSE_VERDICT_TIMEOUT_MS = 5_000;
|
|
129
130
|
const FORCE_CLOSE_VERDICT_POLL_MS = 50;
|
|
130
131
|
|
|
132
|
+
export interface CreateGjcTmuxSessionOptions {
|
|
133
|
+
platform?: NodeJS.Platform;
|
|
134
|
+
}
|
|
135
|
+
|
|
131
136
|
export type CreateOwnerIsolationTestDependencies = {
|
|
132
137
|
probe?: Partial<OwnerIsolationProbeSync>;
|
|
133
138
|
execute?: (plan: PlanResponse, deps: TmuxOwnerIsolationExecutionDependencies) => TmuxOwnerIsolationExecutionResult;
|
|
@@ -354,15 +359,19 @@ export function statusGjcTmuxSession(sessionName: string, env: NodeJS.ProcessEnv
|
|
|
354
359
|
throw new Error(`gjc_tmux_session_not_found:${sessionName}`);
|
|
355
360
|
}
|
|
356
361
|
|
|
357
|
-
export function createGjcTmuxSession(
|
|
358
|
-
|
|
362
|
+
export function createGjcTmuxSession(
|
|
363
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
364
|
+
options: CreateGjcTmuxSessionOptions = {},
|
|
365
|
+
): GjcTmuxSessionStatus {
|
|
366
|
+
const platform = options.platform ?? process.platform;
|
|
367
|
+
const tmuxCommand = resolveGjcTmuxCommand(env, platform);
|
|
359
368
|
const sessionName = buildGjcTmuxSessionName(env);
|
|
360
369
|
const cwd = process.cwd();
|
|
361
370
|
const sessionId = env[GJC_COORDINATOR_SESSION_ID_ENV]?.trim() || sessionName;
|
|
362
371
|
const stateFile =
|
|
363
372
|
env[GJC_COORDINATOR_SESSION_STATE_FILE_ENV]?.trim() ||
|
|
364
373
|
tmuxRuntimeSessionPath(cwd, env.GJC_SESSION_ID?.trim() || sessionId, buildGjcTmuxSessionSlug(sessionName));
|
|
365
|
-
const stateDir = path.dirname(stateFile);
|
|
374
|
+
const stateDir = (platform === "win32" ? path.win32 : path).dirname(stateFile);
|
|
366
375
|
const generation = crypto.randomUUID();
|
|
367
376
|
const childEnvironment: Record<string, string> = {
|
|
368
377
|
GJC_TMUX_LAUNCHED: "1",
|
|
@@ -373,12 +382,9 @@ export function createGjcTmuxSession(env: NodeJS.ProcessEnv = process.env): GjcT
|
|
|
373
382
|
[GJC_COORDINATOR_SESSION_STATE_FILE_ENV]: stateFile,
|
|
374
383
|
};
|
|
375
384
|
const shellQuote = (value: string): string => `'${value.replace(/'/g, `'\\''`)}'`;
|
|
376
|
-
const powershellQuote = (value: string): string => `'${value.replace(/'/g, "''")}'`;
|
|
377
385
|
const command =
|
|
378
|
-
|
|
379
|
-
?
|
|
380
|
-
.map(([name, value]) => `$env:${name} = ${powershellQuote(value)}`)
|
|
381
|
-
.join("; ")}; gjc`
|
|
386
|
+
platform === "win32"
|
|
387
|
+
? buildWindowsPowerShellInnerCommand({ command: ["gjc"], environment: childEnvironment })
|
|
382
388
|
: `exec env ${Object.entries(childEnvironment)
|
|
383
389
|
.map(([name, value]) => `${name}=${shellQuote(value)}`)
|
|
384
390
|
.join(" ")} gjc`;
|
|
@@ -388,11 +394,11 @@ export function createGjcTmuxSession(env: NodeJS.ProcessEnv = process.env): GjcT
|
|
|
388
394
|
"-d",
|
|
389
395
|
"-s",
|
|
390
396
|
sessionName,
|
|
391
|
-
...(
|
|
397
|
+
...(platform === "win32" ? [] : ["-P", "-F", "#{session_id}"]),
|
|
392
398
|
command,
|
|
393
399
|
];
|
|
394
400
|
function probeTmuxServer(tmuxCommand: string, env: NodeJS.ProcessEnv): TmuxServerProof {
|
|
395
|
-
if (
|
|
401
|
+
if (platform !== "linux") {
|
|
396
402
|
return {
|
|
397
403
|
state: "safe",
|
|
398
404
|
pid: 1,
|
|
@@ -421,7 +427,7 @@ export function createGjcTmuxSession(env: NodeJS.ProcessEnv = process.env): GjcT
|
|
|
421
427
|
.split(/\s+/)[19];
|
|
422
428
|
if (!startTime) return { state: "unverifiable" };
|
|
423
429
|
const cgroup = classifyCgroup({
|
|
424
|
-
platform
|
|
430
|
+
platform,
|
|
425
431
|
cgroupText: fsSync.readFileSync(`/proc/${pid}/cgroup`, "utf8"),
|
|
426
432
|
});
|
|
427
433
|
return {
|
|
@@ -484,7 +490,7 @@ export function createGjcTmuxSession(env: NodeJS.ProcessEnv = process.env): GjcT
|
|
|
484
490
|
}
|
|
485
491
|
}),
|
|
486
492
|
};
|
|
487
|
-
if (resolveGjcTmuxBinary({ env }).isPsmux)
|
|
493
|
+
if (resolveGjcTmuxBinary({ env, platform }).isPsmux)
|
|
488
494
|
throw new Error("gjc_tmux_owner_isolation_native_session_identity_unavailable");
|
|
489
495
|
|
|
490
496
|
const baseline = captureOwnerGenerationBaselineSync(stateDir, sessionId);
|
|
@@ -492,7 +498,7 @@ export function createGjcTmuxSession(env: NodeJS.ProcessEnv = process.env): GjcT
|
|
|
492
498
|
{
|
|
493
499
|
schema_version: 1,
|
|
494
500
|
op: "plan",
|
|
495
|
-
platform
|
|
501
|
+
platform,
|
|
496
502
|
session_id: sessionId,
|
|
497
503
|
owner_generation: generation,
|
|
498
504
|
baseline,
|
|
@@ -174,6 +174,39 @@ function findReceiptGoal(
|
|
|
174
174
|
return storyGoal ? { goal: storyGoal, receiptKind: "per-goal" } : null;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
/**
|
|
178
|
+
* A review-blocker replacement can stand in for a superseded validation-batch
|
|
179
|
+
* final only while validating the run's final aggregate receipt. Ordinary
|
|
180
|
+
* per-goal validation continues to require the original batch-close receipt.
|
|
181
|
+
*/
|
|
182
|
+
function hasFreshReviewedBatchFinalReplacement(input: {
|
|
183
|
+
plan: UltragoalPlan;
|
|
184
|
+
ledger: readonly UltragoalLedgerEvent[];
|
|
185
|
+
deferredGoal: UltragoalGoal;
|
|
186
|
+
}): boolean {
|
|
187
|
+
const finalGoalId = input.deferredGoal.completionVerification?.validationBatch?.finalGoalId;
|
|
188
|
+
const finalGoal = finalGoalId ? input.plan.goals.find(goal => goal.id === finalGoalId) : undefined;
|
|
189
|
+
if (finalGoal?.status !== "superseded") return false;
|
|
190
|
+
const replacements = input.plan.goals.filter(
|
|
191
|
+
goal =>
|
|
192
|
+
goal.status === "complete" &&
|
|
193
|
+
goal.steering?.kind === "review_blocker" &&
|
|
194
|
+
goal.steering.blockedGoalId === finalGoal.id,
|
|
195
|
+
);
|
|
196
|
+
if (replacements.length !== 1) return false;
|
|
197
|
+
const replacement = replacements[0]!;
|
|
198
|
+
const receipt = replacement.completionVerification;
|
|
199
|
+
if (receipt?.receiptKind !== "per-goal") return false;
|
|
200
|
+
return (
|
|
201
|
+
validateCompletionReceipt({
|
|
202
|
+
plan: input.plan,
|
|
203
|
+
ledger: input.ledger,
|
|
204
|
+
goal: replacement,
|
|
205
|
+
receiptKind: "per-goal",
|
|
206
|
+
}).state === "active_verified_complete"
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
177
210
|
export function validateCompletionReceipt(input: {
|
|
178
211
|
plan: UltragoalPlan;
|
|
179
212
|
ledger: readonly UltragoalLedgerEvent[];
|
|
@@ -267,12 +300,26 @@ export function validateCompletionReceipt(input: {
|
|
|
267
300
|
goalId: input.goal.id,
|
|
268
301
|
};
|
|
269
302
|
}
|
|
270
|
-
const priorDiagnostic =
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
303
|
+
const priorDiagnostic =
|
|
304
|
+
priorGoal.completionVerification.validationBatch?.role === "deferred-member"
|
|
305
|
+
? validateDeferredMemberReceiptFresh({
|
|
306
|
+
plan: input.plan,
|
|
307
|
+
ledger: input.ledger,
|
|
308
|
+
goal: priorGoal,
|
|
309
|
+
receipt: priorGoal.completionVerification,
|
|
310
|
+
receiptKind: "per-goal",
|
|
311
|
+
requireClose: !hasFreshReviewedBatchFinalReplacement({
|
|
312
|
+
plan: input.plan,
|
|
313
|
+
ledger: input.ledger,
|
|
314
|
+
deferredGoal: priorGoal,
|
|
315
|
+
}),
|
|
316
|
+
})
|
|
317
|
+
: validateCompletionReceipt({
|
|
318
|
+
plan: input.plan,
|
|
319
|
+
ledger: input.ledger,
|
|
320
|
+
goal: priorGoal,
|
|
321
|
+
receiptKind: "per-goal",
|
|
322
|
+
});
|
|
276
323
|
if (priorDiagnostic.state !== "active_verified_complete") {
|
|
277
324
|
return {
|
|
278
325
|
state: priorDiagnostic.state,
|
|
@@ -9,6 +9,7 @@ import { DEFAULT_ULTRAGOAL_OBJECTIVE } from "./goal-mode-request";
|
|
|
9
9
|
import {
|
|
10
10
|
computeUltragoalPlanGeneration,
|
|
11
11
|
findFreshBatchCloseReceipt,
|
|
12
|
+
findLedgerReceiptEvent,
|
|
12
13
|
requiredUltragoalGoals,
|
|
13
14
|
validateDeferredMemberReceiptFresh,
|
|
14
15
|
validateReceiptFreshBase,
|
|
@@ -3451,7 +3452,12 @@ function canonicalChangeSetRows(value: unknown, fieldName: string): UltragoalCha
|
|
|
3451
3452
|
if ("goalId" in record) throw new Error(`${fieldName}[${index}] must not contain goalId attribution`);
|
|
3452
3453
|
const status = nonEmptyString(record.status);
|
|
3453
3454
|
if (!status) throw new Error(`${fieldName}[${index}].status is required`);
|
|
3454
|
-
|
|
3455
|
+
const oldPath = nonEmptyString(record.oldPath);
|
|
3456
|
+
return {
|
|
3457
|
+
path: normalizeRepoPath(pathValue),
|
|
3458
|
+
status: status as UltragoalChangeStatus,
|
|
3459
|
+
...(oldPath ? { oldPath: normalizeRepoPath(oldPath) } : {}),
|
|
3460
|
+
};
|
|
3455
3461
|
});
|
|
3456
3462
|
}
|
|
3457
3463
|
|
|
@@ -3711,6 +3717,140 @@ function validateBatchCloseQualityGate(
|
|
|
3711
3717
|
throw new Error("validationBatchClose.unionChangeSet.unionHash does not match declared union");
|
|
3712
3718
|
requireNonEmptyString(close.coverageEvidence, "validationBatchClose.coverageEvidence");
|
|
3713
3719
|
}
|
|
3720
|
+
|
|
3721
|
+
function hydrateReviewedBatchReplacementClose(input: {
|
|
3722
|
+
gate: JsonObject;
|
|
3723
|
+
plan: UltragoalPlan;
|
|
3724
|
+
goal: UltragoalGoal;
|
|
3725
|
+
metadata: UltragoalValidationBatchMetadata;
|
|
3726
|
+
ledger: readonly UltragoalLedgerEvent[];
|
|
3727
|
+
changeSet?: UltragoalChangeSet;
|
|
3728
|
+
}): JsonObject {
|
|
3729
|
+
const requested = qualityGateObject(input.gate.validationBatchClose);
|
|
3730
|
+
if (requested?.kind !== "review-blocker-replacement-close") return input.gate;
|
|
3731
|
+
const expectedKeys = new Set(["schemaVersion", "kind", "replacementGoalId", "coverageEvidence"]);
|
|
3732
|
+
if (Object.keys(requested).some(key => !expectedKeys.has(key)))
|
|
3733
|
+
throw new Error("review-blocker replacement close contains unsupported fields");
|
|
3734
|
+
const replacementGoalId = nonEmptyString(requested.replacementGoalId);
|
|
3735
|
+
const coverageEvidence = nonEmptyString(requested.coverageEvidence);
|
|
3736
|
+
if (requested.schemaVersion !== 1 || !replacementGoalId || !coverageEvidence)
|
|
3737
|
+
throw new Error("review-blocker replacement close is malformed");
|
|
3738
|
+
if (input.goal.status !== "active" || input.metadata.finalGoalId !== input.goal.id)
|
|
3739
|
+
throw new Error("review-blocker replacement close requires the active durable validation-batch final goal");
|
|
3740
|
+
if (!input.changeSet) throw new Error("review-blocker replacement close requires a current cumulative change set");
|
|
3741
|
+
|
|
3742
|
+
const replacements = input.plan.goals.filter(
|
|
3743
|
+
goal => goal.steering?.kind === "review_blocker" && goal.steering.blockedGoalId === input.goal.id,
|
|
3744
|
+
);
|
|
3745
|
+
if (replacements.length !== 1 || replacements[0]?.id !== replacementGoalId)
|
|
3746
|
+
throw new Error("review-blocker replacement close requires exactly the declared replacement");
|
|
3747
|
+
const replacement = replacements[0]!;
|
|
3748
|
+
const replacementReceipt = replacement.completionVerification;
|
|
3749
|
+
if (replacement.status !== "complete" || replacementReceipt?.receiptKind !== "per-goal")
|
|
3750
|
+
throw new Error("review-blocker replacement close requires a completed per-goal replacement receipt");
|
|
3751
|
+
const replacementDiagnostic = validateReceiptFreshBase({
|
|
3752
|
+
plan: input.plan,
|
|
3753
|
+
ledger: input.ledger,
|
|
3754
|
+
goal: replacement,
|
|
3755
|
+
receipt: replacementReceipt,
|
|
3756
|
+
receiptKind: "per-goal",
|
|
3757
|
+
});
|
|
3758
|
+
if (replacementDiagnostic) throw new Error(`review-blocker replacement close ${replacementDiagnostic.message}`);
|
|
3759
|
+
const replacementCheckpointIndex = input.ledger.findIndex(
|
|
3760
|
+
event => event.eventId === replacementReceipt.checkpointLedgerEventId,
|
|
3761
|
+
);
|
|
3762
|
+
const reviewRecordedIndex = input.ledger.findIndex(
|
|
3763
|
+
event =>
|
|
3764
|
+
event.event === "review_blockers_recorded" &&
|
|
3765
|
+
event.goalId === input.goal.id &&
|
|
3766
|
+
event.blockerGoalId === replacement.id,
|
|
3767
|
+
);
|
|
3768
|
+
const reactivatedIndex = input.ledger.findIndex(
|
|
3769
|
+
(event, index) =>
|
|
3770
|
+
index > replacementCheckpointIndex &&
|
|
3771
|
+
event.event === "goal_checkpointed" &&
|
|
3772
|
+
event.goalId === input.goal.id &&
|
|
3773
|
+
event.status === "active",
|
|
3774
|
+
);
|
|
3775
|
+
if (reviewRecordedIndex < 0 || reviewRecordedIndex >= replacementCheckpointIndex || reactivatedIndex < 0)
|
|
3776
|
+
throw new Error("review-blocker replacement close lacks durable supersession and reopening evidence");
|
|
3777
|
+
|
|
3778
|
+
const historicalRequiredGoalIds = input.plan.goals
|
|
3779
|
+
.filter(goal => goal.id !== input.goal.id && goal.status !== "superseded")
|
|
3780
|
+
.map(goal => goal.id);
|
|
3781
|
+
const aggregateGoals = input.plan.goals.filter(goal => {
|
|
3782
|
+
const receipt = goal.completionVerification;
|
|
3783
|
+
return goal.status === "complete" && receipt?.receiptKind === "final-aggregate";
|
|
3784
|
+
});
|
|
3785
|
+
const aggregateGoal = aggregateGoals.find(goal => {
|
|
3786
|
+
const receipt = goal.completionVerification!;
|
|
3787
|
+
const event = findLedgerReceiptEvent(input.ledger, receipt);
|
|
3788
|
+
return (
|
|
3789
|
+
event !== null &&
|
|
3790
|
+
hashStructuredValue(event.qualityGateJson) === receipt.qualityGateHash &&
|
|
3791
|
+
goal.updatedAt === receipt.verifiedAt &&
|
|
3792
|
+
receipt.basis.relevantGoalIdsBeforeCheckpoint.length === historicalRequiredGoalIds.length &&
|
|
3793
|
+
receipt.basis.relevantGoalIdsBeforeCheckpoint.every(
|
|
3794
|
+
(goalId, index) => goalId === historicalRequiredGoalIds[index],
|
|
3795
|
+
)
|
|
3796
|
+
);
|
|
3797
|
+
});
|
|
3798
|
+
if (!aggregateGoal)
|
|
3799
|
+
throw new Error(
|
|
3800
|
+
"review-blocker replacement close requires a fresh final-aggregate receipt covering required goals",
|
|
3801
|
+
);
|
|
3802
|
+
|
|
3803
|
+
const memberMetadataHashes: Record<string, string> = {};
|
|
3804
|
+
const memberChangeSetHashes: Record<string, string> = {};
|
|
3805
|
+
const memberReceipts: JsonObject[] = [];
|
|
3806
|
+
for (const memberId of input.metadata.memberIds) {
|
|
3807
|
+
const member = input.plan.goals.find(goal => goal.id === memberId);
|
|
3808
|
+
if (!member?.validationBatch)
|
|
3809
|
+
throw new Error(`review-blocker replacement close references missing batch member ${memberId}`);
|
|
3810
|
+
memberMetadataHashes[memberId] = member.validationBatch.metadataHash;
|
|
3811
|
+
if (memberId === input.goal.id) continue;
|
|
3812
|
+
const receipt = requireDeferredMemberReceiptFresh(
|
|
3813
|
+
input.plan,
|
|
3814
|
+
input.ledger,
|
|
3815
|
+
member,
|
|
3816
|
+
"review-blocker replacement close",
|
|
3817
|
+
);
|
|
3818
|
+
memberChangeSetHashes[memberId] = receipt.validationBatch.changeSetHash;
|
|
3819
|
+
memberReceipts.push({
|
|
3820
|
+
goalId: memberId,
|
|
3821
|
+
receiptId: receipt.receiptId,
|
|
3822
|
+
checkpointLedgerEventId: receipt.checkpointLedgerEventId,
|
|
3823
|
+
qualityGateHash: receipt.qualityGateHash,
|
|
3824
|
+
changeSetHash: receipt.validationBatch.changeSetHash,
|
|
3825
|
+
role: "deferred-member",
|
|
3826
|
+
});
|
|
3827
|
+
}
|
|
3828
|
+
const paths = input.changeSet.paths.map(row => ({ ...row }));
|
|
3829
|
+
memberChangeSetHashes[input.goal.id] = changeSetHashForPaths(paths);
|
|
3830
|
+
const unionHash = hashStructuredValue({
|
|
3831
|
+
memberChangeSetHashes,
|
|
3832
|
+
paths: paths.map(row => ({ path: row.path, status: row.status, oldPath: row.oldPath })),
|
|
3833
|
+
});
|
|
3834
|
+
return {
|
|
3835
|
+
...input.gate,
|
|
3836
|
+
validationBatchClose: {
|
|
3837
|
+
schemaVersion: 1,
|
|
3838
|
+
kind: "validation-batch-close",
|
|
3839
|
+
batchId: input.metadata.batchId,
|
|
3840
|
+
finalGoalId: input.metadata.finalGoalId,
|
|
3841
|
+
memberIds: [...input.metadata.memberIds],
|
|
3842
|
+
memberMetadataHashes,
|
|
3843
|
+
memberReceipts,
|
|
3844
|
+
unionChangeSet: {
|
|
3845
|
+
source: "validation-batch",
|
|
3846
|
+
memberChangeSetHashes,
|
|
3847
|
+
paths,
|
|
3848
|
+
unionHash,
|
|
3849
|
+
},
|
|
3850
|
+
coverageEvidence,
|
|
3851
|
+
},
|
|
3852
|
+
};
|
|
3853
|
+
}
|
|
3714
3854
|
async function readRequiredCompletionQualityGate(
|
|
3715
3855
|
cwd: string,
|
|
3716
3856
|
value: string | undefined,
|
|
@@ -3729,13 +3869,25 @@ async function readRequiredCompletionQualityGate(
|
|
|
3729
3869
|
const gate = await readStructuredValue(cwd, value);
|
|
3730
3870
|
const gateObject = qualityGateObject(gate);
|
|
3731
3871
|
if (!gateObject) throw new Error("qualityGate must be a JSON object");
|
|
3732
|
-
|
|
3872
|
+
const validationBatch = options.goal ? requireFreshValidationBatchMetadata(options.goal) : undefined;
|
|
3873
|
+
const hydratedGate =
|
|
3874
|
+
validationBatch && options.plan && options.goal && options.ledger
|
|
3875
|
+
? hydrateReviewedBatchReplacementClose({
|
|
3876
|
+
gate: gateObject,
|
|
3877
|
+
plan: options.plan,
|
|
3878
|
+
goal: options.goal,
|
|
3879
|
+
metadata: validationBatch,
|
|
3880
|
+
ledger: options.ledger,
|
|
3881
|
+
changeSet: options.changeSet,
|
|
3882
|
+
})
|
|
3883
|
+
: gateObject;
|
|
3884
|
+
await validateCompletionQualityGate(cwd, hydratedGate, {
|
|
3733
3885
|
changeSet: options.changeSet,
|
|
3734
3886
|
plan: options.plan,
|
|
3735
3887
|
goal: options.goal,
|
|
3736
3888
|
ledger: options.ledger,
|
|
3737
3889
|
});
|
|
3738
|
-
return
|
|
3890
|
+
return hydratedGate;
|
|
3739
3891
|
}
|
|
3740
3892
|
|
|
3741
3893
|
function validatePipelineCheckpointSafety(
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
|
|
4
|
+
export const GJC_TMUX_LAUNCHED_ENV = "GJC_TMUX_LAUNCHED";
|
|
5
|
+
|
|
6
|
+
export interface WindowsPowerShellInnerCommandOptions {
|
|
7
|
+
command: readonly string[];
|
|
8
|
+
args?: readonly string[];
|
|
9
|
+
environment?: Record<string, string>;
|
|
10
|
+
tmuxExitMarkerPath?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function powershellQuote(value: string): string {
|
|
14
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function buildPowerShellTmuxExitMarkerFinally(markerPath: string): string {
|
|
18
|
+
const markerDir = path.win32.dirname(markerPath);
|
|
19
|
+
return [
|
|
20
|
+
"} finally {",
|
|
21
|
+
"\ttry {",
|
|
22
|
+
`\t\tNew-Item -ItemType Directory -Force -Path ${powershellQuote(markerDir)} -ErrorAction Stop | Out-Null`,
|
|
23
|
+
"\t\t$__gjcTmuxExitMarker = @{ schema_version = 1; source = 'tmux_inner_shell'; ended_at = (Get-Date).ToUniversalTime().ToString('o'); exit_code = $__gjcTmuxExitCode } | ConvertTo-Json -Compress",
|
|
24
|
+
`\t\tSet-Content -LiteralPath ${powershellQuote(markerPath)} -Value $__gjcTmuxExitMarker -Encoding UTF8 -ErrorAction Stop`,
|
|
25
|
+
"\t} catch {",
|
|
26
|
+
"\t}",
|
|
27
|
+
"}",
|
|
28
|
+
].join("\n");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Builds the shared BOM-free UTF-16LE command for native Windows tmux-compatible panes. */
|
|
32
|
+
export function buildWindowsPowerShellInnerCommand({
|
|
33
|
+
command,
|
|
34
|
+
args = [],
|
|
35
|
+
environment,
|
|
36
|
+
tmuxExitMarkerPath,
|
|
37
|
+
}: WindowsPowerShellInnerCommandOptions): string {
|
|
38
|
+
const envLines = Object.entries({ [GJC_TMUX_LAUNCHED_ENV]: "1", ...(environment ?? {}) }).map(
|
|
39
|
+
([key, value]) => `$env:${key} = ${powershellQuote(value)}`,
|
|
40
|
+
);
|
|
41
|
+
const resolvedCommand = command.map(powershellQuote).join(" ");
|
|
42
|
+
const innerArgs = args.map(powershellQuote).join(" ");
|
|
43
|
+
const invocation = `& ${resolvedCommand} ${innerArgs}`;
|
|
44
|
+
const exitLine = "if ($null -ne $LASTEXITCODE) { exit $LASTEXITCODE } else { exit 1 }";
|
|
45
|
+
const script = tmuxExitMarkerPath
|
|
46
|
+
? [
|
|
47
|
+
...envLines,
|
|
48
|
+
"$__gjcTmuxExitCode = 1",
|
|
49
|
+
"try {",
|
|
50
|
+
`\t${invocation}`,
|
|
51
|
+
"\tif ($null -ne $LASTEXITCODE) { $__gjcTmuxExitCode = $LASTEXITCODE } else { $__gjcTmuxExitCode = 1 }",
|
|
52
|
+
buildPowerShellTmuxExitMarkerFinally(tmuxExitMarkerPath),
|
|
53
|
+
"exit $__gjcTmuxExitCode",
|
|
54
|
+
].join("\n")
|
|
55
|
+
: [...envLines, invocation, exitLine].join("\n");
|
|
56
|
+
const encodedCommand = Buffer.from(script, "utf16le").toString("base64");
|
|
57
|
+
return `pwsh -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand ${encodedCommand}`;
|
|
58
|
+
}
|