@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
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { dlopen, ptr } from "bun:ffi";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import { Process } from "@gajae-code/natives";
|
|
4
|
+
|
|
5
|
+
const DARWIN_PROC_PIDTBSDINFO = 3;
|
|
6
|
+
const DARWIN_PROC_BSDINFO_SIZE = 136;
|
|
7
|
+
const DARWIN_PROC_BSDINFO_START_SECONDS_OFFSET = 120;
|
|
8
|
+
const DARWIN_PROC_BSDINFO_START_MICROSECONDS_OFFSET = 128;
|
|
9
|
+
const POWERSHELL_PROCESS_INCARNATION_COMMAND = "powershell.exe";
|
|
10
|
+
const WIN32_PROCESS_INCARNATION_OUTPUT = /^(\d+)\t(0|[1-9]\d*)(?:\r?\n)?$/;
|
|
11
|
+
const MAX_WINDOWS_FILETIME_TICKS = 18_446_744_073_709_551_615n;
|
|
12
|
+
|
|
13
|
+
const darwinProcLibrary =
|
|
14
|
+
process.platform === "darwin"
|
|
15
|
+
? (() => {
|
|
16
|
+
try {
|
|
17
|
+
return dlopen("/usr/lib/libproc.dylib", {
|
|
18
|
+
proc_pidinfo: {
|
|
19
|
+
args: ["i32", "i32", "u64", "ptr", "i32"],
|
|
20
|
+
returns: "i32",
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
} catch {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
})()
|
|
27
|
+
: undefined;
|
|
28
|
+
|
|
29
|
+
type ProcessIncarnationCommandResult = { exitCode: number | null; stdout: string } | undefined;
|
|
30
|
+
|
|
31
|
+
export type ProcessIncarnationCommandRunner = (
|
|
32
|
+
command: string,
|
|
33
|
+
args: readonly string[],
|
|
34
|
+
) => ProcessIncarnationCommandResult;
|
|
35
|
+
|
|
36
|
+
export interface ProcessIncarnationOptions {
|
|
37
|
+
platform?: typeof process.platform;
|
|
38
|
+
runCommand?: ProcessIncarnationCommandRunner;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function runProcessIncarnationCommand(command: string, args: readonly string[]): ProcessIncarnationCommandResult {
|
|
42
|
+
try {
|
|
43
|
+
const result = Bun.spawnSync([command, ...args], { stdin: "ignore", stdout: "pipe", stderr: "ignore" });
|
|
44
|
+
return { exitCode: result.exitCode, stdout: Buffer.from(result.stdout).toString("utf8") };
|
|
45
|
+
} catch {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function windowsProcessIncarnationCommand(pid: number): { command: string; args: string[] } {
|
|
51
|
+
return {
|
|
52
|
+
command: POWERSHELL_PROCESS_INCARNATION_COMMAND,
|
|
53
|
+
args: [
|
|
54
|
+
"-NoLogo",
|
|
55
|
+
"-NoProfile",
|
|
56
|
+
"-NonInteractive",
|
|
57
|
+
"-Command",
|
|
58
|
+
[
|
|
59
|
+
"$ErrorActionPreference = 'Stop'",
|
|
60
|
+
"$OutputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)",
|
|
61
|
+
`$process = Get-Process -Id ${pid} -ErrorAction Stop`,
|
|
62
|
+
"$filetime = [UInt64]($process.StartTime.ToUniversalTime().ToFileTimeUtc())",
|
|
63
|
+
'[Console]::Out.WriteLine(("{0}`t{1}" -f $process.Id, $filetime))',
|
|
64
|
+
].join("; "),
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function isWindowsFiletimeTicks(value: string): boolean {
|
|
70
|
+
if (!/^(?:0|[1-9]\d*)$/.test(value)) return false;
|
|
71
|
+
try {
|
|
72
|
+
return BigInt(value) <= MAX_WINDOWS_FILETIME_TICKS;
|
|
73
|
+
} catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function parseWin32ProcessIncarnation(pid: number, output: string): string | undefined {
|
|
79
|
+
const match = WIN32_PROCESS_INCARNATION_OUTPUT.exec(output);
|
|
80
|
+
if (!match || match[1] !== String(pid) || !isWindowsFiletimeTicks(match[2])) return undefined;
|
|
81
|
+
return `windows:${match[2]}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Parse the microsecond-resolution start timestamp returned by Darwin proc_pidinfo. */
|
|
85
|
+
export function parseDarwinProcessIncarnation(info: Uint8Array): string | undefined {
|
|
86
|
+
if (info.byteLength < DARWIN_PROC_BSDINFO_SIZE) return undefined;
|
|
87
|
+
try {
|
|
88
|
+
const view = new DataView(info.buffer, info.byteOffset, info.byteLength);
|
|
89
|
+
const seconds = view.getBigUint64(DARWIN_PROC_BSDINFO_START_SECONDS_OFFSET, true);
|
|
90
|
+
const microseconds = view.getBigUint64(DARWIN_PROC_BSDINFO_START_MICROSECONDS_OFFSET, true);
|
|
91
|
+
if (seconds === 0n || microseconds >= 1_000_000n) return undefined;
|
|
92
|
+
return `darwin:${seconds}:${microseconds}`;
|
|
93
|
+
} catch {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function isProcessIncarnation(value: unknown): value is string {
|
|
99
|
+
return (
|
|
100
|
+
typeof value === "string" &&
|
|
101
|
+
(/^(?:linux:\d+|darwin:[1-9]\d*:\d+)$/.test(value) ||
|
|
102
|
+
(value.startsWith("windows:") && isWindowsFiletimeTicks(value.slice("windows:".length))))
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** A PID is reusable; bind it to the strongest OS-provided process start incarnation available. */
|
|
107
|
+
export function processIncarnation(pid: number, options: ProcessIncarnationOptions = {}): string | undefined {
|
|
108
|
+
if (!Number.isSafeInteger(pid) || pid <= 0) return undefined;
|
|
109
|
+
const platform = options.platform ?? process.platform;
|
|
110
|
+
if (platform === process.platform && options.runCommand === undefined) {
|
|
111
|
+
try {
|
|
112
|
+
const nativeProcess = Process.fromPid(pid) as { incarnation?: unknown } | null;
|
|
113
|
+
if (isProcessIncarnation(nativeProcess?.incarnation)) return nativeProcess.incarnation;
|
|
114
|
+
} catch {
|
|
115
|
+
// Fall through to the platform-specific reader.
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (platform === "linux") {
|
|
119
|
+
try {
|
|
120
|
+
const stat = fs.readFileSync(`/proc/${pid}/stat`, "utf8");
|
|
121
|
+
const close = stat.lastIndexOf(")");
|
|
122
|
+
const startTicks = stat
|
|
123
|
+
.slice(close + 2)
|
|
124
|
+
.trim()
|
|
125
|
+
.split(/\s+/)[19];
|
|
126
|
+
return startTicks ? `linux:${startTicks}` : undefined;
|
|
127
|
+
} catch {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (platform === "darwin") {
|
|
132
|
+
const info = new Uint8Array(DARWIN_PROC_BSDINFO_SIZE);
|
|
133
|
+
try {
|
|
134
|
+
const bytesRead = darwinProcLibrary?.symbols.proc_pidinfo(
|
|
135
|
+
pid,
|
|
136
|
+
DARWIN_PROC_PIDTBSDINFO,
|
|
137
|
+
0,
|
|
138
|
+
ptr(info),
|
|
139
|
+
info.byteLength,
|
|
140
|
+
);
|
|
141
|
+
return bytesRead === DARWIN_PROC_BSDINFO_SIZE ? parseDarwinProcessIncarnation(info) : undefined;
|
|
142
|
+
} catch {
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (platform === "win32") {
|
|
147
|
+
const command = windowsProcessIncarnationCommand(pid);
|
|
148
|
+
let result: ProcessIncarnationCommandResult;
|
|
149
|
+
try {
|
|
150
|
+
result = (options.runCommand ?? runProcessIncarnationCommand)(command.command, command.args);
|
|
151
|
+
} catch {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
return result?.exitCode === 0 && typeof result.stdout === "string"
|
|
155
|
+
? parseWin32ProcessIncarnation(pid, result.stdout)
|
|
156
|
+
: undefined;
|
|
157
|
+
}
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import internalSourceMarker from "./internal-source-marker-2178.txt" with { type: "file" };
|
|
4
|
+
|
|
5
|
+
export type SdkInternalAction = "broker-internal" | "session-host-internal";
|
|
6
|
+
|
|
7
|
+
export type SdkInternalSpawnCommand =
|
|
8
|
+
| {
|
|
9
|
+
kind: "bun-source";
|
|
10
|
+
file: string;
|
|
11
|
+
args: string[];
|
|
12
|
+
env: NodeJS.ProcessEnv;
|
|
13
|
+
cwd: string;
|
|
14
|
+
}
|
|
15
|
+
| {
|
|
16
|
+
kind: "compiled";
|
|
17
|
+
file: string;
|
|
18
|
+
args: string[];
|
|
19
|
+
env: NodeJS.ProcessEnv;
|
|
20
|
+
cwd?: undefined;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type EmbeddedFile = Blob | { name: string };
|
|
24
|
+
|
|
25
|
+
/** Test-only injectable inputs for hostile evidence and platform grammar coverage. */
|
|
26
|
+
export interface SdkInternalRuntimeDescriptorTestOptions {
|
|
27
|
+
execPath?: string;
|
|
28
|
+
environment?: NodeJS.ProcessEnv;
|
|
29
|
+
embeddedFiles?: readonly EmbeddedFile[];
|
|
30
|
+
markerPath?: string;
|
|
31
|
+
brokerDirectory?: string;
|
|
32
|
+
cliPath?: string;
|
|
33
|
+
configPath?: string;
|
|
34
|
+
bunAvailable?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const COMPILED_MARKER_NAME = /^internal-source-marker-2178-[A-Za-z0-9]+\.txt$/;
|
|
38
|
+
const POSIX_MARKER_VFS_PATH = /^\/\$bunfs\/root\/internal-source-marker-2178-[A-Za-z0-9]+\.txt$/;
|
|
39
|
+
const WINDOWS_MARKER_VFS_PATH = /^[A-Za-z]:\/~BUN\/(?:root\/)?internal-source-marker-2178-[A-Za-z0-9]+\.txt$/;
|
|
40
|
+
|
|
41
|
+
function isCompiledMarkerPath(markerPath: string): boolean {
|
|
42
|
+
const normalized = markerPath.replaceAll("\\", "/");
|
|
43
|
+
return POSIX_MARKER_VFS_PATH.test(normalized) || WINDOWS_MARKER_VFS_PATH.test(normalized);
|
|
44
|
+
}
|
|
45
|
+
function embeddedFileName(file: EmbeddedFile): string | undefined {
|
|
46
|
+
return "name" in file && typeof file.name === "string" ? file.name : undefined;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function containedPath(parent: string, candidate: string): boolean {
|
|
50
|
+
const relative = path.relative(parent, candidate);
|
|
51
|
+
return relative === "" || (!relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function regularReadablePath(file: string, label: string): string {
|
|
55
|
+
let canonical: string;
|
|
56
|
+
try {
|
|
57
|
+
canonical = fs.realpathSync(file);
|
|
58
|
+
const stat = fs.statSync(canonical);
|
|
59
|
+
fs.accessSync(canonical, fs.constants.R_OK);
|
|
60
|
+
if (!stat.isFile()) throw new Error("not a regular file");
|
|
61
|
+
} catch {
|
|
62
|
+
throw new Error(`SDK internal launch refused: ${label} is not a readable regular file.`);
|
|
63
|
+
}
|
|
64
|
+
return canonical;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function internalEnvironment(environment: NodeJS.ProcessEnv, source: boolean): NodeJS.ProcessEnv {
|
|
68
|
+
const isolated = { ...environment };
|
|
69
|
+
delete isolated.BUN_OPTIONS;
|
|
70
|
+
if (source) {
|
|
71
|
+
delete isolated.PI_COMPILED;
|
|
72
|
+
delete isolated.GJC_COMPILED;
|
|
73
|
+
}
|
|
74
|
+
return isolated;
|
|
75
|
+
}
|
|
76
|
+
function expectedPackageName(packageDirectory: string): void {
|
|
77
|
+
try {
|
|
78
|
+
const manifest = JSON.parse(fs.readFileSync(path.join(packageDirectory, "package.json"), "utf8")) as {
|
|
79
|
+
name?: unknown;
|
|
80
|
+
};
|
|
81
|
+
if (manifest.name !== "@gajae-code/coding-agent") throw new Error("unexpected package name");
|
|
82
|
+
} catch {
|
|
83
|
+
throw new Error("SDK internal launch refused: product package identity is invalid.");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function sourceDescriptor(
|
|
88
|
+
action: SdkInternalAction,
|
|
89
|
+
options: SdkInternalRuntimeDescriptorTestOptions,
|
|
90
|
+
markerPath: string,
|
|
91
|
+
): SdkInternalSpawnCommand {
|
|
92
|
+
if (options.bunAvailable === false || typeof Bun === "undefined")
|
|
93
|
+
throw new Error("SDK internal launch refused: Bun source runtime is unavailable.");
|
|
94
|
+
const brokerDirectory = path.resolve(options.brokerDirectory ?? import.meta.dir);
|
|
95
|
+
const packageDirectory = path.resolve(brokerDirectory, "../../..");
|
|
96
|
+
const sourceDirectory = path.resolve(brokerDirectory, "../..");
|
|
97
|
+
const runtime = regularReadablePath(path.resolve(options.execPath ?? process.execPath), "runtime executable");
|
|
98
|
+
const cli = regularReadablePath(
|
|
99
|
+
path.resolve(options.cliPath ?? path.join(sourceDirectory, "cli.ts")),
|
|
100
|
+
"CLI entrypoint",
|
|
101
|
+
);
|
|
102
|
+
const config = regularReadablePath(
|
|
103
|
+
path.resolve(options.configPath ?? path.join(brokerDirectory, "internal-source.bunfig.toml")),
|
|
104
|
+
"isolated Bun configuration",
|
|
105
|
+
);
|
|
106
|
+
const marker = regularReadablePath(path.resolve(markerPath), "source marker");
|
|
107
|
+
const canonicalBrokerDirectory = fs.realpathSync(brokerDirectory);
|
|
108
|
+
const canonicalPackageDirectory = fs.realpathSync(packageDirectory);
|
|
109
|
+
const canonicalSourceDirectory = fs.realpathSync(sourceDirectory);
|
|
110
|
+
expectedPackageName(canonicalPackageDirectory);
|
|
111
|
+
if (
|
|
112
|
+
!containedPath(canonicalPackageDirectory, canonicalBrokerDirectory) ||
|
|
113
|
+
!containedPath(canonicalPackageDirectory, canonicalSourceDirectory) ||
|
|
114
|
+
!containedPath(canonicalSourceDirectory, cli) ||
|
|
115
|
+
!containedPath(canonicalBrokerDirectory, config) ||
|
|
116
|
+
!containedPath(canonicalBrokerDirectory, marker)
|
|
117
|
+
)
|
|
118
|
+
throw new Error("SDK internal launch refused: product runtime assets escape their trusted directories.");
|
|
119
|
+
return {
|
|
120
|
+
kind: "bun-source",
|
|
121
|
+
file: runtime,
|
|
122
|
+
args: ["--no-env-file", `--config=${config}`, cli, "sdk", action],
|
|
123
|
+
env: internalEnvironment(options.environment ?? process.env, true),
|
|
124
|
+
cwd: canonicalBrokerDirectory,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function resolveSdkInternalSpawnCommandWithEvidence(
|
|
129
|
+
action: SdkInternalAction,
|
|
130
|
+
options: SdkInternalRuntimeDescriptorTestOptions,
|
|
131
|
+
): SdkInternalSpawnCommand {
|
|
132
|
+
const markerPath = options.markerPath ?? internalSourceMarker;
|
|
133
|
+
const embeddedFiles = options.embeddedFiles ?? (typeof Bun === "undefined" ? undefined : Bun.embeddedFiles);
|
|
134
|
+
if (!embeddedFiles) throw new Error("SDK internal launch refused: Bun runtime evidence is unavailable.");
|
|
135
|
+
const markerName = path.basename(markerPath.replaceAll("\\", "/"));
|
|
136
|
+
const markerEntries = embeddedFiles.filter(file => embeddedFileName(file) === markerName);
|
|
137
|
+
const compiledMarkerPath = isCompiledMarkerPath(markerPath);
|
|
138
|
+
const exactCompiledArtifact = COMPILED_MARKER_NAME.test(markerName) && markerEntries.length === 1;
|
|
139
|
+
const isSourceMarker = path.isAbsolute(markerPath) && !compiledMarkerPath;
|
|
140
|
+
if (embeddedFiles.length === 0 && isSourceMarker) return sourceDescriptor(action, options, markerPath);
|
|
141
|
+
if (exactCompiledArtifact && compiledMarkerPath) {
|
|
142
|
+
const executable = regularReadablePath(path.resolve(options.execPath ?? process.execPath), "compiled executable");
|
|
143
|
+
return {
|
|
144
|
+
kind: "compiled",
|
|
145
|
+
file: executable,
|
|
146
|
+
args: ["sdk", action],
|
|
147
|
+
env: internalEnvironment(options.environment ?? process.env, false),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
throw new Error("SDK internal launch refused: compiled-runtime marker evidence is inconsistent.");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** Resolve the production descriptor from the statically imported marker and current Bun runtime evidence. */
|
|
154
|
+
export function resolveSdkInternalSpawnCommand(action: SdkInternalAction): SdkInternalSpawnCommand {
|
|
155
|
+
return resolveSdkInternalSpawnCommandWithEvidence(action, {});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Test hook: injects runtime evidence without weakening the production marker authority. */
|
|
159
|
+
export function resolveSdkInternalSpawnCommandForTest(
|
|
160
|
+
action: SdkInternalAction,
|
|
161
|
+
options: SdkInternalRuntimeDescriptorTestOptions,
|
|
162
|
+
): SdkInternalSpawnCommand {
|
|
163
|
+
return resolveSdkInternalSpawnCommandWithEvidence(action, options);
|
|
164
|
+
}
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import * as fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { withFileLock } from "../../config/file-lock";
|
|
5
|
+
import { assertSupportedStateVersion, SDK_STATE_VERSION, UnsupportedStateVersionError } from "./state-version";
|
|
6
|
+
|
|
7
|
+
export type SessionIndexEventType =
|
|
8
|
+
| "host_registered"
|
|
9
|
+
| "host_heartbeat"
|
|
10
|
+
| "host_unregistered"
|
|
11
|
+
| "lifecycle_started"
|
|
12
|
+
| "lifecycle_terminal"
|
|
13
|
+
| "session_closed"
|
|
14
|
+
| "record_reconciled";
|
|
15
|
+
export interface SessionIndexEvent {
|
|
16
|
+
version: typeof SDK_STATE_VERSION;
|
|
17
|
+
indexSeq: number;
|
|
18
|
+
type: SessionIndexEventType;
|
|
19
|
+
sessionId: string;
|
|
20
|
+
locator: { repo: string; stateRoot: string };
|
|
21
|
+
endpointGeneration: number;
|
|
22
|
+
pid: number;
|
|
23
|
+
endpointMtimeMs?: number;
|
|
24
|
+
lifecycleRequestId?: string;
|
|
25
|
+
terminalUncertain?: boolean;
|
|
26
|
+
ts: number;
|
|
27
|
+
checksum: string;
|
|
28
|
+
}
|
|
29
|
+
export interface IndexedSession {
|
|
30
|
+
sessionId: string;
|
|
31
|
+
locator: { repo: string; stateRoot: string };
|
|
32
|
+
endpointGeneration: number;
|
|
33
|
+
pid: number;
|
|
34
|
+
endpointMtimeMs?: number;
|
|
35
|
+
live: boolean;
|
|
36
|
+
indexSeq: number;
|
|
37
|
+
lifecycleRequestId?: string;
|
|
38
|
+
terminalUncertain?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface SessionList {
|
|
41
|
+
indexSeq: number;
|
|
42
|
+
sessions: IndexedSession[];
|
|
43
|
+
warnings: string[];
|
|
44
|
+
}
|
|
45
|
+
const canonical = (event: Omit<SessionIndexEvent, "checksum">) => JSON.stringify(event);
|
|
46
|
+
export const sessionIndexChecksum = (event: Omit<SessionIndexEvent, "checksum">) =>
|
|
47
|
+
createHash("sha256").update(canonical(event)).digest("hex");
|
|
48
|
+
const dirFor = (agentDir: string) => path.join(agentDir, "sdk", "sessions");
|
|
49
|
+
const logFor = (agentDir: string) => path.join(dirFor(agentDir), "index.jsonl");
|
|
50
|
+
const snapshotFor = (agentDir: string) => path.join(dirFor(agentDir), "index.snapshot.json");
|
|
51
|
+
async function appendSync(file: string, value: string): Promise<void> {
|
|
52
|
+
const h = await fs.open(file, "a", 0o600);
|
|
53
|
+
try {
|
|
54
|
+
await h.write(`${value}\n`);
|
|
55
|
+
await h.sync();
|
|
56
|
+
} finally {
|
|
57
|
+
await h.close();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function alive(pid: number): boolean {
|
|
61
|
+
try {
|
|
62
|
+
process.kill(pid, 0);
|
|
63
|
+
return true;
|
|
64
|
+
} catch (e) {
|
|
65
|
+
return (e as NodeJS.ErrnoException).code === "EPERM";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export class SessionIndex {
|
|
69
|
+
#agentDir: string;
|
|
70
|
+
#events: SessionIndexEvent[] = [];
|
|
71
|
+
#warnings: string[] = [];
|
|
72
|
+
#logOffset = 0;
|
|
73
|
+
constructor(agentDir: string) {
|
|
74
|
+
this.#agentDir = agentDir;
|
|
75
|
+
}
|
|
76
|
+
async open(): Promise<this> {
|
|
77
|
+
await this.assertSupportedStateVersions();
|
|
78
|
+
await fs.mkdir(dirFor(this.#agentDir), { recursive: true, mode: 0o700 });
|
|
79
|
+
await fs.chmod(dirFor(this.#agentDir), 0o700);
|
|
80
|
+
await this.replay();
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
async replay(): Promise<void> {
|
|
84
|
+
this.#events = [];
|
|
85
|
+
this.#warnings = [];
|
|
86
|
+
this.#logOffset = 0;
|
|
87
|
+
let snapshotSeq = 0;
|
|
88
|
+
try {
|
|
89
|
+
const snapshot = JSON.parse(await fs.readFile(snapshotFor(this.#agentDir), "utf8")) as {
|
|
90
|
+
version?: number;
|
|
91
|
+
events?: SessionIndexEvent[];
|
|
92
|
+
indexSeq?: number;
|
|
93
|
+
};
|
|
94
|
+
assertSupportedStateVersion(snapshotFor(this.#agentDir), snapshot);
|
|
95
|
+
const snapshotIndexSeq = snapshot.indexSeq;
|
|
96
|
+
if (
|
|
97
|
+
typeof snapshotIndexSeq !== "number" ||
|
|
98
|
+
!Number.isSafeInteger(snapshotIndexSeq) ||
|
|
99
|
+
snapshotIndexSeq < 0 ||
|
|
100
|
+
!Array.isArray(snapshot.events) ||
|
|
101
|
+
snapshot.events.some(event => {
|
|
102
|
+
const { checksum, ...unsigned } = event;
|
|
103
|
+
return event.indexSeq > snapshotIndexSeq || checksum !== sessionIndexChecksum(unsigned);
|
|
104
|
+
})
|
|
105
|
+
)
|
|
106
|
+
throw new Error("invalid snapshot");
|
|
107
|
+
this.#events = snapshot.events;
|
|
108
|
+
snapshotSeq = snapshotIndexSeq;
|
|
109
|
+
} catch (e) {
|
|
110
|
+
if (e instanceof UnsupportedStateVersionError) throw e;
|
|
111
|
+
if ((e as NodeJS.ErrnoException).code !== "ENOENT") this.#warnings.push("Invalid session index snapshot");
|
|
112
|
+
}
|
|
113
|
+
await this.#tail(snapshotSeq);
|
|
114
|
+
}
|
|
115
|
+
async #tail(snapshotSeq = this.indexSeq): Promise<void> {
|
|
116
|
+
let data: Buffer;
|
|
117
|
+
try {
|
|
118
|
+
const handle = await fs.open(logFor(this.#agentDir), "r");
|
|
119
|
+
try {
|
|
120
|
+
const stat = await handle.stat();
|
|
121
|
+
if (stat.size < this.#logOffset) {
|
|
122
|
+
this.#warnings.push("Session index log was truncated");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
data = Buffer.alloc(stat.size - this.#logOffset);
|
|
126
|
+
if (data.length) await handle.read(data, 0, data.length, this.#logOffset);
|
|
127
|
+
} finally {
|
|
128
|
+
await handle.close();
|
|
129
|
+
}
|
|
130
|
+
} catch (e) {
|
|
131
|
+
if ((e as NodeJS.ErrnoException).code === "ENOENT") return;
|
|
132
|
+
throw e;
|
|
133
|
+
}
|
|
134
|
+
const lastNewline = data.lastIndexOf(0x0a);
|
|
135
|
+
if (lastNewline < 0) return;
|
|
136
|
+
const consumed = data.subarray(0, lastNewline + 1);
|
|
137
|
+
this.#logOffset += consumed.length;
|
|
138
|
+
for (const line of consumed.toString("utf8").split("\n")) {
|
|
139
|
+
if (!line) continue;
|
|
140
|
+
let event: SessionIndexEvent;
|
|
141
|
+
try {
|
|
142
|
+
event = JSON.parse(line) as SessionIndexEvent;
|
|
143
|
+
assertSupportedStateVersion(logFor(this.#agentDir), event);
|
|
144
|
+
} catch (error) {
|
|
145
|
+
if (error instanceof UnsupportedStateVersionError) throw error;
|
|
146
|
+
this.#warnings.push("Corrupt session index entry; replay truncated");
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (event.indexSeq <= snapshotSeq) continue;
|
|
150
|
+
const { checksum, ...unsigned } = event;
|
|
151
|
+
if (checksum !== sessionIndexChecksum(unsigned) || event.indexSeq !== this.indexSeq + 1) {
|
|
152
|
+
this.#warnings.push("Corrupt session index entry; replay truncated");
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
this.#events.push(event);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
async refresh(): Promise<void> {
|
|
159
|
+
await this.#tail();
|
|
160
|
+
}
|
|
161
|
+
get indexSeq(): number {
|
|
162
|
+
return this.#events.at(-1)?.indexSeq ?? 0;
|
|
163
|
+
}
|
|
164
|
+
async append(
|
|
165
|
+
input: Omit<SessionIndexEvent, "version" | "indexSeq" | "checksum" | "ts"> &
|
|
166
|
+
Partial<Pick<SessionIndexEvent, "ts">>,
|
|
167
|
+
): Promise<SessionIndexEvent> {
|
|
168
|
+
await fs.mkdir(dirFor(this.#agentDir), { recursive: true, mode: 0o700 });
|
|
169
|
+
return withFileLock(logFor(this.#agentDir), async () => {
|
|
170
|
+
await this.refresh();
|
|
171
|
+
const unsigned: Omit<SessionIndexEvent, "checksum"> = {
|
|
172
|
+
...input,
|
|
173
|
+
version: SDK_STATE_VERSION,
|
|
174
|
+
indexSeq: this.indexSeq + 1,
|
|
175
|
+
ts: input.ts ?? Date.now(),
|
|
176
|
+
};
|
|
177
|
+
const event: SessionIndexEvent = { ...unsigned, checksum: sessionIndexChecksum(unsigned) };
|
|
178
|
+
await appendSync(logFor(this.#agentDir), JSON.stringify(event));
|
|
179
|
+
await this.refresh();
|
|
180
|
+
return event;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
async snapshot(): Promise<void> {
|
|
184
|
+
const file = snapshotFor(this.#agentDir);
|
|
185
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
186
|
+
await fs.writeFile(
|
|
187
|
+
tmp,
|
|
188
|
+
JSON.stringify({ version: SDK_STATE_VERSION, indexSeq: this.indexSeq, events: this.#events }),
|
|
189
|
+
{ mode: 0o600 },
|
|
190
|
+
);
|
|
191
|
+
const h = await fs.open(tmp, "r");
|
|
192
|
+
try {
|
|
193
|
+
await h.sync();
|
|
194
|
+
} finally {
|
|
195
|
+
await h.close();
|
|
196
|
+
}
|
|
197
|
+
await fs.rename(tmp, file);
|
|
198
|
+
}
|
|
199
|
+
async assertSupportedStateVersions(): Promise<void> {
|
|
200
|
+
const files = [snapshotFor(this.#agentDir), logFor(this.#agentDir)];
|
|
201
|
+
for (const file of files) {
|
|
202
|
+
let source: string;
|
|
203
|
+
try {
|
|
204
|
+
source = await fs.readFile(file, "utf8");
|
|
205
|
+
} catch (error) {
|
|
206
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") continue;
|
|
207
|
+
throw error;
|
|
208
|
+
}
|
|
209
|
+
if (file.endsWith(".json")) {
|
|
210
|
+
assertSupportedStateVersion(file, JSON.parse(source));
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
for (const line of source.split("\n")) {
|
|
214
|
+
if (!line) continue;
|
|
215
|
+
try {
|
|
216
|
+
assertSupportedStateVersion(file, JSON.parse(line));
|
|
217
|
+
} catch (error) {
|
|
218
|
+
if (error instanceof UnsupportedStateVersionError) throw error;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
listSessions(): SessionList {
|
|
225
|
+
const latest = new Map<string, SessionIndexEvent>();
|
|
226
|
+
for (const event of this.#events) {
|
|
227
|
+
const previous = latest.get(event.sessionId);
|
|
228
|
+
latest.set(
|
|
229
|
+
event.sessionId,
|
|
230
|
+
event.type === "host_heartbeat" && previous
|
|
231
|
+
? {
|
|
232
|
+
...event,
|
|
233
|
+
locator: previous.locator,
|
|
234
|
+
endpointMtimeMs: previous.endpointMtimeMs,
|
|
235
|
+
lifecycleRequestId: previous.lifecycleRequestId,
|
|
236
|
+
}
|
|
237
|
+
: event,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
const sessions = [...latest.values()]
|
|
241
|
+
.filter(event => !["host_unregistered", "session_closed"].includes(event.type))
|
|
242
|
+
.map(event => ({
|
|
243
|
+
sessionId: event.sessionId,
|
|
244
|
+
locator: event.locator,
|
|
245
|
+
endpointGeneration: event.endpointGeneration,
|
|
246
|
+
pid: event.pid,
|
|
247
|
+
endpointMtimeMs: event.endpointMtimeMs,
|
|
248
|
+
lifecycleRequestId: event.lifecycleRequestId,
|
|
249
|
+
terminalUncertain: event.type === "lifecycle_terminal" || event.terminalUncertain === true,
|
|
250
|
+
indexSeq: event.indexSeq,
|
|
251
|
+
live: alive(event.pid),
|
|
252
|
+
}));
|
|
253
|
+
return { indexSeq: this.indexSeq, sessions, warnings: this.#warnings };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
hostUnregisteredAfter(
|
|
257
|
+
registration: Pick<
|
|
258
|
+
IndexedSession,
|
|
259
|
+
"sessionId" | "endpointGeneration" | "pid" | "indexSeq" | "lifecycleRequestId"
|
|
260
|
+
>,
|
|
261
|
+
): { indexSeq: number; lifecycleRequestId?: string } | undefined {
|
|
262
|
+
const lifecycleRequestId = registration.lifecycleRequestId;
|
|
263
|
+
const event = this.#events.findLast(
|
|
264
|
+
item =>
|
|
265
|
+
item.type === "host_unregistered" &&
|
|
266
|
+
item.indexSeq > registration.indexSeq &&
|
|
267
|
+
item.sessionId === registration.sessionId &&
|
|
268
|
+
item.endpointGeneration === registration.endpointGeneration &&
|
|
269
|
+
item.pid === registration.pid &&
|
|
270
|
+
(lifecycleRequestId === undefined || item.lifecycleRequestId === lifecycleRequestId),
|
|
271
|
+
);
|
|
272
|
+
return event
|
|
273
|
+
? {
|
|
274
|
+
indexSeq: event.indexSeq,
|
|
275
|
+
...(lifecycleRequestId ? { lifecycleRequestId } : {}),
|
|
276
|
+
}
|
|
277
|
+
: undefined;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
findHostRegistration(
|
|
281
|
+
sessionId: string,
|
|
282
|
+
endpointGeneration: number,
|
|
283
|
+
pid: number,
|
|
284
|
+
lifecycleRequestId?: string,
|
|
285
|
+
): IndexedSession | undefined {
|
|
286
|
+
const event = this.#events.findLast(
|
|
287
|
+
item =>
|
|
288
|
+
item.type === "host_registered" &&
|
|
289
|
+
item.sessionId === sessionId &&
|
|
290
|
+
item.endpointGeneration === endpointGeneration &&
|
|
291
|
+
item.pid === pid &&
|
|
292
|
+
(lifecycleRequestId === undefined || item.lifecycleRequestId === lifecycleRequestId),
|
|
293
|
+
);
|
|
294
|
+
return event
|
|
295
|
+
? {
|
|
296
|
+
sessionId: event.sessionId,
|
|
297
|
+
locator: event.locator,
|
|
298
|
+
endpointGeneration: event.endpointGeneration,
|
|
299
|
+
pid: event.pid,
|
|
300
|
+
endpointMtimeMs: event.endpointMtimeMs,
|
|
301
|
+
lifecycleRequestId: event.lifecycleRequestId,
|
|
302
|
+
terminalUncertain: false,
|
|
303
|
+
indexSeq: event.indexSeq,
|
|
304
|
+
live: alive(event.pid),
|
|
305
|
+
}
|
|
306
|
+
: undefined;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
hasHostRegistrationForLifecycle(sessionId: string, pid: number, lifecycleRequestId: string): boolean {
|
|
310
|
+
return this.#events.some(
|
|
311
|
+
event =>
|
|
312
|
+
event.type === "host_registered" &&
|
|
313
|
+
event.sessionId === sessionId &&
|
|
314
|
+
event.pid === pid &&
|
|
315
|
+
event.lifecycleRequestId === lifecycleRequestId,
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const SDK_STATE_VERSION = 1;
|
|
2
|
+
|
|
3
|
+
export class UnsupportedStateVersionError extends Error {
|
|
4
|
+
readonly code = "unsupported_state_version";
|
|
5
|
+
|
|
6
|
+
constructor(
|
|
7
|
+
readonly file: string,
|
|
8
|
+
readonly version: number,
|
|
9
|
+
) {
|
|
10
|
+
super(`Unsupported SDK state version ${version} in ${file}; maximum supported version is ${SDK_STATE_VERSION}.`);
|
|
11
|
+
this.name = "UnsupportedStateVersionError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function assertSupportedStateVersion(file: string, value: unknown): void {
|
|
16
|
+
if (!value || typeof value !== "object") return;
|
|
17
|
+
const record = value as { version?: unknown; stateVersion?: unknown };
|
|
18
|
+
for (const version of [record.version, record.stateVersion]) {
|
|
19
|
+
if (typeof version === "number" && Number.isFinite(version) && version > SDK_STATE_VERSION) {
|
|
20
|
+
throw new UnsupportedStateVersionError(file, version);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|