@gajae-code/coding-agent 0.13.3 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +184 -2
- package/README.md +2 -0
- package/bin/gajaessi.js +4 -0
- package/dist/types/async/job-manager.d.ts +55 -2
- package/dist/types/async/support.d.ts +14 -0
- package/dist/types/capability/mcp.d.ts +6 -0
- package/dist/types/capability/types.d.ts +6 -0
- package/dist/types/cli/accounts-cli.d.ts +19 -0
- package/dist/types/cli/args.d.ts +3 -0
- package/dist/types/cli/config-cli.d.ts +6 -0
- package/dist/types/cli/crash-cli.d.ts +10 -0
- package/dist/types/cli/customize-doctor.d.ts +145 -0
- package/dist/types/cli/daemon-cli.d.ts +3 -1
- package/dist/types/cli/mcp-cli.d.ts +11 -0
- package/dist/types/cli/notify-cli.d.ts +1 -1
- package/dist/types/cli/root-flags.d.ts +12 -0
- package/dist/types/cli/setup-cli.d.ts +3 -1
- package/dist/types/cli/skills-cli.d.ts +2 -1
- package/dist/types/cli/update-cli.d.ts +19 -1
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/commands/accounts.d.ts +40 -0
- package/dist/types/commands/crash.d.ts +24 -0
- package/dist/types/commands/customize.d.ts +22 -0
- package/dist/types/commands/daemon.d.ts +1 -1
- package/dist/types/commands/launch.d.ts +6 -0
- package/dist/types/commands/setup.d.ts +6 -0
- package/dist/types/commands/skills.d.ts +6 -1
- package/dist/types/commands/update.d.ts +7 -0
- package/dist/types/config/atomic-yaml-patch-worker.d.ts +25 -0
- package/dist/types/config/atomic-yaml-patch.d.ts +62 -2
- package/dist/types/config/config-schema-version.d.ts +10 -0
- package/dist/types/config/file-lock.d.ts +18 -0
- package/dist/types/config/model-profile-activation.d.ts +3 -1
- package/dist/types/config/model-registry.d.ts +9 -1
- package/dist/types/config/models-config-schema.d.ts +2 -0
- package/dist/types/config/settings-schema.d.ts +70 -6
- package/dist/types/config/settings.d.ts +63 -0
- package/dist/types/config/skill-settings-defaults.d.ts +26 -0
- package/dist/types/config/task-delegation.d.ts +39 -0
- package/dist/types/config/update-channel.d.ts +10 -0
- package/dist/types/coordinator-mcp/server.d.ts +5 -1
- package/dist/types/crash/index-store.d.ts +87 -0
- package/dist/types/crash/nudge.d.ts +50 -0
- package/dist/types/crash/record-loader.d.ts +17 -0
- package/dist/types/crash/report.d.ts +134 -0
- package/dist/types/crash/sanitize.d.ts +25 -0
- package/dist/types/cursor.d.ts +13 -2
- package/dist/types/customization/import.d.ts +37 -0
- package/dist/types/customization/index.d.ts +4 -0
- package/dist/types/customization/inventory.d.ts +25 -0
- package/dist/types/customization/mutations.d.ts +32 -0
- package/dist/types/customization/types.d.ts +115 -0
- package/dist/types/daemon/control-types.d.ts +8 -1
- package/dist/types/daemon/operator-contract.d.ts +4 -4
- package/dist/types/discovery/claude.d.ts +39 -1
- package/dist/types/discovery/codex.d.ts +39 -1
- package/dist/types/discovery/index.d.ts +2 -0
- package/dist/types/discovery/mcp-compat.d.ts +30 -0
- package/dist/types/edit/renderer.d.ts +23 -0
- package/dist/types/extensibility/extensions/runner.d.ts +3 -0
- package/dist/types/extensibility/extensions/types.d.ts +21 -4
- package/dist/types/extensibility/gjc-plugins/observability.d.ts +6 -1
- package/dist/types/extensibility/gjc-plugins/registry.d.ts +8 -1
- package/dist/types/extensibility/hooks/loader.d.ts +19 -5
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +22 -1
- package/dist/types/extensibility/skill-management.d.ts +107 -0
- package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +3 -1
- package/dist/types/gjc-runtime/launch-worktree.d.ts +8 -0
- package/dist/types/gjc-runtime/linux-proc.d.ts +3 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +10 -6
- package/dist/types/gjc-runtime/session-state-lock.d.ts +104 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +120 -2
- package/dist/types/gjc-runtime/state-writer.d.ts +10 -1
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +4 -2
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -6
- package/dist/types/gjc-runtime/workflow-settings.d.ts +109 -0
- package/dist/types/hooks/events.d.ts +60 -0
- package/dist/types/hooks/normalize.d.ts +83 -0
- package/dist/types/hooks/skill-state.d.ts +9 -2
- package/dist/types/main.d.ts +1 -1
- package/dist/types/modes/acp/abort-scope.d.ts +13 -0
- package/dist/types/modes/acp/acp-agent.d.ts +7 -4
- package/dist/types/modes/components/customization/customization-dashboard.d.ts +44 -0
- package/dist/types/modes/components/customization/import-wizard.d.ts +21 -0
- package/dist/types/modes/components/customization/index.d.ts +1 -0
- package/dist/types/modes/components/gajae-pet-widget.d.ts +8 -30
- package/dist/types/modes/components/irc-sidebar.d.ts +1 -0
- package/dist/types/modes/components/iterm-pet-transport.d.ts +122 -0
- package/dist/types/modes/components/oauth-selector.d.ts +10 -4
- package/dist/types/modes/components/pet-capability.d.ts +11 -25
- package/dist/types/modes/components/status-line/gh.d.ts +6 -2
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +7 -8
- package/dist/types/modes/controllers/stt-controller.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/modes/utils/injected-user-submission.d.ts +10 -0
- package/dist/types/runtime-mcp/config.d.ts +9 -0
- package/dist/types/runtime-mcp/manager.d.ts +26 -1
- package/dist/types/runtime-mcp/oauth-discovery.d.ts +4 -0
- package/dist/types/runtime-mcp/oauth-flow.d.ts +24 -1
- package/dist/types/runtime-mcp/pool-key.d.ts +2 -0
- package/dist/types/runtime-mcp/protocol.d.ts +278 -0
- package/dist/types/runtime-mcp/scope-config.d.ts +29 -0
- package/dist/types/runtime-mcp/tool-bridge.d.ts +15 -13
- package/dist/types/runtime-mcp/transports/http.d.ts +9 -0
- package/dist/types/runtime-mcp/types.d.ts +102 -10
- package/dist/types/sdk/acp/adapter.d.ts +26 -5
- package/dist/types/sdk/broker/broker.d.ts +3 -55
- package/dist/types/sdk/broker/lifecycle.d.ts +18 -12
- package/dist/types/sdk/broker/session-index.d.ts +14 -5
- package/dist/types/sdk/broker/startup-failure.d.ts +16 -1
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +51 -1
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -41
- package/dist/types/sdk/bus/config.d.ts +11 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +0 -1
- package/dist/types/sdk/bus/daemon-paths.d.ts +6 -0
- package/dist/types/sdk/bus/discord-conversation.d.ts +2 -0
- package/dist/types/sdk/bus/discord-daemon.d.ts +17 -12
- package/dist/types/sdk/bus/existing-thread-readiness.d.ts +4 -34
- package/dist/types/sdk/bus/inbound-reaction-ordering.d.ts +61 -0
- package/dist/types/sdk/bus/index.d.ts +85 -99
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +29 -7
- package/dist/types/sdk/bus/managed-daemon.d.ts +2 -32
- package/dist/types/sdk/bus/notification-service.d.ts +52 -0
- package/dist/types/sdk/bus/operator-runtime.d.ts +1 -1
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +16 -5
- package/dist/types/sdk/bus/reconciliation-store.d.ts +113 -5
- package/dist/types/sdk/bus/session-control.d.ts +25 -1
- package/dist/types/sdk/bus/slack-conversation.d.ts +4 -0
- package/dist/types/sdk/bus/slack-daemon.d.ts +9 -17
- package/dist/types/sdk/bus/slack-live-provider.d.ts +3 -1
- package/dist/types/sdk/bus/slack-provider.d.ts +4 -0
- package/dist/types/sdk/bus/slack-thread-binding.d.ts +6 -40
- package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +30 -104
- package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +10 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +262 -19
- package/dist/types/sdk/bus/telegram-daemon-orphan-reap.d.ts +125 -0
- package/dist/types/sdk/bus/telegram-daemon-owner-registry.d.ts +22 -0
- package/dist/types/sdk/bus/telegram-daemon.d.ts +119 -310
- package/dist/types/sdk/bus/telegram-reference.d.ts +1 -47
- package/dist/types/sdk/bus/threaded-render.d.ts +1 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +33 -17
- package/dist/types/sdk/cli/rows.d.ts +2 -11
- package/dist/types/sdk/cli/session-cli.d.ts +15 -25
- package/dist/types/sdk/client/client.d.ts +97 -1
- package/dist/types/sdk/host/control/dispatch.d.ts +0 -7
- package/dist/types/sdk/host/control/index.d.ts +1 -1
- package/dist/types/sdk/host/control/operations.d.ts +18 -5
- package/dist/types/sdk/host/control/runtime-gate.d.ts +19 -0
- package/dist/types/sdk/host/host.d.ts +15 -1
- package/dist/types/sdk/host/query/handlers.d.ts +5 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
- package/dist/types/sdk/host/session-runtime.d.ts +127 -7
- package/dist/types/sdk/host/types.d.ts +1 -1
- package/dist/types/sdk/host/websocket-transport.d.ts +1 -1
- package/dist/types/sdk/index.d.ts +2 -1
- package/dist/types/sdk/lifecycle/broker-client.d.ts +8 -0
- package/dist/types/sdk/lifecycle/client.d.ts +59 -0
- package/dist/types/sdk/lifecycle/index.d.ts +3 -0
- package/dist/types/sdk/lifecycle/service.d.ts +232 -0
- package/dist/types/sdk/mcp/server.d.ts +9 -6
- package/dist/types/sdk/prompt-deadline-lease.d.ts +43 -0
- package/dist/types/sdk/prompt-deadline-manager.d.ts +28 -0
- package/dist/types/sdk/prompt-status.d.ts +10 -3
- package/dist/types/sdk/protocol/operation-registry.d.ts +5 -0
- package/dist/types/sdk/receipt-state.d.ts +17 -0
- package/dist/types/sdk/reconciliation-extensions.d.ts +2 -0
- package/dist/types/sdk/router/index.d.ts +1 -0
- package/dist/types/sdk/router/session-router.d.ts +152 -0
- package/dist/types/sdk/session-list.d.ts +22 -0
- package/dist/types/sdk/session-reconnect.d.ts +43 -1
- package/dist/types/sdk/session.d.ts +34 -1
- package/dist/types/sdk/transport/serve-cli.d.ts +1 -4
- package/dist/types/session/account-inventory.d.ts +86 -0
- package/dist/types/session/agent-session.d.ts +145 -6
- package/dist/types/session/agent-storage.d.ts +10 -0
- package/dist/types/session/coordinator-tool-label.d.ts +28 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +23 -4
- package/dist/types/session/messages.d.ts +1 -1
- package/dist/types/session/secure-token-file.d.ts +3 -0
- package/dist/types/session/session-manager.d.ts +40 -1
- package/dist/types/session/startup-auth-config.d.ts +44 -0
- package/dist/types/session/terminal-abort.d.ts +378 -0
- package/dist/types/session/yield-queue.d.ts +7 -0
- package/dist/types/session-import/claude.d.ts +26 -0
- package/dist/types/session-import/codex.d.ts +88 -0
- package/dist/types/session-import/command.d.ts +35 -0
- package/dist/types/session-import/detect.d.ts +22 -0
- package/dist/types/session-import/index.d.ts +7 -0
- package/dist/types/session-import/provider-codex.d.ts +22 -0
- package/dist/types/session-import/provider-service.d.ts +38 -0
- package/dist/types/session-import/redact.d.ts +23 -0
- package/dist/types/session-import/service.d.ts +47 -0
- package/dist/types/session-import/types.d.ts +120 -0
- package/dist/types/setup/paseo/check.d.ts +16 -0
- package/dist/types/setup/paseo/install-saga.d.ts +115 -0
- package/dist/types/setup/paseo/json-publisher.d.ts +76 -0
- package/dist/types/setup/paseo/orchestration-preferences.d.ts +24 -0
- package/dist/types/setup/paseo/paseo-ownership.d.ts +87 -0
- package/dist/types/setup/paseo/paseo-setup.d.ts +29 -0
- package/dist/types/setup/paseo/provider-config.d.ts +35 -0
- package/dist/types/setup/paseo/remove.d.ts +14 -0
- package/dist/types/setup/paseo/result-types.d.ts +59 -0
- package/dist/types/setup/paseo/setup-deps.d.ts +73 -0
- package/dist/types/setup/paseo/skills-bridge.d.ts +44 -0
- package/dist/types/skill-state/active-state.d.ts +5 -1
- package/dist/types/slash-commands/acp-builtins.d.ts +5 -1
- package/dist/types/slash-commands/builtin-registry.d.ts +2 -0
- package/dist/types/slash-commands/helpers/credential-switch.d.ts +12 -0
- package/dist/types/slash-commands/helpers/usage-report.d.ts +5 -6
- package/dist/types/slash-commands/types.d.ts +7 -1
- package/dist/types/task/executor.d.ts +10 -0
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/tools/ask-answer-registry.d.ts +6 -3
- package/dist/types/tools/bash-sleep-advisory.d.ts +14 -0
- package/dist/types/tools/bash.d.ts +2 -6
- package/dist/types/tools/browser/attach.d.ts +11 -0
- package/dist/types/tools/browser/launch.d.ts +20 -0
- package/dist/types/tools/browser/profile-discovery.d.ts +6 -0
- package/dist/types/tools/browser/render.d.ts +1 -0
- package/dist/types/tools/browser.d.ts +3 -1
- package/dist/types/tools/image-gen.d.ts +9 -2
- package/dist/types/tools/index.d.ts +8 -0
- package/dist/types/tools/monitor.d.ts +1 -1
- package/dist/types/tools/skill-discovery.d.ts +8 -1
- package/dist/types/tools/subagent.d.ts +2 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +2 -2
- package/dist/types/utils/herdr-pane.d.ts +76 -0
- package/package.json +19 -9
- package/scripts/build-binary.ts +2 -1
- package/scripts/build-sdk-package-smoke.ts +2 -13
- package/scripts/capture-sticky-viewport-showcase.ts +0 -1
- package/scripts/compile-args.ts +2 -0
- package/scripts/generate-sdk-adapter-parity-manifest.ts +31 -16
- package/scripts/generate-sdk-operation-inventory.ts +28 -0
- package/scripts/generate-telegram-baseline-manifest.ts +1 -0
- package/scripts/generate-tool-catalog.ts +6 -4
- package/scripts/verify-gjc-sdk-canonicalization.ts +5 -39
- package/src/async/job-manager.ts +352 -17
- package/src/async/support.ts +25 -0
- package/src/autoresearch/dashboard.ts +28 -13
- package/src/capability/index.ts +3 -1
- package/src/capability/mcp.ts +6 -0
- package/src/capability/types.ts +6 -0
- package/src/cli/accounts-cli.ts +395 -0
- package/src/cli/args.ts +23 -0
- package/src/cli/auth-broker-cli.ts +136 -66
- package/src/cli/auth-gateway-cli.ts +94 -70
- package/src/cli/config-cli.ts +27 -2
- package/src/cli/crash-cli.ts +78 -0
- package/src/cli/customize-doctor.ts +1605 -0
- package/src/cli/daemon-cli.ts +12 -3
- package/src/cli/fast-help.ts +1 -0
- package/src/cli/mcp-cli.ts +128 -60
- package/src/cli/notify-cli.ts +8 -14
- package/src/cli/root-flags.ts +8 -0
- package/src/cli/setup-cli.ts +145 -0
- package/src/cli/skills-cli.ts +38 -2
- package/src/cli/update-cli.ts +167 -12
- package/src/cli.ts +4 -0
- package/src/commands/accounts.ts +71 -0
- package/src/commands/crash.ts +35 -0
- package/src/commands/customize.ts +84 -0
- package/src/commands/daemon.ts +2 -2
- package/src/commands/deep-interview.ts +2 -0
- package/src/commands/launch.ts +1 -0
- package/src/commands/mcp.ts +12 -7
- package/src/commands/ralplan.ts +2 -0
- package/src/commands/sdk.ts +65 -32
- package/src/commands/setup.ts +5 -0
- package/src/commands/skills.ts +14 -4
- package/src/commands/ultragoal.ts +10 -1
- package/src/commands/update.ts +26 -15
- package/src/config/atomic-yaml-patch-worker.ts +57 -0
- package/src/config/atomic-yaml-patch.ts +769 -29
- package/src/config/config-schema-version.ts +10 -0
- package/src/config/file-lock.ts +70 -1
- package/src/config/mcp-schema.json +52 -14
- package/src/config/model-profile-activation.ts +20 -1
- package/src/config/model-profiles.ts +29 -19
- package/src/config/model-registry.ts +132 -21
- package/src/config/models-config-schema.ts +1 -1
- package/src/config/settings-schema.ts +76 -6
- package/src/config/settings.ts +4038 -199
- package/src/config/skill-settings-defaults.ts +41 -3
- package/src/config/task-delegation.ts +87 -0
- package/src/config/update-channel.ts +23 -0
- package/src/coordinator-mcp/server.ts +377 -308
- package/src/crash/index-store.ts +723 -0
- package/src/crash/nudge.ts +89 -0
- package/src/crash/record-loader.ts +149 -0
- package/src/crash/report.ts +551 -0
- package/src/crash/sanitize.ts +129 -0
- package/src/cursor.ts +36 -10
- package/src/customization/import.ts +946 -0
- package/src/customization/index.ts +4 -0
- package/src/customization/inventory.ts +335 -0
- package/src/customization/mutations.ts +141 -0
- package/src/customization/types.ts +223 -0
- package/src/daemon/control-types.ts +8 -1
- package/src/daemon/operator-contract.ts +6 -6
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +11 -22
- package/src/defaults/gjc/skills/ralplan/SKILL.md +36 -23
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +16 -0
- package/src/discovery/claude-hooks.ts +38 -0
- package/src/discovery/claude.ts +142 -209
- package/src/discovery/codex-hooks.ts +38 -0
- package/src/discovery/codex.ts +132 -198
- package/src/discovery/helpers.ts +8 -1
- package/src/discovery/index.ts +2 -0
- package/src/discovery/mcp-compat.ts +234 -0
- package/src/discovery/mcp-json.ts +6 -0
- package/src/edit/renderer.ts +40 -0
- package/src/edit/streaming.ts +4 -2
- package/src/exec/bash-executor.ts +24 -20
- package/src/export/html/index.ts +51 -2
- package/src/extensibility/extensions/loader.ts +9 -1
- package/src/extensibility/extensions/runner.ts +17 -4
- package/src/extensibility/extensions/types.ts +31 -6
- package/src/extensibility/gjc-plugins/constrained-hooks.ts +33 -0
- package/src/extensibility/gjc-plugins/installer.ts +9 -5
- package/src/extensibility/gjc-plugins/observability.ts +8 -2
- package/src/extensibility/gjc-plugins/registry.ts +13 -2
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +3 -1
- package/src/extensibility/gjc-plugins/schema.ts +222 -39
- package/src/extensibility/hooks/loader.ts +154 -10
- package/src/extensibility/runtime-skill-discovery.ts +257 -60
- package/src/extensibility/skill-management.ts +368 -0
- package/src/extensibility/skills.ts +52 -16
- package/src/gjc-runtime/deep-interview-runtime.ts +45 -61
- package/src/gjc-runtime/launch-worktree.ts +56 -2
- package/src/gjc-runtime/linux-proc.ts +7 -1
- package/src/gjc-runtime/ralplan-runtime.ts +100 -164
- package/src/gjc-runtime/session-state-lock.ts +992 -0
- package/src/gjc-runtime/session-state-sidecar.ts +644 -142
- package/src/gjc-runtime/state-writer.ts +39 -14
- package/src/gjc-runtime/tmux-owner-isolation.ts +5 -4
- package/src/gjc-runtime/ultragoal-guard.ts +11 -4
- package/src/gjc-runtime/ultragoal-runtime.ts +44 -41
- package/src/gjc-runtime/workflow-settings.ts +596 -0
- package/src/goals/tools/goal-tool.ts +6 -1
- package/src/hooks/events.ts +291 -0
- package/src/hooks/native-skill-hook.ts +4 -0
- package/src/hooks/normalize.ts +369 -0
- package/src/hooks/skill-state.ts +165 -46
- package/src/internal-urls/docs-index.generated.ts +40 -32
- package/src/main.ts +32 -5
- package/src/migrate/mcp-mapper.ts +25 -2
- package/src/modes/acp/abort-scope.ts +29 -0
- package/src/modes/acp/acp-agent.ts +423 -98
- package/src/modes/components/assistant-message.ts +6 -1
- package/src/modes/components/customization/customization-dashboard.ts +443 -0
- package/src/modes/components/customization/import-wizard.ts +372 -0
- package/src/modes/components/customization/index.ts +1 -0
- package/src/modes/components/gajae-pet-widget.ts +539 -213
- package/src/modes/components/irc-sidebar.ts +11 -0
- package/src/modes/components/iterm-pet-transport.ts +585 -0
- package/src/modes/components/oauth-selector.ts +277 -86
- package/src/modes/components/pet-capability.ts +39 -40
- package/src/modes/components/settings-selector.ts +9 -0
- package/src/modes/components/status-line/gh.ts +45 -1
- package/src/modes/components/status-line/segments.ts +16 -1
- package/src/modes/components/tool-status-header.ts +13 -3
- package/src/modes/controllers/command-controller.ts +20 -8
- package/src/modes/controllers/extension-ui-controller.ts +56 -257
- package/src/modes/controllers/input-controller.ts +10 -0
- package/src/modes/controllers/runtime-mcp-command-controller.ts +16 -3
- package/src/modes/controllers/selector-controller.ts +177 -72
- package/src/modes/controllers/stt-controller.ts +3 -3
- package/src/modes/interactive-mode.ts +88 -16
- package/src/modes/print-mode.ts +35 -6
- package/src/modes/runtime-init.ts +21 -68
- package/src/modes/types.ts +1 -0
- package/src/modes/utils/injected-user-submission.ts +25 -0
- package/src/modes/utils/terminal-bell.ts +15 -1
- package/src/prompts/agent-fragments/ralplan-persistence.md +1 -1
- package/src/prompts/agent-fragments/restricted-bash.md +1 -1
- package/src/prompts/agents/critic.md +1 -1
- package/src/prompts/system/rlm-research.md +1 -1
- package/src/prompts/system/system-prompt.md +0 -2
- package/src/prompts/tools/bash.md +7 -1
- package/src/prompts/tools/browser.md +1 -1
- package/src/prompts/tools/cron.md +6 -6
- package/src/prompts/tools/read.md +0 -2
- package/src/prompts/tools/skill-discovery.md +4 -2
- package/src/runtime-mcp/client.ts +427 -23
- package/src/runtime-mcp/config.ts +37 -5
- package/src/runtime-mcp/manager-pool.test.ts +56 -0
- package/src/runtime-mcp/manager.ts +52 -2
- package/src/runtime-mcp/oauth-discovery.ts +13 -0
- package/src/runtime-mcp/oauth-flow.ts +46 -1
- package/src/runtime-mcp/pool-key.ts +5 -1
- package/src/runtime-mcp/pool.test.ts +9 -0
- package/src/runtime-mcp/protocol.test.ts +353 -0
- package/src/runtime-mcp/protocol.ts +624 -0
- package/src/runtime-mcp/scope-config.ts +78 -0
- package/src/runtime-mcp/tool-bridge.ts +44 -10
- package/src/runtime-mcp/transports/http.ts +84 -13
- package/src/runtime-mcp/types.ts +123 -12
- package/src/sdk/acp/adapter.ts +328 -97
- package/src/sdk/broker/broker.ts +160 -741
- package/src/sdk/broker/ensure.ts +9 -1
- package/src/sdk/broker/lifecycle.ts +510 -116
- package/src/sdk/broker/operation-receipt-ledger.ts +11 -2
- package/src/sdk/broker/process-incarnation.ts +19 -0
- package/src/sdk/broker/session-index.ts +516 -117
- package/src/sdk/broker/startup-failure.ts +28 -5
- package/src/sdk/broker/transport.ts +1 -13
- package/src/sdk/bus/chat-daemon-cli.ts +4 -2
- package/src/sdk/bus/chat-daemon-control.ts +67 -6
- package/src/sdk/bus/chat-daemon-runtime.ts +183 -859
- package/src/sdk/bus/config.ts +13 -0
- package/src/sdk/bus/conversation-store.ts +59 -171
- package/src/sdk/bus/daemon-paths.ts +20 -0
- package/src/sdk/bus/discord-conversation.ts +2 -0
- package/src/sdk/bus/discord-daemon.ts +524 -126
- package/src/sdk/bus/discord-live-provider.ts +206 -79
- package/src/sdk/bus/existing-thread-readiness.ts +4 -97
- package/src/sdk/bus/inbound-reaction-ordering.ts +122 -0
- package/src/sdk/bus/index.ts +2480 -456
- package/src/sdk/bus/kind-aware-reconciliation.ts +204 -34
- package/src/sdk/bus/lifecycle-commands.ts +2 -2
- package/src/sdk/bus/managed-daemon.ts +2 -145
- package/src/sdk/bus/notification-service.ts +196 -0
- package/src/sdk/bus/operator-runtime.ts +1 -1
- package/src/sdk/bus/prompt-reconciliation.ts +24 -15
- package/src/sdk/bus/reconciliation-store.ts +553 -24
- package/src/sdk/bus/session-control.ts +49 -3
- package/src/sdk/bus/slack-conversation.ts +4 -0
- package/src/sdk/bus/slack-daemon.ts +733 -134
- package/src/sdk/bus/slack-live-provider.ts +65 -15
- package/src/sdk/bus/slack-provider.ts +4 -0
- package/src/sdk/bus/slack-thread-binding.ts +9 -104
- package/src/sdk/bus/telegram-adoption-intent.ts +299 -209
- package/src/sdk/bus/telegram-daemon-cli.ts +194 -7
- package/src/sdk/bus/telegram-daemon-contract.ts +265 -19
- package/src/sdk/bus/telegram-daemon-control.ts +3 -13
- package/src/sdk/bus/telegram-daemon-orphan-reap.ts +498 -0
- package/src/sdk/bus/telegram-daemon-owner-registry.ts +176 -0
- package/src/sdk/bus/telegram-daemon.ts +2552 -2280
- package/src/sdk/bus/telegram-reference.ts +1 -226
- package/src/sdk/bus/telegram-setup.ts +2 -2
- package/src/sdk/bus/threaded-render.ts +1 -0
- package/src/sdk/bus/topic-registry.ts +279 -146
- package/src/sdk/cli/rows.ts +2 -35
- package/src/sdk/cli/session-cli.ts +776 -700
- package/src/sdk/client/client.ts +892 -1
- package/src/sdk/host/control/dispatch.ts +93 -58
- package/src/sdk/host/control/index.ts +1 -1
- package/src/sdk/host/control/operations.ts +18 -10
- package/src/sdk/host/control/runtime-gate.ts +40 -0
- package/src/sdk/host/host.ts +63 -12
- package/src/sdk/host/query/handlers.ts +66 -7
- package/src/sdk/host/reverse-leases.ts +2 -2
- package/src/sdk/host/sdk-surface-parity.test.ts +1 -1
- package/src/sdk/host/session-runtime.test.ts +2787 -34
- package/src/sdk/host/session-runtime.ts +1489 -101
- package/src/sdk/host/surface-policy.ts +12 -8
- package/src/sdk/host/types.ts +1 -1
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +31 -59
- package/src/sdk/host/websocket-transport.ts +85 -50
- package/src/sdk/index.ts +2 -1
- package/src/sdk/lifecycle/broker-client.ts +53 -0
- package/src/sdk/lifecycle/client.ts +234 -0
- package/src/sdk/lifecycle/index.ts +3 -0
- package/src/sdk/{bus/recent-activity.ts → lifecycle/recent-sessions.ts} +5 -2
- package/src/sdk/lifecycle/service.ts +720 -0
- package/src/sdk/mcp/server.ts +226 -188
- package/src/sdk/prompt-deadline-lease.ts +55 -0
- package/src/sdk/prompt-deadline-manager.ts +148 -0
- package/src/sdk/prompt-status.ts +11 -3
- package/src/sdk/protocol/operation-inventory.generated.json +272 -129
- package/src/sdk/protocol/operation-registry.ts +71 -8
- package/src/sdk/receipt-state.ts +43 -0
- package/src/sdk/reconciliation-extensions.ts +14 -0
- package/src/sdk/router/index.ts +1 -0
- package/src/sdk/router/session-router.ts +1658 -0
- package/src/sdk/session-list.ts +93 -0
- package/src/sdk/session-reconnect.ts +45 -1
- package/src/sdk/session.ts +716 -120
- package/src/sdk/transport/serve-cli.ts +18 -34
- package/src/session/account-inventory.ts +603 -0
- package/src/session/agent-session.ts +2857 -582
- package/src/session/agent-storage.ts +35 -0
- package/src/session/blob-store.ts +32 -1
- package/src/session/coordinator-tool-label.ts +40 -0
- package/src/session/internal/managed-session-scope.ts +4 -0
- package/src/session/internal/managed-session-storage.ts +173 -12
- package/src/session/messages.ts +1 -1
- package/src/session/secure-token-file.ts +80 -0
- package/src/session/session-manager.ts +730 -58
- package/src/session/session-storage.ts +25 -16
- package/src/session/startup-auth-config.ts +297 -0
- package/src/session/terminal-abort.ts +1253 -0
- package/src/session/yield-queue.ts +57 -15
- package/src/session-import/claude.ts +334 -0
- package/src/session-import/codex.ts +1033 -0
- package/src/session-import/command.ts +77 -0
- package/src/session-import/detect.ts +133 -0
- package/src/session-import/index.ts +7 -0
- package/src/session-import/provider-codex.ts +327 -0
- package/src/session-import/provider-service.ts +457 -0
- package/src/session-import/redact.ts +128 -0
- package/src/session-import/service.ts +1264 -0
- package/src/session-import/types.ts +148 -0
- package/src/setup/paseo/check.ts +213 -0
- package/src/setup/paseo/install-saga.ts +293 -0
- package/src/setup/paseo/json-publisher.ts +263 -0
- package/src/setup/paseo/orchestration-preferences.ts +86 -0
- package/src/setup/paseo/paseo-ownership.ts +224 -0
- package/src/setup/paseo/paseo-setup.ts +253 -0
- package/src/setup/paseo/provider-config.ts +139 -0
- package/src/setup/paseo/remove.ts +183 -0
- package/src/setup/paseo/result-types.ts +79 -0
- package/src/setup/paseo/setup-deps.ts +175 -0
- package/src/setup/paseo/skills-bridge.ts +260 -0
- package/src/skill-state/active-state.ts +21 -11
- package/src/slash-commands/acp-builtins.ts +9 -1
- package/src/slash-commands/builtin-registry.ts +98 -16
- package/src/slash-commands/helpers/credential-switch.ts +143 -0
- package/src/slash-commands/helpers/mcp.ts +9 -3
- package/src/slash-commands/helpers/usage-report.ts +61 -56
- package/src/slash-commands/types.ts +7 -2
- package/src/task/executor.ts +30 -11
- package/src/task/index.ts +66 -7
- package/src/task/render.ts +23 -9
- package/src/tools/ask-answer-registry.ts +23 -7
- package/src/tools/ask.ts +8 -4
- package/src/tools/bash-sleep-advisory.ts +115 -0
- package/src/tools/bash.ts +98 -18
- package/src/tools/browser/attach.ts +71 -3
- package/src/tools/browser/launch.ts +86 -13
- package/src/tools/browser/profile-discovery.ts +57 -7
- package/src/tools/browser/render.ts +8 -1
- package/src/tools/browser.ts +130 -21
- package/src/tools/computer.enforcement.test.ts +1 -1
- package/src/tools/computer.ts +3 -2
- package/src/tools/cron.ts +12 -1
- package/src/tools/image-gen.ts +27 -16
- package/src/tools/index.ts +8 -0
- package/src/tools/job.ts +33 -6
- package/src/tools/monitor.ts +41 -2
- package/src/tools/skill-discovery.ts +21 -29
- package/src/tools/subagent.ts +142 -24
- package/src/tools/tool-catalog.generated.ts +6 -6
- package/src/tools/ultragoal-ask-guard.ts +10 -3
- package/src/utils/herdr-pane.ts +345 -0
- package/src/utils/title-generator.ts +2 -0
- package/src/web/scrapers/index.ts +6 -4
- package/dist/types/cli/malloc-env-guard.test.d.ts +0 -1
- package/dist/types/defaults/gjc-defaults.test.d.ts +0 -1
- package/dist/types/memory-backend/lazy-loading.test.d.ts +0 -1
- package/dist/types/runtime/boot-ordering.test.d.ts +0 -1
- package/dist/types/runtime/lazy-service.test.d.ts +0 -1
- package/dist/types/runtime/network-prewarm-service.test.d.ts +0 -1
- package/dist/types/runtime/workspace-tree-service.test.d.ts +0 -1
- package/dist/types/runtime-mcp/config.test.d.ts +0 -1
- package/dist/types/runtime-mcp/http.test.d.ts +0 -1
- package/dist/types/runtime-mcp/manager-pool.test.d.ts +0 -1
- package/dist/types/runtime-mcp/pool-key.test.d.ts +0 -1
- package/dist/types/runtime-mcp/pool.test.d.ts +0 -1
- package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +0 -117
- package/dist/types/sdk/bus/lifecycle-orchestrator.d.ts +0 -141
- package/dist/types/sdk/bus/telegram-cli.d.ts +0 -31
- package/dist/types/sdk/elevation/allowlist.d.ts +0 -20
- package/dist/types/sdk/elevation/audit.d.ts +0 -93
- package/dist/types/sdk/elevation/capability.d.ts +0 -3
- package/dist/types/sdk/elevation/digest.d.ts +0 -72
- package/dist/types/sdk/elevation/dispatch-receipt.d.ts +0 -85
- package/dist/types/sdk/elevation/grant-ledger.d.ts +0 -163
- package/dist/types/sdk/elevation/owner.d.ts +0 -48
- package/dist/types/sdk/host/import-graph.test.d.ts +0 -1
- package/dist/types/sdk/host/sdk-surface-parity.test.d.ts +0 -1
- package/dist/types/sdk/host/session-runtime.test.d.ts +0 -1
- package/dist/types/sdk/host/websocket-transport.lifecycle.test.d.ts +0 -1
- package/dist/types/session/auth-broker-config.d.ts +0 -13
- package/dist/types/session/heap-eviction-artifacts.test.d.ts +0 -1
- package/dist/types/skills/skills.test.d.ts +0 -1
- package/dist/types/slash-commands/notify-command.test.d.ts +0 -1
- package/dist/types/task/token-log.test.d.ts +0 -1
- package/dist/types/tools/computer.enforcement.test.d.ts +0 -1
- package/dist/types/tools/descriptors.test.d.ts +0 -1
- package/scripts/g005-daemon-smoke.ts +0 -180
- package/scripts/g011-daemon-path-smoke.ts +0 -153
- package/src/sdk/bus/lifecycle-control-runtime.ts +0 -1733
- package/src/sdk/bus/lifecycle-orchestrator.ts +0 -489
- package/src/sdk/bus/telegram-cli.ts +0 -212
- package/src/sdk/elevation/allowlist.ts +0 -54
- package/src/sdk/elevation/audit.ts +0 -208
- package/src/sdk/elevation/capability.ts +0 -41
- package/src/sdk/elevation/digest.ts +0 -129
- package/src/sdk/elevation/dispatch-receipt.ts +0 -184
- package/src/sdk/elevation/grant-ledger.ts +0 -1142
- package/src/sdk/elevation/owner.ts +0 -109
- package/src/session/auth-broker-config.ts +0 -109
- /package/dist/types/{ai-core-import-gate.test.d.ts → discovery/claude-hooks.d.ts} +0 -0
- /package/dist/types/{cli/fixture-report.test.d.ts → discovery/codex-hooks.d.ts} +0 -0
- /package/dist/types/sdk/{bus/recent-activity.d.ts → lifecycle/recent-sessions.d.ts} +0 -0
|
@@ -30,6 +30,7 @@ interface MCPConfigFile {
|
|
|
30
30
|
enabled?: boolean;
|
|
31
31
|
autoload?: boolean;
|
|
32
32
|
sharing?: "per-session" | "shared";
|
|
33
|
+
protocol?: "auto" | "2026-07-28" | "legacy";
|
|
33
34
|
timeout?: number;
|
|
34
35
|
command?: string;
|
|
35
36
|
args?: string[];
|
|
@@ -104,6 +105,10 @@ function isValidExactServerConfig(value: unknown): boolean {
|
|
|
104
105
|
return (
|
|
105
106
|
isOptionalBoolean(value.enabled) &&
|
|
106
107
|
(value.sharing === undefined || value.sharing === "per-session" || value.sharing === "shared") &&
|
|
108
|
+
(value.protocol === undefined ||
|
|
109
|
+
value.protocol === "auto" ||
|
|
110
|
+
value.protocol === "2026-07-28" ||
|
|
111
|
+
value.protocol === "legacy") &&
|
|
107
112
|
isOptionalBoolean(value.autoload) &&
|
|
108
113
|
isOptionalBoolean(value.noInheritEnv) &&
|
|
109
114
|
(value.timeout === undefined ||
|
|
@@ -203,6 +208,7 @@ function transformMCPConfig(config: MCPConfigFile, source: SourceMeta, quiet = f
|
|
|
203
208
|
enabled,
|
|
204
209
|
autoload,
|
|
205
210
|
sharing: serverConfig.sharing,
|
|
211
|
+
protocol: serverConfig.protocol,
|
|
206
212
|
timeout,
|
|
207
213
|
command: serverConfig.command,
|
|
208
214
|
args: serverConfig.args,
|
package/src/edit/renderer.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Edit tool renderer and LSP batching helpers.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
5
6
|
import type { Component } from "@gajae-code/tui";
|
|
6
7
|
import { Text, visibleWidth, wrapTextWithAnsi } from "@gajae-code/tui";
|
|
7
8
|
import { sanitizeText } from "@gajae-code/utils";
|
|
@@ -85,6 +86,45 @@ export interface EditToolDetails {
|
|
|
85
86
|
newText?: string;
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Bounded durable identity of one edit snapshot (#4566).
|
|
91
|
+
*
|
|
92
|
+
* Live edit results carry full `oldText`/`newText` file bodies so in-process
|
|
93
|
+
* consumers (ACP `diff` ToolCallContent, editors) keep working. Every persisted
|
|
94
|
+
* transcript entry replaces those bodies with this fixed-size receipt: byte
|
|
95
|
+
* length plus SHA-256 content digest, enough to detect source drift and to
|
|
96
|
+
* account for the edit durably without re-writing the whole file per edit.
|
|
97
|
+
*/
|
|
98
|
+
export interface EditSnapshotReceipt {
|
|
99
|
+
/** UTF-8 byte length of the snapshot (`0` for create/delete-absent sides). */
|
|
100
|
+
bytes: number;
|
|
101
|
+
/** SHA-256 hex digest of the exact snapshot text (empty string for length 0). */
|
|
102
|
+
sha256: string;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Per-edit-mode cap on any single persisted edit-result string field (#4566). */
|
|
106
|
+
export const EDIT_PERSIST_FIELD_MAX_CHARS = 16 * 1024;
|
|
107
|
+
|
|
108
|
+
/** Fixed marker used when a snapshot receipt replaces a full body. */
|
|
109
|
+
export const EDIT_SNAPSHOT_EXTERNALIZED_NOTICE =
|
|
110
|
+
"[edit snapshot externalized: see oldTextDigest/newTextDigest; full body omitted from transcript]";
|
|
111
|
+
|
|
112
|
+
function sha256Hex(text: string): string {
|
|
113
|
+
if (text.length === 0) return "";
|
|
114
|
+
return createHash("sha256").update(Buffer.from(text, "utf-8")).digest("hex");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Build the bounded durable receipt for one snapshot body. */
|
|
118
|
+
export function editSnapshotReceipt(text: string | undefined): EditSnapshotReceipt | undefined {
|
|
119
|
+
if (text === undefined) return undefined;
|
|
120
|
+
return { bytes: Buffer.byteLength(text, "utf-8"), sha256: sha256Hex(text) };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** True when a snapshot body is small enough to persist inline without amplification. */
|
|
124
|
+
export function editSnapshotPersistableInline(text: string | undefined): boolean {
|
|
125
|
+
return text !== undefined && text.length <= EDIT_PERSIST_FIELD_MAX_CHARS;
|
|
126
|
+
}
|
|
127
|
+
|
|
88
128
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
89
129
|
// TUI Renderer
|
|
90
130
|
// ═══════════════════════════════════════════════════════════════════════════
|
package/src/edit/streaming.ts
CHANGED
|
@@ -82,7 +82,9 @@ export interface EditRequestTargetInventory {
|
|
|
82
82
|
/** First envelope entry rename target, for free-form modes that carry no structured `edits`. */
|
|
83
83
|
rename?: string;
|
|
84
84
|
}
|
|
85
|
-
|
|
85
|
+
function missingApplyPatchEndError(): string {
|
|
86
|
+
return `The last line of the patch must be '${END_PATCH_MARKER}'`;
|
|
87
|
+
}
|
|
86
88
|
|
|
87
89
|
export function orderedDistinctPaths(paths: readonly (string | undefined)[]): string[] {
|
|
88
90
|
const seen = new Set<string>();
|
|
@@ -181,7 +183,7 @@ export function getEditRequestTargetInventory(
|
|
|
181
183
|
} catch (err) {
|
|
182
184
|
const parseError = err instanceof Error ? err.message : String(err);
|
|
183
185
|
const inventory = applyPatchEntryInventory(expandApplyPatchToPreviewEntries({ input }));
|
|
184
|
-
if (options.isPartial && parseError ===
|
|
186
|
+
if (options.isPartial && parseError === missingApplyPatchEndError()) return inventory;
|
|
185
187
|
return { ...inventory, parseError };
|
|
186
188
|
}
|
|
187
189
|
}
|
|
@@ -184,7 +184,6 @@ export interface BashResult {
|
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
const shellSessions = new Map<string, Shell>();
|
|
187
|
-
const brokenShellSessions = new Set<string>();
|
|
188
187
|
const retiringShellSessions = new Set<Shell>();
|
|
189
188
|
// Cover pi-shell's normal cancellation kill waves without turning a stalled
|
|
190
189
|
// native cleanup into a multi-second JavaScript tool stall.
|
|
@@ -204,16 +203,18 @@ export function getShellSessionCount(): number {
|
|
|
204
203
|
*/
|
|
205
204
|
export async function disposeAllShellSessions(): Promise<void> {
|
|
206
205
|
// Snapshot and drop strong references up front so concurrent callers cannot
|
|
207
|
-
// reuse a session that is being torn down, then await every native
|
|
206
|
+
// reuse a session that is being torn down, then await every native close so
|
|
208
207
|
// shutdown/signal cleanup does not return before resources are released.
|
|
209
208
|
// Include retiring shells whose JS call returned after bounded abort cleanup
|
|
210
209
|
// while the native run is still unwinding; they are no longer reusable but
|
|
211
210
|
// remain owned until their run promise settles.
|
|
211
|
+
// `close` rather than `abort`: aborting only cancels in-flight commands and
|
|
212
|
+
// leaves a completed session retained for reuse, which keeps the native shell
|
|
213
|
+
// alive for the rest of the process lifetime.
|
|
212
214
|
const sessions = new Set([...shellSessions.values(), ...retiringShellSessions]);
|
|
213
215
|
shellSessions.clear();
|
|
214
216
|
retiringShellSessions.clear();
|
|
215
|
-
|
|
216
|
-
await Promise.allSettled([...sessions].map(session => session.abort()));
|
|
217
|
+
await Promise.allSettled([...sessions].map(session => session.close()));
|
|
217
218
|
}
|
|
218
219
|
|
|
219
220
|
postmortem.register("bash-executor:shell-sessions", () => disposeAllShellSessions());
|
|
@@ -292,10 +293,9 @@ export async function executeBash(command: string, options?: BashExecutorOptions
|
|
|
292
293
|
|
|
293
294
|
const usePersistentShell = options?.oneShot !== true;
|
|
294
295
|
const sessionKey = buildSessionKey(shell, configuredPrefix, snapshotPath, shellEnv, options?.sessionKey, minimizer);
|
|
295
|
-
const persistentSessionBroken = usePersistentShell && brokenShellSessions.has(sessionKey);
|
|
296
296
|
|
|
297
|
-
let shellSession =
|
|
298
|
-
if (!shellSession &&
|
|
297
|
+
let shellSession = usePersistentShell ? shellSessions.get(sessionKey) : undefined;
|
|
298
|
+
if (!shellSession && usePersistentShell) {
|
|
299
299
|
shellSession = new Shell({
|
|
300
300
|
sessionEnv: shellEnv,
|
|
301
301
|
snapshotPath: snapshotPath ?? undefined,
|
|
@@ -306,14 +306,13 @@ export async function executeBash(command: string, options?: BashExecutorOptions
|
|
|
306
306
|
// Non-persistent invocations still need an owned native Shell so its lifetime
|
|
307
307
|
// can be ended explicitly. executeShell creates a native shell outside the
|
|
308
308
|
// persistent registry, leaving its cleanup untrackable by the host process.
|
|
309
|
-
const oneShotShell =
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
: undefined;
|
|
309
|
+
const oneShotShell = !usePersistentShell
|
|
310
|
+
? new Shell({
|
|
311
|
+
sessionEnv: shellEnv,
|
|
312
|
+
snapshotPath: snapshotPath ?? undefined,
|
|
313
|
+
minimizer,
|
|
314
|
+
})
|
|
315
|
+
: undefined;
|
|
317
316
|
const activeShell = shellSession ?? oneShotShell;
|
|
318
317
|
const userSignal = options?.signal;
|
|
319
318
|
const runAbortController = new AbortController();
|
|
@@ -389,20 +388,23 @@ export async function executeBash(command: string, options?: BashExecutorOptions
|
|
|
389
388
|
if (shellSession) {
|
|
390
389
|
resetSession = true;
|
|
391
390
|
retiringShellSessions.add(shellSession);
|
|
392
|
-
|
|
393
|
-
|
|
391
|
+
if (shellSessions.get(sessionKey) === shellSession) {
|
|
392
|
+
shellSessions.delete(sessionKey);
|
|
393
|
+
}
|
|
394
394
|
runSettled = await awaitAbortCleanup(runPromise);
|
|
395
|
+
// A retired session is never reused, so release the native shell instead
|
|
396
|
+
// of leaving it retained for the rest of the process lifetime.
|
|
395
397
|
if (runSettled) {
|
|
396
|
-
brokenShellSessions.delete(sessionKey);
|
|
397
398
|
retiringShellSessions.delete(shellSession);
|
|
399
|
+
void shellSession.close().catch(() => undefined);
|
|
398
400
|
} else {
|
|
399
401
|
void runPromise
|
|
400
402
|
.finally(() => {
|
|
401
|
-
brokenShellSessions.delete(sessionKey);
|
|
402
403
|
retiringShellSessions.delete(shellSession);
|
|
403
404
|
if (shellSessions.get(sessionKey) === shellSession) {
|
|
404
405
|
shellSessions.delete(sessionKey);
|
|
405
406
|
}
|
|
407
|
+
void shellSession.close().catch(() => undefined);
|
|
406
408
|
})
|
|
407
409
|
.catch(() => undefined);
|
|
408
410
|
}
|
|
@@ -508,7 +510,9 @@ export async function executeBash(command: string, options?: BashExecutorOptions
|
|
|
508
510
|
shellSessions.delete(sessionKey);
|
|
509
511
|
}
|
|
510
512
|
if (oneShotShell) {
|
|
511
|
-
|
|
513
|
+
// Always close: a successful run keeps its session retained, so aborting
|
|
514
|
+
// alone would leak the native shell and hold the event loop open.
|
|
515
|
+
const disposePromise = (abortPromise ?? Promise.resolve()).then(() => oneShotShell.close());
|
|
512
516
|
await Promise.race([disposePromise.catch(() => undefined), Bun.sleep(CANCEL_CLEANUP_WAIT_MS)]);
|
|
513
517
|
}
|
|
514
518
|
}
|
package/src/export/html/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as syncFs from "node:fs";
|
|
1
2
|
import * as fs from "node:fs/promises";
|
|
2
3
|
import * as path from "node:path";
|
|
3
4
|
import type { AgentState } from "@gajae-code/agent-core";
|
|
@@ -162,6 +163,51 @@ async function assertExportDoesNotAliasSource(sourcePath: string, outputPath: st
|
|
|
162
163
|
throw new Error("HTML export output must not overwrite the source transcript");
|
|
163
164
|
}
|
|
164
165
|
|
|
166
|
+
const HTML_EXPORT_SOURCE_OPEN_FLAGS =
|
|
167
|
+
syncFs.constants.O_RDONLY |
|
|
168
|
+
syncFs.constants.O_NONBLOCK |
|
|
169
|
+
(process.platform === "win32" ? 0 : (syncFs.constants.O_NOFOLLOW ?? 0));
|
|
170
|
+
|
|
171
|
+
const HTML_EXPORT_DESTINATION_OPEN_FLAGS =
|
|
172
|
+
syncFs.constants.O_WRONLY |
|
|
173
|
+
syncFs.constants.O_CREAT |
|
|
174
|
+
(process.platform === "win32" ? 0 : (syncFs.constants.O_NOFOLLOW ?? 0));
|
|
175
|
+
|
|
176
|
+
function sameFileIdentity(left: syncFs.BigIntStats, right: syncFs.BigIntStats): boolean {
|
|
177
|
+
return left.dev === right.dev && left.ino === right.ino;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function openHtmlExportDescriptors(
|
|
181
|
+
sourcePath: string | undefined,
|
|
182
|
+
outputPath: string,
|
|
183
|
+
): Promise<{ source: number | undefined; destination: number }> {
|
|
184
|
+
let source: number | undefined;
|
|
185
|
+
let destination: number | undefined;
|
|
186
|
+
try {
|
|
187
|
+
if (sourcePath) {
|
|
188
|
+
try {
|
|
189
|
+
source = syncFs.openSync(sourcePath, HTML_EXPORT_SOURCE_OPEN_FLAGS);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
if (!isEnoent(error)) throw error;
|
|
192
|
+
}
|
|
193
|
+
await assertExportDoesNotAliasSource(sourcePath, outputPath);
|
|
194
|
+
}
|
|
195
|
+
destination = syncFs.openSync(outputPath, HTML_EXPORT_DESTINATION_OPEN_FLAGS, 0o666);
|
|
196
|
+
if (source !== undefined) {
|
|
197
|
+
const sourceIdentity = syncFs.fstatSync(source, { bigint: true });
|
|
198
|
+
const destinationIdentity = syncFs.fstatSync(destination, { bigint: true });
|
|
199
|
+
if (sameFileIdentity(sourceIdentity, destinationIdentity))
|
|
200
|
+
throw new Error("HTML export output must not overwrite the source transcript");
|
|
201
|
+
}
|
|
202
|
+
syncFs.ftruncateSync(destination, 0);
|
|
203
|
+
return { source, destination };
|
|
204
|
+
} catch (error) {
|
|
205
|
+
if (destination !== undefined) syncFs.closeSync(destination);
|
|
206
|
+
if (source !== undefined) syncFs.closeSync(source);
|
|
207
|
+
throw error;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
165
211
|
async function writeSessionHtml(
|
|
166
212
|
sm: SessionManager,
|
|
167
213
|
state: AgentState | undefined,
|
|
@@ -174,8 +220,8 @@ async function writeSessionHtml(
|
|
|
174
220
|
const markerOffset = themedTemplate.indexOf(marker);
|
|
175
221
|
if (markerOffset < 0) throw new Error("HTML export template is missing the session-data marker");
|
|
176
222
|
const sourcePath = sm.getSessionFile();
|
|
177
|
-
|
|
178
|
-
const sink = Bun.file(
|
|
223
|
+
const descriptors = await openHtmlExportDescriptors(sourcePath, outputPath);
|
|
224
|
+
const sink = Bun.file(descriptors.destination).writer();
|
|
179
225
|
const encoder = new Base64StreamEncoder();
|
|
180
226
|
const writeEncoded = (value: string): void => {
|
|
181
227
|
const encoded = encoder.write(value);
|
|
@@ -204,6 +250,9 @@ async function writeSessionHtml(
|
|
|
204
250
|
} catch (error) {
|
|
205
251
|
await sink.end();
|
|
206
252
|
throw error;
|
|
253
|
+
} finally {
|
|
254
|
+
if (descriptors.source !== undefined) syncFs.closeSync(descriptors.source);
|
|
255
|
+
syncFs.closeSync(descriptors.destination);
|
|
207
256
|
}
|
|
208
257
|
}
|
|
209
258
|
|
|
@@ -240,7 +240,15 @@ class ConcreteExtensionAPI implements ExtensionAPI, IExtensionRuntime {
|
|
|
240
240
|
|
|
241
241
|
sendUserMessage(
|
|
242
242
|
content: string | (TextContent | ImageContent)[],
|
|
243
|
-
options?: {
|
|
243
|
+
options?: {
|
|
244
|
+
deliverAs?: "steer" | "followUp";
|
|
245
|
+
queuedAtDispatch?: boolean;
|
|
246
|
+
onPreflightAccepted?: () => void;
|
|
247
|
+
onPreflightAcceptCommit?: () => void | Promise<void>;
|
|
248
|
+
onQueuedPromoted?: () => void;
|
|
249
|
+
preflightSignal?: AbortSignal;
|
|
250
|
+
sdkRunToken?: string;
|
|
251
|
+
},
|
|
244
252
|
): Promise<void> {
|
|
245
253
|
return Promise.resolve(this.runtime.sendUserMessage(content, options));
|
|
246
254
|
}
|
|
@@ -69,12 +69,18 @@ interface BeforeAgentStartCombinedResult {
|
|
|
69
69
|
|
|
70
70
|
export type ExtensionErrorListener = (error: ExtensionError) => void;
|
|
71
71
|
|
|
72
|
+
/** Bounded timeout for session_shutdown handlers — generous but never infinite. */
|
|
73
|
+
export const SESSION_SHUTDOWN_HANDLER_TIMEOUT_MS = 60_000;
|
|
72
74
|
export const EXTENSION_HANDLER_TIMEOUT_MS = 30_000;
|
|
73
75
|
let extensionHandlerTimeoutMs = EXTENSION_HANDLER_TIMEOUT_MS;
|
|
76
|
+
let sessionShutdownHandlerTimeoutMs = SESSION_SHUTDOWN_HANDLER_TIMEOUT_MS;
|
|
74
77
|
|
|
75
78
|
export function testSetExtensionHandlerTimeoutMs(timeoutMs: number): void {
|
|
76
79
|
extensionHandlerTimeoutMs = timeoutMs;
|
|
77
80
|
}
|
|
81
|
+
export function testSetSessionShutdownHandlerTimeoutMs(timeoutMs: number): void {
|
|
82
|
+
sessionShutdownHandlerTimeoutMs = timeoutMs;
|
|
83
|
+
}
|
|
78
84
|
|
|
79
85
|
const EXTENSION_HANDLER_TIMEOUT = Symbol("extensionHandlerTimeout");
|
|
80
86
|
|
|
@@ -201,7 +207,7 @@ export class ExtensionRunner {
|
|
|
201
207
|
#isIdleFn: () => boolean = () => true;
|
|
202
208
|
#getActivePromptHandleFn: () => string | undefined = () => undefined;
|
|
203
209
|
#waitForIdleFn: () => Promise<void> = async () => {};
|
|
204
|
-
#abortFn: () => void = () => {};
|
|
210
|
+
#abortFn: () => void | Promise<void> = () => {};
|
|
205
211
|
#abortPromptAndWaitFn: NonNullable<ExtensionContextActions["abortPromptAndWait"]> = async () => {
|
|
206
212
|
throw new Error("abortPromptAndWait binding is unavailable");
|
|
207
213
|
};
|
|
@@ -637,7 +643,7 @@ export class ExtensionRunner {
|
|
|
637
643
|
withSdkControlMutation: body => this.#withSdkControlMutationFn?.(body) ?? body(),
|
|
638
644
|
cycleThinkingLevel: () => this.#cycleThinkingLevelFn?.(),
|
|
639
645
|
setQueueMode: (kind, mode) => this.#setQueueModeFn?.(kind, mode) ?? false,
|
|
640
|
-
invokeSkill: async (name, args) => await this.#invokeSkillFn?.(name, args),
|
|
646
|
+
invokeSkill: async (name, args, options) => await this.#invokeSkillFn?.(name, args, options),
|
|
641
647
|
|
|
642
648
|
setPlanMode: on => this.#setPlanModeFn?.(on),
|
|
643
649
|
operateGoal: async (op, objective) => await this.#operateGoalFn?.(op, objective),
|
|
@@ -715,12 +721,13 @@ export class ExtensionRunner {
|
|
|
715
721
|
event: TEvent,
|
|
716
722
|
ctx: ExtensionContext,
|
|
717
723
|
ext: Extension,
|
|
718
|
-
timeoutMs: number,
|
|
724
|
+
timeoutMs: number | undefined,
|
|
719
725
|
): Promise<TResult | undefined> {
|
|
720
726
|
let timeout: NodeJS.Timeout | undefined;
|
|
721
727
|
const abortController = new AbortController();
|
|
722
728
|
const handlerContext = createHandlerContext(ctx, abortController.signal);
|
|
723
729
|
try {
|
|
730
|
+
if (timeoutMs === undefined) return await handler(event, handlerContext);
|
|
724
731
|
const timeoutPromise = new Promise<typeof EXTENSION_HANDLER_TIMEOUT>(resolve => {
|
|
725
732
|
timeout = setTimeout(() => resolve(EXTENSION_HANDLER_TIMEOUT), timeoutMs);
|
|
726
733
|
});
|
|
@@ -782,7 +789,13 @@ export class ExtensionRunner {
|
|
|
782
789
|
this.#markAttemptExecuted(scope);
|
|
783
790
|
marked = true;
|
|
784
791
|
}
|
|
785
|
-
const handlerResult = await this.#runHandlerWithTimeout(
|
|
792
|
+
const handlerResult = await this.#runHandlerWithTimeout(
|
|
793
|
+
handler,
|
|
794
|
+
event,
|
|
795
|
+
ctx,
|
|
796
|
+
ext,
|
|
797
|
+
event.type === "session_shutdown" ? sessionShutdownHandlerTimeoutMs : extensionHandlerTimeoutMs,
|
|
798
|
+
);
|
|
786
799
|
if (continueWhile && !continueWhile()) return result as RunnerEmitResult<TEvent>;
|
|
787
800
|
|
|
788
801
|
if (this.#isSessionBeforeEvent(event) && handlerResult) {
|
|
@@ -65,7 +65,6 @@ import type {
|
|
|
65
65
|
import type { EventBus } from "../../utils/event-bus";
|
|
66
66
|
import type {
|
|
67
67
|
AgentEndEvent,
|
|
68
|
-
AgentStartEvent,
|
|
69
68
|
AutoCompactionEndEvent,
|
|
70
69
|
AutoCompactionStartEvent,
|
|
71
70
|
AutoRetryEndEvent,
|
|
@@ -89,6 +88,7 @@ import type {
|
|
|
89
88
|
SessionStartEvent,
|
|
90
89
|
SessionSwitchEvent,
|
|
91
90
|
SessionTreeEvent,
|
|
91
|
+
AgentStartEvent as SharedAgentStartEvent,
|
|
92
92
|
TodoReminderEvent,
|
|
93
93
|
ToolCallEventResult,
|
|
94
94
|
ToolResultEventResult,
|
|
@@ -369,7 +369,7 @@ export interface ExtensionContext {
|
|
|
369
369
|
/** Stable resource ownership identifier for the active prompt run. */
|
|
370
370
|
getActivePromptHandle(): string | undefined;
|
|
371
371
|
/** Abort the current agent operation */
|
|
372
|
-
abort(): void
|
|
372
|
+
abort(): void | Promise<void>;
|
|
373
373
|
/** Abort and prove whether resources for a specific prompt settled. */
|
|
374
374
|
abortPromptAndWait?(handle: string, options: { graceMs: number }): Promise<RunSettlementProof>;
|
|
375
375
|
/** Whether there are queued messages waiting */
|
|
@@ -429,6 +429,7 @@ export interface ExtensionContext {
|
|
|
429
429
|
onPreflightAccepted?: () => void;
|
|
430
430
|
onPreflightAcceptCommit?: () => void | Promise<void>;
|
|
431
431
|
onSkillPrepared?: (meta: { name: string; path: string; lineCount?: number; cleanedArgs?: string }) => void;
|
|
432
|
+
preflightSignal?: AbortSignal;
|
|
432
433
|
},
|
|
433
434
|
): Promise<unknown>;
|
|
434
435
|
setPlanMode?(on: boolean): unknown;
|
|
@@ -634,7 +635,12 @@ export interface BeforeAgentStartEvent {
|
|
|
634
635
|
systemPrompt: string[];
|
|
635
636
|
}
|
|
636
637
|
|
|
637
|
-
export type { AgentEndEvent,
|
|
638
|
+
export type { AgentEndEvent, TurnEndEvent, TurnStartEvent } from "../shared-events";
|
|
639
|
+
|
|
640
|
+
/** Fired when an agent loop starts. `sdkRunToken` is an internal SDK queue-owner binding. */
|
|
641
|
+
export interface AgentStartEvent extends SharedAgentStartEvent {
|
|
642
|
+
sdkRunToken?: string;
|
|
643
|
+
}
|
|
638
644
|
|
|
639
645
|
/** Fired when a message starts (user, assistant, or toolResult) */
|
|
640
646
|
export interface MessageStartEvent {
|
|
@@ -1169,7 +1175,10 @@ export interface ExtensionAPI {
|
|
|
1169
1175
|
*/
|
|
1170
1176
|
sendMessage<T = unknown>(
|
|
1171
1177
|
message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details" | "attribution">,
|
|
1172
|
-
options?: {
|
|
1178
|
+
options?: {
|
|
1179
|
+
triggerTurn?: boolean;
|
|
1180
|
+
deliverAs?: "steer" | "followUp" | "nextTurn";
|
|
1181
|
+
},
|
|
1173
1182
|
): void;
|
|
1174
1183
|
|
|
1175
1184
|
/** Send a user message to the agent, or queue it when deliverAs is set. */
|
|
@@ -1177,8 +1186,14 @@ export interface ExtensionAPI {
|
|
|
1177
1186
|
content: string | (TextContent | ImageContent)[],
|
|
1178
1187
|
options?: {
|
|
1179
1188
|
deliverAs?: "steer" | "followUp";
|
|
1189
|
+
/** Internal SDK signal preserving a busy dispatch across async admission fences. */
|
|
1190
|
+
queuedAtDispatch?: boolean;
|
|
1180
1191
|
onPreflightAccepted?: () => void;
|
|
1181
1192
|
onPreflightAcceptCommit?: () => void | Promise<void>;
|
|
1193
|
+
onQueuedPromoted?: () => void;
|
|
1194
|
+
preflightSignal?: AbortSignal;
|
|
1195
|
+
/** Internal SDK correlation owner for an exact queued follow-up. */
|
|
1196
|
+
sdkRunToken?: string;
|
|
1182
1197
|
},
|
|
1183
1198
|
): Promise<void>;
|
|
1184
1199
|
|
|
@@ -1387,7 +1402,10 @@ export type SendMessageHandler = <T = unknown>(
|
|
|
1387
1402
|
* When paired with `triggerTurn: true` during prompt teardown, the session schedules
|
|
1388
1403
|
* an internal continuation without surfacing the message in the editable pending queue.
|
|
1389
1404
|
*/
|
|
1390
|
-
options?: {
|
|
1405
|
+
options?: {
|
|
1406
|
+
triggerTurn?: boolean;
|
|
1407
|
+
deliverAs?: "steer" | "followUp" | "nextTurn";
|
|
1408
|
+
},
|
|
1391
1409
|
) => void;
|
|
1392
1410
|
|
|
1393
1411
|
export type SendUserMessageHandler = (
|
|
@@ -1396,6 +1414,11 @@ export type SendUserMessageHandler = (
|
|
|
1396
1414
|
deliverAs?: "steer" | "followUp";
|
|
1397
1415
|
onPreflightAccepted?: () => void;
|
|
1398
1416
|
onPreflightAcceptCommit?: () => void | Promise<void>;
|
|
1417
|
+
/** Fired when a queued submission (steering or follow-up) is promoted to its own run (SDK ownership correlation). */
|
|
1418
|
+
onQueuedPromoted?: () => void;
|
|
1419
|
+
preflightSignal?: AbortSignal;
|
|
1420
|
+
/** Internal SDK correlation owner for an exact queued follow-up. */
|
|
1421
|
+
sdkRunToken?: string;
|
|
1399
1422
|
},
|
|
1400
1423
|
) => void | Promise<void>;
|
|
1401
1424
|
|
|
@@ -1485,8 +1508,9 @@ export interface ExtensionContextActions {
|
|
|
1485
1508
|
isIdle: () => boolean;
|
|
1486
1509
|
/** Stable resource ownership identifier for the active prompt run. */
|
|
1487
1510
|
getActivePromptHandle?: () => string | undefined;
|
|
1488
|
-
abort: () => void
|
|
1511
|
+
abort: () => void | Promise<void>;
|
|
1489
1512
|
abortPromptAndWait?: (handle: string, options: { graceMs: number }) => Promise<RunSettlementProof>;
|
|
1513
|
+
|
|
1490
1514
|
hasPendingMessages: () => boolean;
|
|
1491
1515
|
/** Typed pending-message counts per queue; optional for embedders without a counted queue. */
|
|
1492
1516
|
getPendingMessageCounts?: () => { steering: number; followUp: number; nextTurn: number };
|
|
@@ -1555,6 +1579,7 @@ export interface ExtensionContextActions {
|
|
|
1555
1579
|
onPreflightAccepted?: () => void;
|
|
1556
1580
|
onPreflightAcceptCommit?: () => void | Promise<void>;
|
|
1557
1581
|
onSkillPrepared?: (meta: { name: string; path: string; lineCount?: number; cleanedArgs?: string }) => void;
|
|
1582
|
+
preflightSignal?: AbortSignal;
|
|
1558
1583
|
},
|
|
1559
1584
|
) => Promise<unknown>;
|
|
1560
1585
|
setPlanMode?: (on: boolean) => unknown;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { logger } from "@gajae-code/utils";
|
|
4
|
+
import { normalizePluginHook } from "../../hooks/normalize";
|
|
4
5
|
import { bundleIdentity } from "./lifecycle-reconciliation";
|
|
5
6
|
import { verifyImplementationHash } from "./metadata";
|
|
6
7
|
import { resolveWithinRoot } from "./paths";
|
|
@@ -106,6 +107,19 @@ export class ConstrainedPluginHookDescriptor {
|
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
async load(): Promise<ConstrainedPluginHook> {
|
|
110
|
+
const normalized = normalizePluginHook({
|
|
111
|
+
declaredEvent: this.event,
|
|
112
|
+
target: this.target,
|
|
113
|
+
phase: this.phase,
|
|
114
|
+
plugin: this.plugin,
|
|
115
|
+
source: this.relativePath,
|
|
116
|
+
});
|
|
117
|
+
if (!normalized.hook) {
|
|
118
|
+
throw new GjcPluginLoadError(
|
|
119
|
+
"invalid_hook",
|
|
120
|
+
normalized.diagnostics.map(diagnostic => `${diagnostic.code}: ${diagnostic.message}`).join("; "),
|
|
121
|
+
);
|
|
122
|
+
}
|
|
109
123
|
if (this.implementationHash) await verifyImplementationHash(this.relativePath, this.implementationHash);
|
|
110
124
|
const registered: { event: string; handler: (...a: any[]) => unknown }[] = [];
|
|
111
125
|
const deny = (method: string) => () => {
|
|
@@ -171,6 +185,25 @@ export async function loadConstrainedPluginHooks(input: { cwd: string }): Promis
|
|
|
171
185
|
const invalidHookIds = new Set<string>();
|
|
172
186
|
for (const entry of effective) {
|
|
173
187
|
if (!entry.enabled) continue;
|
|
188
|
+
for (const hook of entry.surfaces.hooks) {
|
|
189
|
+
if (entry.disabledSurfaceIds.includes(hook.extensionId)) continue;
|
|
190
|
+
const normalized = normalizePluginHook({
|
|
191
|
+
declaredEvent: hook.event,
|
|
192
|
+
target: hook.target,
|
|
193
|
+
phase: hook.phase,
|
|
194
|
+
plugin: entry.name,
|
|
195
|
+
source: hook.relativePath,
|
|
196
|
+
});
|
|
197
|
+
if (normalized.hook) continue;
|
|
198
|
+
invalidHookIds.add(`${entry.scope}:${entry.name}:${hook.extensionId}`);
|
|
199
|
+
preQuarantine.push({
|
|
200
|
+
identity: bundleIdentity(entry.scope, entry.name),
|
|
201
|
+
plugin: entry.name,
|
|
202
|
+
surfaceId: hook.extensionId,
|
|
203
|
+
code: "invalid_hook",
|
|
204
|
+
message: normalized.diagnostics.map(diagnostic => `${diagnostic.code}: ${diagnostic.message}`).join("; "),
|
|
205
|
+
});
|
|
206
|
+
}
|
|
174
207
|
const drift = await verifyEntryHashes(entry);
|
|
175
208
|
if (drift) preQuarantine.push(drift);
|
|
176
209
|
for (const hook of entry.surfaces.hooks) {
|
|
@@ -392,8 +392,12 @@ export async function runGjcBundleTransaction(
|
|
|
392
392
|
): Promise<GjcBundleTransactionResult> {
|
|
393
393
|
const resolved = await resolveSource(source);
|
|
394
394
|
try {
|
|
395
|
-
// Compile + validate
|
|
395
|
+
// Compile + validate candidate-internal collisions and MCP policy outside
|
|
396
|
+
// every lock (never imports plugin code). Registry collisions are rechecked
|
|
397
|
+
// under both locks below, but a statically invalid candidate must not create
|
|
398
|
+
// lock roots or sweep installation remnants.
|
|
396
399
|
const bundle = await compileGjcPluginBundle(resolved.dir);
|
|
400
|
+
validateInstallPlan(bundle, []);
|
|
397
401
|
const dirName = safeDirSegment(bundle.name);
|
|
398
402
|
const root = scopeRoot(options.scope, options.cwd);
|
|
399
403
|
const finalDir = path.join(root, dirName);
|
|
@@ -450,10 +454,6 @@ export async function runGjcBundleTransaction(
|
|
|
450
454
|
if (decision.kind === "abort") return { status: "aborted", error: decision.error, remnants: [] };
|
|
451
455
|
if (decision.kind === "noop") return { status: "noop", entry: decision.entry, remnants: [] };
|
|
452
456
|
|
|
453
|
-
// The decision committed, so mutation may begin.
|
|
454
|
-
await fs.mkdir(root, { recursive: true });
|
|
455
|
-
await cleanupOrphans(root, dirName);
|
|
456
|
-
|
|
457
457
|
// Hard install-time collision + MCP security validation against the
|
|
458
458
|
// effective registry across BOTH scopes. Surface IDs derive from the
|
|
459
459
|
// surface name, not the bundle name, so a differently named bundle in
|
|
@@ -461,6 +461,10 @@ export async function runGjcBundleTransaction(
|
|
|
461
461
|
// identity is excluded, since that is the entry being replaced.
|
|
462
462
|
validateInstallPlan(bundle, effective);
|
|
463
463
|
|
|
464
|
+
// The decision and all validation committed, so mutation may begin.
|
|
465
|
+
await fs.mkdir(root, { recursive: true });
|
|
466
|
+
await cleanupOrphans(root, dirName);
|
|
467
|
+
|
|
464
468
|
const unique = `${process.pid}-${randomBytes(6).toString("hex")}`;
|
|
465
469
|
const stagingDir = `${finalDir}.installing-${unique}`;
|
|
466
470
|
const backupDir = `${finalDir}.backup-${unique}`;
|
|
@@ -65,9 +65,15 @@ function rowsForEntry(entry: GjcPluginRegistryEntry, quarantinedIds: Map<string,
|
|
|
65
65
|
/**
|
|
66
66
|
* Build the observability summary for the effective registry at `cwd`, including
|
|
67
67
|
* hash-drift and session-collision quarantine status.
|
|
68
|
+
*
|
|
69
|
+
* Pass `{ migrate: false }` from read-only inspection surfaces (for example
|
|
70
|
+
* `gjc customize doctor`) so reporting never persists registry migrations.
|
|
68
71
|
*/
|
|
69
|
-
export async function summarizeGjcPluginObservability(
|
|
70
|
-
|
|
72
|
+
export async function summarizeGjcPluginObservability(
|
|
73
|
+
cwd: string,
|
|
74
|
+
options: { migrate?: boolean } = {},
|
|
75
|
+
): Promise<PluginObservabilitySummary> {
|
|
76
|
+
const effective = await loadEffectiveGjcPluginRegistry(cwd, options);
|
|
71
77
|
const preQuarantine: SessionQuarantine[] = [];
|
|
72
78
|
for (const entry of effective) {
|
|
73
79
|
if (!entry.enabled) continue;
|
|
@@ -319,9 +319,20 @@ export async function updateRegistry(
|
|
|
319
319
|
|
|
320
320
|
/**
|
|
321
321
|
* Effective registry for a cwd: user + project entries in deterministic order.
|
|
322
|
+
*
|
|
323
|
+
* Defaults to the startup semantics (legacy-entry discovery + migration, which
|
|
324
|
+
* may persist the migrated registry). Read-only inspection surfaces (for
|
|
325
|
+
* example `gjc customize doctor`) pass `{ migrate: false }` so reporting never
|
|
326
|
+
* writes to the registry.
|
|
322
327
|
*/
|
|
323
|
-
export async function loadEffectiveGjcPluginRegistry(
|
|
324
|
-
|
|
328
|
+
export async function loadEffectiveGjcPluginRegistry(
|
|
329
|
+
cwd: string,
|
|
330
|
+
options: { migrate?: boolean } = {},
|
|
331
|
+
): Promise<GjcPluginRegistryEntry[]> {
|
|
332
|
+
const [user, project] = await Promise.all([
|
|
333
|
+
readRegistry("user", cwd, options),
|
|
334
|
+
readRegistry("project", cwd, options),
|
|
335
|
+
]);
|
|
325
336
|
return sortRegistryEntries([...user.plugins, ...project.plugins]);
|
|
326
337
|
}
|
|
327
338
|
|
|
@@ -437,7 +437,9 @@ export async function buildPluginMcpConfigs(input: { cwd: string }): Promise<{
|
|
|
437
437
|
const { assertMcpInstallPolicy, assertDnsResolvesPublic, assertUrlAllowed } = await import("./mcp-policy");
|
|
438
438
|
const nodePath = await import("node:path");
|
|
439
439
|
|
|
440
|
-
|
|
440
|
+
// A manifest-controlled MCP name such as "constructor" or "toString" must
|
|
441
|
+
// remain an ordinary own key rather than interacting with Object.prototype.
|
|
442
|
+
const configs: Record<string, any> = Object.create(null) as Record<string, any>;
|
|
441
443
|
for (const entry of active) {
|
|
442
444
|
const disabled = new Set(entry.disabledSurfaceIds);
|
|
443
445
|
for (const m of entry.surfaces.mcps) {
|