@gajae-code/coding-agent 0.10.2 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -2
- package/dist/types/append-only-mode.d.ts +1 -1
- package/dist/types/async/job-manager.d.ts +46 -7
- 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/ultragoal-receipt-freshness.d.ts +11 -0
- 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/command-controller.d.ts +2 -2
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -0
- 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 +5 -2
- 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 +170 -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 +7 -2
- 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 +42 -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 +50 -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 +78 -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/dist/types/tools/subagent-render.d.ts +1 -0
- package/dist/types/tools/subagent.d.ts +6 -1
- package/package.json +34 -13
- package/scripts/build-sdk-package-smoke.ts +99 -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/async/job-manager.ts +406 -63
- 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 +108 -14
- package/src/gjc-runtime/ultragoal-receipt-freshness.ts +102 -1
- package/src/gjc-runtime/ultragoal-runtime.ts +227 -11
- 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 +10 -17
- package/src/modes/controllers/event-controller.ts +11 -16
- package/src/modes/controllers/extension-ui-controller.ts +396 -28
- package/src/modes/controllers/selector-controller.ts +674 -36
- package/src/modes/index.ts +0 -22
- package/src/modes/interactive-mode.ts +87 -36
- 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 +1258 -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 +7 -2
- 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 +113 -0
- package/src/sdk/broker/ensure.ts +307 -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 +355 -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 +2292 -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 +3979 -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 +603 -63
- 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 +2650 -944
- 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/task/index.ts +26 -16
- 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/subagent-render.ts +19 -8
- package/src/tools/subagent.ts +84 -32
- 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
|
@@ -279,6 +279,8 @@ export function formatLifecycleOutcome(r: SessionLifecycleResponse): string {
|
|
|
279
279
|
return "\u26a0\ufe0f Close refused: that session is not GJC-managed or did not match.";
|
|
280
280
|
case "not_found":
|
|
281
281
|
return "\u2753 No matching session was found.";
|
|
282
|
+
case "unsupported_platform":
|
|
283
|
+
return "Remote session lifecycle is unavailable on this psmux host because GJC cannot prove immutable session identity. No lifecycle action was performed. Use a local GJC terminal with a supported tmux provider.";
|
|
282
284
|
case "terminal_uncertain":
|
|
283
285
|
return /in progress/i.test(r.message)
|
|
284
286
|
? "\u23f3 That request is already in progress \u2014 hold on."
|
|
@@ -10,20 +10,21 @@ import * as crypto from "node:crypto";
|
|
|
10
10
|
import * as fs from "node:fs";
|
|
11
11
|
import * as fsPromises from "node:fs/promises";
|
|
12
12
|
import * as path from "node:path";
|
|
13
|
-
import {
|
|
13
|
+
import type { NotificationControlServer as NativeNotificationControlServer } from "@gajae-code/natives";
|
|
14
|
+
import { tmuxRuntimeSessionPath } from "../../gjc-runtime/session-layout";
|
|
14
15
|
import {
|
|
15
16
|
GJC_COORDINATOR_SESSION_ID_ENV,
|
|
16
17
|
GJC_COORDINATOR_SESSION_STATE_FILE_ENV,
|
|
17
18
|
GJC_TMUX_OWNER_GENERATION_ENV,
|
|
18
19
|
GJC_TMUX_OWNER_SERVER_KEY_ENV,
|
|
19
20
|
GJC_TMUX_OWNER_STATE_DIR_ENV,
|
|
20
|
-
} from "
|
|
21
|
+
} from "../../gjc-runtime/session-state-sidecar";
|
|
21
22
|
import {
|
|
22
23
|
buildGjcTmuxProfileCommands,
|
|
23
24
|
buildGjcTmuxSessionSlug,
|
|
24
25
|
resolveGjcTmuxBinary,
|
|
25
26
|
resolveGjcTmuxCommand,
|
|
26
|
-
} from "
|
|
27
|
+
} from "../../gjc-runtime/tmux-common";
|
|
27
28
|
import {
|
|
28
29
|
captureOwnerGenerationBaseline,
|
|
29
30
|
classifyCgroup,
|
|
@@ -33,15 +34,20 @@ import {
|
|
|
33
34
|
planTmuxOwnerIsolation,
|
|
34
35
|
replaceOwnerGeneration,
|
|
35
36
|
type TmuxServerProof,
|
|
36
|
-
} from "
|
|
37
|
+
} from "../../gjc-runtime/tmux-owner-isolation";
|
|
37
38
|
import {
|
|
38
39
|
findGjcTmuxSessionByName,
|
|
39
40
|
forceCloseGjcTmuxSession,
|
|
40
41
|
type GjcTmuxSessionStatus,
|
|
41
42
|
listGjcTmuxSessions,
|
|
42
|
-
} from "
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
} from "../../gjc-runtime/tmux-sessions";
|
|
44
|
+
import type {
|
|
45
|
+
LifecycleErrorReason,
|
|
46
|
+
ResumeCandidate,
|
|
47
|
+
SessionCreateFrame,
|
|
48
|
+
SessionLifecycleRequest,
|
|
49
|
+
SessionLifecycleResponse,
|
|
50
|
+
} from "./index";
|
|
45
51
|
import { normalizeLifecyclePath } from "./lifecycle-commands";
|
|
46
52
|
import {
|
|
47
53
|
type AuditEvent,
|
|
@@ -56,6 +62,16 @@ import {
|
|
|
56
62
|
} from "./lifecycle-orchestrator";
|
|
57
63
|
import { listRecentSessions } from "./recent-activity";
|
|
58
64
|
|
|
65
|
+
type NativeControlServerConstructor = new (
|
|
66
|
+
token: string,
|
|
67
|
+
ownerId: string,
|
|
68
|
+
agentDir?: string,
|
|
69
|
+
) => NativeNotificationControlServer;
|
|
70
|
+
|
|
71
|
+
interface NativeControlServerModule {
|
|
72
|
+
NotificationControlServer: NativeControlServerConstructor;
|
|
73
|
+
}
|
|
74
|
+
|
|
59
75
|
/** Minimal view of the native control server this runtime depends on. */
|
|
60
76
|
export interface ControlServerLike {
|
|
61
77
|
onLifecycleRequest(
|
|
@@ -80,6 +96,24 @@ export type LifecycleControlServerFactory = (input: {
|
|
|
80
96
|
ownerId: string;
|
|
81
97
|
agentDir: string;
|
|
82
98
|
}) => LifecycleControlServer;
|
|
99
|
+
const lifecycleErrorReasons = new Set<LifecycleErrorReason>([
|
|
100
|
+
"unauthorized",
|
|
101
|
+
"rate_limited",
|
|
102
|
+
"duplicate_conflict",
|
|
103
|
+
"invalid_target",
|
|
104
|
+
"ambiguous_target",
|
|
105
|
+
"spawn_failed",
|
|
106
|
+
"discovery_timeout",
|
|
107
|
+
"readiness_timeout",
|
|
108
|
+
"close_refused",
|
|
109
|
+
"not_found",
|
|
110
|
+
"terminal_uncertain",
|
|
111
|
+
"unsupported_platform",
|
|
112
|
+
]);
|
|
113
|
+
|
|
114
|
+
function isLifecycleErrorReason(value: unknown): value is LifecycleErrorReason {
|
|
115
|
+
return typeof value === "string" && lifecycleErrorReasons.has(value as LifecycleErrorReason);
|
|
116
|
+
}
|
|
83
117
|
|
|
84
118
|
/** Atomic + fsynced file-backed idempotency ledger store. */
|
|
85
119
|
function ledgerReadError(error: unknown): Error {
|
|
@@ -95,7 +129,7 @@ function isLedgerDoc(value: unknown): value is LedgerDoc {
|
|
|
95
129
|
return Object.values(doc.entries).every(entry => {
|
|
96
130
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false;
|
|
97
131
|
const candidate = entry as Partial<LedgerEntry>;
|
|
98
|
-
|
|
132
|
+
const isBaseEntry =
|
|
99
133
|
typeof candidate.requestHash === "string" &&
|
|
100
134
|
(candidate.state === "in_progress" ||
|
|
101
135
|
candidate.state === "success" ||
|
|
@@ -109,11 +143,44 @@ function isLedgerDoc(value: unknown): value is LedgerDoc {
|
|
|
109
143
|
typeof candidate.updatedAt === "number" &&
|
|
110
144
|
!!candidate.targetSummary &&
|
|
111
145
|
typeof candidate.targetSummary === "object" &&
|
|
112
|
-
!Array.isArray(candidate.targetSummary)
|
|
113
|
-
);
|
|
146
|
+
!Array.isArray(candidate.targetSummary);
|
|
147
|
+
if (!isBaseEntry) return false;
|
|
148
|
+
if (candidate.state === "failure" || candidate.state === "terminal_uncertain")
|
|
149
|
+
return isLifecycleErrorReason(candidate.reason);
|
|
150
|
+
if (candidate.state !== "success") return true;
|
|
151
|
+
switch (candidate.verb) {
|
|
152
|
+
case "session_create":
|
|
153
|
+
return (
|
|
154
|
+
typeof candidate.intendedSessionId === "string" &&
|
|
155
|
+
typeof candidate.sessionId === "string" &&
|
|
156
|
+
typeof candidate.tmuxSession === "string" &&
|
|
157
|
+
typeof candidate.endpointUrl === "string"
|
|
158
|
+
);
|
|
159
|
+
case "session_close":
|
|
160
|
+
return typeof candidate.sessionId === "string" && typeof candidate.processGone === "boolean";
|
|
161
|
+
case "session_resume":
|
|
162
|
+
return (
|
|
163
|
+
typeof candidate.sessionId === "string" &&
|
|
164
|
+
typeof candidate.tmuxSession === "string" &&
|
|
165
|
+
typeof candidate.endpointUrl === "string" &&
|
|
166
|
+
(candidate.resumeMode === undefined ||
|
|
167
|
+
candidate.resumeMode === "reattached" ||
|
|
168
|
+
candidate.resumeMode === "cold_restarted")
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
return false;
|
|
114
172
|
});
|
|
115
173
|
}
|
|
116
174
|
|
|
175
|
+
function migrateLegacyLedger(doc: LedgerDoc): LedgerDoc {
|
|
176
|
+
for (const entry of Object.values(doc.entries)) {
|
|
177
|
+
if (entry.state === "success" && entry.verb === "session_resume" && entry.resumeMode === undefined) {
|
|
178
|
+
entry.resumeMode = "reattached";
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return doc;
|
|
182
|
+
}
|
|
183
|
+
|
|
117
184
|
function isUnsupportedDirectorySyncError(error: unknown): boolean {
|
|
118
185
|
const code = (error as NodeJS.ErrnoException | undefined)?.code;
|
|
119
186
|
return code === "EINVAL" || code === "ENOTSUP" || code === "EOPNOTSUPP";
|
|
@@ -163,7 +230,7 @@ export function fileLedgerStore(idempotencyFile: string): LedgerStore {
|
|
|
163
230
|
try {
|
|
164
231
|
const doc = JSON.parse(contents) as unknown;
|
|
165
232
|
if (!isLedgerDoc(doc)) throw new Error("invalid");
|
|
166
|
-
return doc;
|
|
233
|
+
return migrateLegacyLedger(doc);
|
|
167
234
|
} catch (error) {
|
|
168
235
|
throw ledgerReadError(error);
|
|
169
236
|
}
|
|
@@ -640,6 +707,91 @@ async function assertLifecycleTmuxServerSafe(input: {
|
|
|
640
707
|
throw new Error(`gjc_lifecycle_owner_${proof.state === "unsafe" ? "server_unsafe" : "server_unverifiable"}`);
|
|
641
708
|
}
|
|
642
709
|
|
|
710
|
+
async function completeLifecycleSpawnTransaction(input: {
|
|
711
|
+
tmux: string;
|
|
712
|
+
env: NodeJS.ProcessEnv;
|
|
713
|
+
sessionId: string;
|
|
714
|
+
generation: string;
|
|
715
|
+
stateDir: string;
|
|
716
|
+
cwd: string;
|
|
717
|
+
sessionName: string;
|
|
718
|
+
sessionStateFile: string;
|
|
719
|
+
argv: string[];
|
|
720
|
+
ownerIsolationProbe?: OwnerIsolationProbe;
|
|
721
|
+
prepareSpawn?: () => void;
|
|
722
|
+
}): Promise<void> {
|
|
723
|
+
const previousBaseline = await captureOwnerGenerationBaseline(input.stateDir, input.sessionId);
|
|
724
|
+
let ownerExecution: LifecycleAttemptExecution | undefined;
|
|
725
|
+
try {
|
|
726
|
+
ownerExecution = await executeLifecycleTmuxOwnerPlan({
|
|
727
|
+
...input,
|
|
728
|
+
previousBaseline,
|
|
729
|
+
onAttemptCreated: attempt => {
|
|
730
|
+
ownerExecution = attempt;
|
|
731
|
+
},
|
|
732
|
+
});
|
|
733
|
+
if (
|
|
734
|
+
!ownerExecution.nativeSessionId ||
|
|
735
|
+
ownerExecution.serverPid === undefined ||
|
|
736
|
+
ownerExecution.serverStartTime === undefined
|
|
737
|
+
)
|
|
738
|
+
throw new Error("gjc_lifecycle_owner_server_unverifiable");
|
|
739
|
+
await applyRequiredLifecycleTmuxMetadata(
|
|
740
|
+
input.tmux,
|
|
741
|
+
`${ownerExecution.nativeSessionId}:`,
|
|
742
|
+
input.env,
|
|
743
|
+
{
|
|
744
|
+
sessionId: input.sessionId,
|
|
745
|
+
sessionStateFile: input.sessionStateFile,
|
|
746
|
+
project: input.cwd,
|
|
747
|
+
ownerGeneration: input.generation,
|
|
748
|
+
ownerServerKey: ownerExecution.serverKey,
|
|
749
|
+
},
|
|
750
|
+
{
|
|
751
|
+
nativeSessionId: ownerExecution.nativeSessionId,
|
|
752
|
+
attemptSession: ownerExecution.attemptSession,
|
|
753
|
+
serverPid: ownerExecution.serverPid,
|
|
754
|
+
},
|
|
755
|
+
);
|
|
756
|
+
if (
|
|
757
|
+
!(await reproveLifecycleAttempt({
|
|
758
|
+
tmux: input.tmux,
|
|
759
|
+
env: input.env,
|
|
760
|
+
serverKey: ownerExecution.serverKey,
|
|
761
|
+
nativeSessionId: ownerExecution.nativeSessionId,
|
|
762
|
+
attemptSession: ownerExecution.attemptSession,
|
|
763
|
+
expectedServerPid: ownerExecution.serverPid,
|
|
764
|
+
expectedServerStartTime: ownerExecution.serverStartTime,
|
|
765
|
+
ownerIsolationProbe: input.ownerIsolationProbe,
|
|
766
|
+
}))
|
|
767
|
+
)
|
|
768
|
+
throw new Error("gjc_lifecycle_owner_server_unverifiable");
|
|
769
|
+
if (!(await isLifecycleGenerationUnchanged(input.stateDir, input.sessionId, previousBaseline)))
|
|
770
|
+
throw new Error("gjc_lifecycle_owner_generation_changed");
|
|
771
|
+
await replaceOwnerGeneration(input.stateDir, input.sessionId, input.generation, previousBaseline);
|
|
772
|
+
} catch (error) {
|
|
773
|
+
let cleanupFailure: unknown;
|
|
774
|
+
if (ownerExecution?.attemptCreated) {
|
|
775
|
+
try {
|
|
776
|
+
await cleanupLifecycleAttempt({
|
|
777
|
+
tmux: input.tmux,
|
|
778
|
+
env: input.env,
|
|
779
|
+
serverKey: ownerExecution.serverKey,
|
|
780
|
+
nativeSessionId: ownerExecution.nativeSessionId,
|
|
781
|
+
attemptSession: ownerExecution.attemptSession,
|
|
782
|
+
expectedServerPid: ownerExecution.serverPid,
|
|
783
|
+
expectedServerStartTime: ownerExecution.serverStartTime,
|
|
784
|
+
ownerIsolationProbe: input.ownerIsolationProbe,
|
|
785
|
+
});
|
|
786
|
+
} catch (cleanupError) {
|
|
787
|
+
cleanupFailure = cleanupError;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
if (cleanupFailure !== undefined)
|
|
791
|
+
throw new AggregateError([error, cleanupFailure], "gjc_lifecycle_cleanup_uncertain");
|
|
792
|
+
throw error;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
643
795
|
/** Real daemon-safe tmux launcher: canonical owner-isolation plan + GJC tags. */
|
|
644
796
|
export function daemonSpawnCreate(
|
|
645
797
|
env: NodeJS.ProcessEnv = process.env,
|
|
@@ -657,7 +809,6 @@ export function daemonSpawnCreate(
|
|
|
657
809
|
const sessionStateFile = lifecycleRuntimeStateFile(cwd, ids.intendedSessionId, name);
|
|
658
810
|
const stateDir = path.dirname(sessionStateFile);
|
|
659
811
|
const generation = crypto.randomUUID();
|
|
660
|
-
const previousBaseline = await captureOwnerGenerationBaseline(stateDir, ids.intendedSessionId);
|
|
661
812
|
// Detached: no interactive TTY needed (daemon-safe). These values contain
|
|
662
813
|
// only opaque ids and paths needed by the resident sidecar to publish its
|
|
663
814
|
// exact-owner terminal verdict.
|
|
@@ -674,91 +825,24 @@ export function daemonSpawnCreate(
|
|
|
674
825
|
};
|
|
675
826
|
if (ids.startupPromptRef) childEnv.GJC_STARTUP_PROMPT_REF = ids.startupPromptRef;
|
|
676
827
|
const envPairs = Object.entries(childEnv)
|
|
677
|
-
.map(([
|
|
828
|
+
.map(([key, value]) => `${key}=${shellQuote(value)}`)
|
|
678
829
|
.join(" ");
|
|
679
830
|
const command = `cd ${shellQuote(cwd)} && exec env ${envPairs} gjc ${args.map(shellQuote).join(" ")}`;
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
previousBaseline,
|
|
696
|
-
|
|
697
|
-
prepareSpawn: () => {
|
|
698
|
-
if (frame.target.kind === "plain_dir") fs.mkdirSync(cwd, { recursive: true });
|
|
699
|
-
},
|
|
700
|
-
});
|
|
701
|
-
if (!ownerExecution.nativeSessionId || ownerExecution.serverPid === undefined)
|
|
702
|
-
throw new Error("gjc_lifecycle_owner_server_unverifiable");
|
|
703
|
-
const target = `${ownerExecution.nativeSessionId}:`;
|
|
704
|
-
await applyRequiredLifecycleTmuxMetadata(
|
|
705
|
-
tmux,
|
|
706
|
-
target,
|
|
707
|
-
env,
|
|
708
|
-
{
|
|
709
|
-
sessionId: ids.intendedSessionId,
|
|
710
|
-
sessionStateFile,
|
|
711
|
-
project: cwd,
|
|
712
|
-
ownerGeneration: generation,
|
|
713
|
-
ownerServerKey: ownerExecution.serverKey,
|
|
714
|
-
},
|
|
715
|
-
{
|
|
716
|
-
nativeSessionId: ownerExecution.nativeSessionId,
|
|
717
|
-
attemptSession: ownerExecution.attemptSession,
|
|
718
|
-
serverPid: ownerExecution.serverPid,
|
|
719
|
-
},
|
|
720
|
-
);
|
|
721
|
-
if (
|
|
722
|
-
!ownerExecution.nativeSessionId ||
|
|
723
|
-
ownerExecution.serverPid === undefined ||
|
|
724
|
-
ownerExecution.serverStartTime === undefined ||
|
|
725
|
-
!(await reproveLifecycleAttempt({
|
|
726
|
-
tmux,
|
|
727
|
-
env,
|
|
728
|
-
serverKey: ownerExecution.serverKey,
|
|
729
|
-
nativeSessionId: ownerExecution.nativeSessionId,
|
|
730
|
-
attemptSession: ownerExecution.attemptSession,
|
|
731
|
-
expectedServerPid: ownerExecution.serverPid,
|
|
732
|
-
expectedServerStartTime: ownerExecution.serverStartTime,
|
|
733
|
-
ownerIsolationProbe: opts.ownerIsolationProbe,
|
|
734
|
-
}))
|
|
735
|
-
)
|
|
736
|
-
throw new Error("gjc_lifecycle_owner_server_unverifiable");
|
|
737
|
-
if (!(await isLifecycleGenerationUnchanged(stateDir, ids.intendedSessionId, previousBaseline)))
|
|
738
|
-
throw new Error("gjc_lifecycle_owner_generation_changed");
|
|
739
|
-
await replaceOwnerGeneration(stateDir, ids.intendedSessionId, generation, previousBaseline);
|
|
740
|
-
} catch (error) {
|
|
741
|
-
let cleanupFailure: unknown;
|
|
742
|
-
if (ownerExecution?.attemptCreated) {
|
|
743
|
-
try {
|
|
744
|
-
await cleanupLifecycleAttempt({
|
|
745
|
-
tmux,
|
|
746
|
-
env,
|
|
747
|
-
serverKey: ownerExecution.serverKey,
|
|
748
|
-
nativeSessionId: ownerExecution.nativeSessionId,
|
|
749
|
-
attemptSession: ownerExecution.attemptSession,
|
|
750
|
-
expectedServerPid: ownerExecution.serverPid,
|
|
751
|
-
expectedServerStartTime: ownerExecution.serverStartTime,
|
|
752
|
-
ownerIsolationProbe: opts.ownerIsolationProbe,
|
|
753
|
-
});
|
|
754
|
-
} catch (cleanupError) {
|
|
755
|
-
cleanupFailure = cleanupError;
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
if (cleanupFailure !== undefined)
|
|
759
|
-
throw new AggregateError([error, cleanupFailure], "gjc_lifecycle_cleanup_uncertain");
|
|
760
|
-
throw error;
|
|
761
|
-
}
|
|
831
|
+
await completeLifecycleSpawnTransaction({
|
|
832
|
+
tmux,
|
|
833
|
+
env,
|
|
834
|
+
sessionId: ids.intendedSessionId,
|
|
835
|
+
generation,
|
|
836
|
+
stateDir,
|
|
837
|
+
cwd,
|
|
838
|
+
sessionName: name,
|
|
839
|
+
sessionStateFile,
|
|
840
|
+
argv: [tmux, "new-session", "-d", "-P", "-F", "#{session_id}", "-s", name, "sh", "-c", command],
|
|
841
|
+
ownerIsolationProbe: opts.ownerIsolationProbe,
|
|
842
|
+
prepareSpawn: () => {
|
|
843
|
+
if (frame.target.kind === "plain_dir") fs.mkdirSync(cwd, { recursive: true });
|
|
844
|
+
},
|
|
845
|
+
});
|
|
762
846
|
|
|
763
847
|
return {
|
|
764
848
|
sessionId: ids.intendedSessionId,
|
|
@@ -912,7 +996,6 @@ export function daemonResumeSession(
|
|
|
912
996
|
const sessionStateFile = lifecycleRuntimeStateFile(resolvedResumeCwd, resumeId, name);
|
|
913
997
|
const stateDir = path.dirname(sessionStateFile);
|
|
914
998
|
const generation = crypto.randomUUID();
|
|
915
|
-
const previousBaseline = await captureOwnerGenerationBaseline(stateDir, resumeId);
|
|
916
999
|
const childEnv: Record<string, string> = {
|
|
917
1000
|
GJC_TMUX_LAUNCHED: "1",
|
|
918
1001
|
GJC_NOTIFICATIONS: "1",
|
|
@@ -926,84 +1009,18 @@ export function daemonResumeSession(
|
|
|
926
1009
|
.map(([key, value]) => `${key}=${shellQuote(value)}`)
|
|
927
1010
|
.join(" ");
|
|
928
1011
|
const command = `cd ${shellQuote(resolvedResumeCwd)} && exec env ${envPairs} gjc --resume ${shellQuote(resumeId)}`;
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
onAttemptCreated: attempt => {
|
|
942
|
-
ownerExecution = attempt;
|
|
943
|
-
},
|
|
944
|
-
previousBaseline,
|
|
945
|
-
});
|
|
946
|
-
if (!ownerExecution.nativeSessionId || ownerExecution.serverPid === undefined)
|
|
947
|
-
throw new Error("gjc_lifecycle_owner_server_unverifiable");
|
|
948
|
-
const tgt = `${ownerExecution.nativeSessionId}:`;
|
|
949
|
-
await applyRequiredLifecycleTmuxMetadata(
|
|
950
|
-
tmux,
|
|
951
|
-
tgt,
|
|
952
|
-
env,
|
|
953
|
-
{
|
|
954
|
-
sessionId: resumeId,
|
|
955
|
-
sessionStateFile,
|
|
956
|
-
project: resolvedResumeCwd,
|
|
957
|
-
ownerGeneration: generation,
|
|
958
|
-
ownerServerKey: ownerExecution.serverKey,
|
|
959
|
-
},
|
|
960
|
-
{
|
|
961
|
-
nativeSessionId: ownerExecution.nativeSessionId,
|
|
962
|
-
attemptSession: ownerExecution.attemptSession,
|
|
963
|
-
serverPid: ownerExecution.serverPid,
|
|
964
|
-
},
|
|
965
|
-
);
|
|
966
|
-
if (
|
|
967
|
-
!ownerExecution.nativeSessionId ||
|
|
968
|
-
ownerExecution.serverPid === undefined ||
|
|
969
|
-
ownerExecution.serverStartTime === undefined ||
|
|
970
|
-
!(await reproveLifecycleAttempt({
|
|
971
|
-
tmux,
|
|
972
|
-
env,
|
|
973
|
-
serverKey: ownerExecution.serverKey,
|
|
974
|
-
nativeSessionId: ownerExecution.nativeSessionId,
|
|
975
|
-
attemptSession: ownerExecution.attemptSession,
|
|
976
|
-
expectedServerPid: ownerExecution.serverPid,
|
|
977
|
-
expectedServerStartTime: ownerExecution.serverStartTime,
|
|
978
|
-
ownerIsolationProbe: opts.ownerIsolationProbe,
|
|
979
|
-
}))
|
|
980
|
-
)
|
|
981
|
-
throw new Error("gjc_lifecycle_owner_server_unverifiable");
|
|
982
|
-
if (!(await isLifecycleGenerationUnchanged(stateDir, resumeId, previousBaseline)))
|
|
983
|
-
throw new Error("gjc_lifecycle_owner_generation_changed");
|
|
984
|
-
await replaceOwnerGeneration(stateDir, resumeId, generation, previousBaseline);
|
|
985
|
-
} catch (error) {
|
|
986
|
-
let cleanupFailure: unknown;
|
|
987
|
-
if (ownerExecution?.attemptCreated) {
|
|
988
|
-
try {
|
|
989
|
-
await cleanupLifecycleAttempt({
|
|
990
|
-
tmux,
|
|
991
|
-
env,
|
|
992
|
-
serverKey: ownerExecution.serverKey,
|
|
993
|
-
nativeSessionId: ownerExecution.nativeSessionId,
|
|
994
|
-
attemptSession: ownerExecution.attemptSession,
|
|
995
|
-
expectedServerPid: ownerExecution.serverPid,
|
|
996
|
-
expectedServerStartTime: ownerExecution.serverStartTime,
|
|
997
|
-
ownerIsolationProbe: opts.ownerIsolationProbe,
|
|
998
|
-
});
|
|
999
|
-
} catch (cleanupError) {
|
|
1000
|
-
cleanupFailure = cleanupError;
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
if (cleanupFailure !== undefined)
|
|
1004
|
-
throw new AggregateError([error, cleanupFailure], "gjc_lifecycle_cleanup_uncertain");
|
|
1005
|
-
throw error;
|
|
1006
|
-
}
|
|
1012
|
+
await completeLifecycleSpawnTransaction({
|
|
1013
|
+
tmux,
|
|
1014
|
+
env,
|
|
1015
|
+
sessionId: resumeId,
|
|
1016
|
+
generation,
|
|
1017
|
+
stateDir,
|
|
1018
|
+
cwd: resolvedResumeCwd,
|
|
1019
|
+
sessionName: name,
|
|
1020
|
+
sessionStateFile,
|
|
1021
|
+
argv: [tmux, "new-session", "-d", "-P", "-F", "#{session_id}", "-s", name, "sh", "-c", command],
|
|
1022
|
+
ownerIsolationProbe: opts.ownerIsolationProbe,
|
|
1023
|
+
});
|
|
1007
1024
|
|
|
1008
1025
|
return {
|
|
1009
1026
|
sessionId: resumeId,
|
|
@@ -1034,39 +1051,50 @@ export function outcomeToResponse(frame: SessionLifecycleRequest, outcome: Lifec
|
|
|
1034
1051
|
};
|
|
1035
1052
|
}
|
|
1036
1053
|
const e = outcome.entry;
|
|
1054
|
+
if (e.state !== "success") throw new Error("invalid lifecycle success ledger entry");
|
|
1037
1055
|
if (frame.type === "session_create") {
|
|
1056
|
+
if (typeof e.sessionId !== "string" || typeof e.endpointUrl !== "string")
|
|
1057
|
+
throw new Error("invalid create success ledger entry");
|
|
1038
1058
|
return {
|
|
1039
1059
|
type: "session_create_response",
|
|
1040
1060
|
requestId: frame.requestId,
|
|
1041
1061
|
status: "ok",
|
|
1042
1062
|
lifecycleRequestId: frame.lifecycleRequestId,
|
|
1043
|
-
sessionId: e.sessionId
|
|
1063
|
+
sessionId: e.sessionId,
|
|
1044
1064
|
matchedBy: "spawn_marker",
|
|
1045
|
-
endpoint: { url: e.endpointUrl
|
|
1065
|
+
endpoint: { url: e.endpointUrl, token: "" },
|
|
1046
1066
|
topic: { chatId: frame.chatId, threadId: "" },
|
|
1047
1067
|
target: frame.target,
|
|
1048
1068
|
};
|
|
1049
1069
|
}
|
|
1050
1070
|
if (frame.type === "session_close") {
|
|
1071
|
+
if (typeof e.sessionId !== "string" || typeof e.processGone !== "boolean")
|
|
1072
|
+
throw new Error("invalid close success ledger entry");
|
|
1051
1073
|
return {
|
|
1052
1074
|
type: "session_close_response",
|
|
1053
1075
|
requestId: frame.requestId,
|
|
1054
1076
|
status: "ok",
|
|
1055
|
-
sessionId: e.sessionId
|
|
1056
|
-
processGone: e.processGone
|
|
1077
|
+
sessionId: e.sessionId,
|
|
1078
|
+
processGone: e.processGone,
|
|
1057
1079
|
historyPreserved: true,
|
|
1058
1080
|
// The killed session's per-session endpoint record is reaped by the
|
|
1059
1081
|
// daemon's dead-PID scan (scanRoots), so it is effectively stale.
|
|
1060
|
-
endpointStale: e.processGone
|
|
1082
|
+
endpointStale: e.processGone,
|
|
1061
1083
|
};
|
|
1062
1084
|
}
|
|
1085
|
+
if (
|
|
1086
|
+
typeof e.sessionId !== "string" ||
|
|
1087
|
+
typeof e.endpointUrl !== "string" ||
|
|
1088
|
+
(e.resumeMode !== "reattached" && e.resumeMode !== "cold_restarted")
|
|
1089
|
+
)
|
|
1090
|
+
throw new Error("invalid resume success ledger entry");
|
|
1063
1091
|
return {
|
|
1064
1092
|
type: "session_resume_response",
|
|
1065
1093
|
requestId: frame.requestId,
|
|
1066
1094
|
status: "ok",
|
|
1067
|
-
sessionId: e.sessionId
|
|
1068
|
-
mode: outcome.mode ??
|
|
1069
|
-
endpoint: { url: e.endpointUrl
|
|
1095
|
+
sessionId: e.sessionId,
|
|
1096
|
+
mode: outcome.mode ?? e.resumeMode,
|
|
1097
|
+
endpoint: { url: e.endpointUrl, token: "" },
|
|
1070
1098
|
topic: { chatId: frame.chatId, threadId: "" },
|
|
1071
1099
|
};
|
|
1072
1100
|
}
|
|
@@ -1126,6 +1154,10 @@ function isSafeLifecycleId(value: unknown): value is string {
|
|
|
1126
1154
|
return typeof value === "string" && !hasLoneUtf16Surrogate(value);
|
|
1127
1155
|
}
|
|
1128
1156
|
|
|
1157
|
+
function isNonEmptySafeLifecycleId(value: unknown): value is string {
|
|
1158
|
+
return isSafeLifecycleId(value) && value.length > 0;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1129
1161
|
/** The native server authenticates callbacks before redacting the control token. */
|
|
1130
1162
|
type AuthenticatedNativeLifecycleRequest =
|
|
1131
1163
|
| Omit<SessionCreateFrame, "token">
|
|
@@ -1149,8 +1181,8 @@ function isBoundedRequestFrame(frame: unknown): frame is AuthenticatedNativeLife
|
|
|
1149
1181
|
switch (frame.type) {
|
|
1150
1182
|
case "session_create":
|
|
1151
1183
|
return (
|
|
1152
|
-
|
|
1153
|
-
|
|
1184
|
+
isNonEmptySafeLifecycleId(frame.lifecycleRequestId) &&
|
|
1185
|
+
isNonEmptySafeLifecycleId(frame.intendedSessionId) &&
|
|
1154
1186
|
(typeof frame.startupPromptRef === "undefined" || typeof frame.startupPromptRef === "string") &&
|
|
1155
1187
|
(typeof frame.modelPreset === "undefined" || typeof frame.modelPreset === "string") &&
|
|
1156
1188
|
((frame.target.kind === "worktree" &&
|
|
@@ -1231,32 +1263,29 @@ export function attachLifecycleControl(server: ControlServerLike, deps: Orchestr
|
|
|
1231
1263
|
export function buildOrchestratorDeps(input: {
|
|
1232
1264
|
pairedChatId: string;
|
|
1233
1265
|
agentNotificationsDir: string;
|
|
1266
|
+
/** Required in-memory, 32-byte audit-v2 redaction key. */
|
|
1267
|
+
auditRedactionKey: Uint8Array;
|
|
1234
1268
|
/** Root of saved session histories (`<agentDir>/sessions`), for resume resolution. */
|
|
1235
1269
|
sessionsRoot?: string;
|
|
1236
1270
|
env?: NodeJS.ProcessEnv;
|
|
1237
1271
|
}): OrchestratorDeps {
|
|
1272
|
+
if (input.auditRedactionKey.byteLength !== 32) throw new Error("invalid_audit_redaction_key");
|
|
1238
1273
|
const env = input.env ?? process.env;
|
|
1239
1274
|
return {
|
|
1240
1275
|
pairedChatId: input.pairedChatId,
|
|
1276
|
+
auditRedactionKey: input.auditRedactionKey,
|
|
1241
1277
|
now: () => Date.now(),
|
|
1242
1278
|
store: fileLedgerStore(path.join(input.agentNotificationsDir, "telegram-lifecycle-idempotency.json")),
|
|
1243
1279
|
audit: fileAudit(path.join(input.agentNotificationsDir, "telegram-lifecycle-audit.jsonl")),
|
|
1280
|
+
isPsmuxProvider: () => resolveGjcTmuxBinary({ env }).isPsmux,
|
|
1244
1281
|
allowCreate: createRateLimiter(3, 10 * 60 * 1000),
|
|
1245
|
-
writeStartupPrompt: async (
|
|
1282
|
+
writeStartupPrompt: async (_requestId, prompt, _persistRef) => {
|
|
1246
1283
|
if (prompt === undefined) return undefined;
|
|
1247
|
-
|
|
1248
|
-
fs.mkdirSync(path.dirname(ref), { recursive: true });
|
|
1249
|
-
const fd = fs.openSync(ref, "w", 0o600);
|
|
1250
|
-
fs.writeSync(fd, prompt);
|
|
1251
|
-
fs.fsyncSync(fd);
|
|
1252
|
-
fs.closeSync(fd);
|
|
1253
|
-
return ref;
|
|
1284
|
+
throw new Error("startup_prompt_capability_transport_unavailable");
|
|
1254
1285
|
},
|
|
1255
1286
|
spawnCreate: daemonSpawnCreate(env),
|
|
1256
1287
|
closeSession: daemonCloseSession(env),
|
|
1257
1288
|
resumeSession: daemonResumeSession(env, { sessionsRoot: input.sessionsRoot }),
|
|
1258
|
-
newLifecycleRequestId: () => `lc-${crypto.randomUUID()}`,
|
|
1259
|
-
newSessionId: () => `s${crypto.randomUUID().slice(0, 8)}`,
|
|
1260
1289
|
};
|
|
1261
1290
|
}
|
|
1262
1291
|
|
|
@@ -1267,6 +1296,6 @@ export function buildOrchestratorDeps(input: {
|
|
|
1267
1296
|
export const createNativeControlServer: LifecycleControlServerFactory = ({ token, ownerId, agentDir }) => {
|
|
1268
1297
|
// Lazy require so loading this module (for the orchestrator / wiring / tests)
|
|
1269
1298
|
// never eagerly resolves the native addon — only a real production start does.
|
|
1270
|
-
const { NotificationControlServer } = require("@gajae-code/natives") as
|
|
1271
|
-
return new NotificationControlServer(token, ownerId, agentDir)
|
|
1299
|
+
const { NotificationControlServer } = require("@gajae-code/natives") as NativeControlServerModule;
|
|
1300
|
+
return new NotificationControlServer(token, ownerId, agentDir);
|
|
1272
1301
|
};
|