@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
package/src/tools/subagent.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@gajae-code/agent-core";
|
|
3
|
-
import { prompt } from "@gajae-code/utils";
|
|
3
|
+
import { formatDuration, logger, prompt } from "@gajae-code/utils";
|
|
4
4
|
import * as z from "zod/v4";
|
|
5
5
|
import { type AsyncJob, AsyncJobManager, jobElapsedMs, type SubagentRecord } from "../async";
|
|
6
6
|
import subagentDescription from "../prompts/tools/subagent.md" with { type: "text" };
|
|
@@ -12,6 +12,15 @@ import { ToolError } from "./tool-errors";
|
|
|
12
12
|
|
|
13
13
|
const DEFAULT_AWAIT_TIMEOUT_MS = 30_000;
|
|
14
14
|
const MAX_AWAIT_TIMEOUT_MS = 60 * 60 * 1000;
|
|
15
|
+
/**
|
|
16
|
+
* Bounded cadence for await liveness: even when the rendered-state signature is
|
|
17
|
+
* stable (a running subagent emitting no new progress), the await panel re-emits
|
|
18
|
+
* so a healthy wait never looks like a hung session (issue #4465). Derived from
|
|
19
|
+
* `heartbeat_ms` so callers keep one knob, floor-bounded so a small heartbeat
|
|
20
|
+
* cannot turn liveness into transcript spam, and injected for tests.
|
|
21
|
+
*/
|
|
22
|
+
const AWAIT_LIVENESS_MULTIPLIER = 30;
|
|
23
|
+
const AWAIT_LIVENESS_MIN_INTERVAL_MS = 15_000;
|
|
15
24
|
const DEFAULT_LIST_LIMIT = 10;
|
|
16
25
|
const MAX_LIST_LIMIT = 50;
|
|
17
26
|
const RECEIPT_PREVIEW_WIDTH = 280;
|
|
@@ -123,6 +132,22 @@ export class SubagentTool implements AgentTool<typeof subagentSchema, SubagentTo
|
|
|
123
132
|
readonly parameters = subagentSchema;
|
|
124
133
|
readonly strict = true;
|
|
125
134
|
readonly loadMode = "discoverable";
|
|
135
|
+
/**
|
|
136
|
+
* Injected monotonic clock for await-liveness tests. Production callers leave
|
|
137
|
+
* this undefined and the await falls back to `Date.now`; tests substitute a
|
|
138
|
+
* virtual clock so a 15s+ liveness interval is exercised without any real
|
|
139
|
+
* multi-minute sleep (#4465).
|
|
140
|
+
*/
|
|
141
|
+
#livenessNowMs?: () => number;
|
|
142
|
+
|
|
143
|
+
/** Test-only seam: substitute the liveness clock. Returns a restore function. */
|
|
144
|
+
withLivenessClock(nowMs: () => number): () => void {
|
|
145
|
+
const prior = this.#livenessNowMs;
|
|
146
|
+
this.#livenessNowMs = nowMs;
|
|
147
|
+
return () => {
|
|
148
|
+
this.#livenessNowMs = prior;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
126
151
|
|
|
127
152
|
constructor(private readonly session: ToolSession) {
|
|
128
153
|
this.description = prompt.render(subagentDescription);
|
|
@@ -135,7 +160,16 @@ export class SubagentTool implements AgentTool<typeof subagentSchema, SubagentTo
|
|
|
135
160
|
onUpdate?: AgentToolUpdateCallback<SubagentToolDetails>,
|
|
136
161
|
_context?: AgentToolContext,
|
|
137
162
|
): Promise<AgentToolResult<SubagentToolDetails>> {
|
|
138
|
-
|
|
163
|
+
// The session's ENDPOINT-owned manager first: concurrent top-level
|
|
164
|
+
// sessions register their manager under their endpoint (sdk/session.ts),
|
|
165
|
+
// so list/pause/resume/message/cancel/await must inspect THIS session's
|
|
166
|
+
// manager — the process-global instance belongs to the last-created
|
|
167
|
+
// session, where this session's subagent records and jobs are absent
|
|
168
|
+
// or belong to a same-id subagent of another session (review thread P1).
|
|
169
|
+
const manager =
|
|
170
|
+
this.session.getAsyncJobManager?.() ??
|
|
171
|
+
AsyncJobManager.forEndpoint(this.session.getSessionId?.() ?? undefined) ??
|
|
172
|
+
AsyncJobManager.instance();
|
|
139
173
|
if (!manager) {
|
|
140
174
|
return {
|
|
141
175
|
content: [{ type: "text", text: "No subagent manager is available in this session." }],
|
|
@@ -241,7 +275,7 @@ export class SubagentTool implements AgentTool<typeof subagentSchema, SubagentTo
|
|
|
241
275
|
records.push(record);
|
|
242
276
|
terminalGuidanceIds.add(record.subagentId);
|
|
243
277
|
} else {
|
|
244
|
-
const result = manager.resumeSubagent(record.subagentId, ownerFilter, params.message);
|
|
278
|
+
const result = manager.resumeSubagent(record.subagentId, ownerFilter, params.message, _toolCallId);
|
|
245
279
|
if (!result.ok && result.reason === "context_unavailable") throw new ToolError("context unavailable");
|
|
246
280
|
if (!result.ok && result.reason === "not_found") {
|
|
247
281
|
missing.push(this.#missingSnapshot(id, "not_found", "No visible detached subagent matches this id."));
|
|
@@ -293,7 +327,7 @@ export class SubagentTool implements AgentTool<typeof subagentSchema, SubagentTo
|
|
|
293
327
|
records.push(manager.getSubagentRecord(record.subagentId, ownerFilter) ?? record);
|
|
294
328
|
steerStates.set(record.subagentId, "queued");
|
|
295
329
|
} else {
|
|
296
|
-
const result = manager.resumeSubagent(record.subagentId, ownerFilter, message);
|
|
330
|
+
const result = manager.resumeSubagent(record.subagentId, ownerFilter, message, _toolCallId);
|
|
297
331
|
if (!result.ok && result.reason === "not_found") {
|
|
298
332
|
missing.push(this.#missingSnapshot(id, "not_found", "No visible detached subagent matches this id."));
|
|
299
333
|
} else if (!result.ok) {
|
|
@@ -402,23 +436,71 @@ export class SubagentTool implements AgentTool<typeof subagentSchema, SubagentTo
|
|
|
402
436
|
});
|
|
403
437
|
}
|
|
404
438
|
const watchedJobIds = targets.map(target => target.jobId).filter((jobId): jobId is string => jobId !== null);
|
|
405
|
-
manager.
|
|
439
|
+
const watchHandle = manager.watchJobGenerations(watchedJobIds);
|
|
406
440
|
const heartbeatMs = params.heartbeat_ms === undefined ? 500 : params.heartbeat_ms;
|
|
441
|
+
// Liveness interval: force a re-emit even when the rendered-state signature
|
|
442
|
+
// is stable so a healthy wait never looks like a hung session (#4465). The
|
|
443
|
+
// `#livenessNowMs` clock is injected for deterministic tests; `Date.now`
|
|
444
|
+
// is the production fallback. The interval is floor-bounded so a caller who
|
|
445
|
+
// sets a tiny `heartbeat_ms` cannot turn liveness into transcript spam.
|
|
446
|
+
const livenessIntervalMs = Math.max(AWAIT_LIVENESS_MIN_INTERVAL_MS, heartbeatMs * AWAIT_LIVENESS_MULTIPLIER);
|
|
447
|
+
const nowMs = this.#livenessNowMs ?? Date.now;
|
|
448
|
+
let lastEmitMs = nowMs();
|
|
407
449
|
let lastEmittedSignature: string | undefined;
|
|
450
|
+
let streamingDisabled = false;
|
|
451
|
+
let stopProgressTimer = (): void => {};
|
|
452
|
+
const disableStreaming = (error: unknown): void => {
|
|
453
|
+
if (streamingDisabled) return;
|
|
454
|
+
streamingDisabled = true;
|
|
455
|
+
stopProgressTimer();
|
|
456
|
+
try {
|
|
457
|
+
logger.warn("Subagent await progress update failed; streaming disabled for this wait", {
|
|
458
|
+
error: safeThrownValue(error),
|
|
459
|
+
});
|
|
460
|
+
} catch {
|
|
461
|
+
// Diagnostics must never turn a recoverable progress-channel failure
|
|
462
|
+
// into an await or process-lifecycle failure.
|
|
463
|
+
}
|
|
464
|
+
};
|
|
408
465
|
const emitIfChanged = (force: boolean): void => {
|
|
409
|
-
if (!onUpdate) return;
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
466
|
+
if (!onUpdate || streamingDisabled) return;
|
|
467
|
+
try {
|
|
468
|
+
const result = this.#progressResult(manager, records, true);
|
|
469
|
+
const signature = subagentAwaitRenderedStateSignature(result.details?.subagents ?? []);
|
|
470
|
+
const t = nowMs();
|
|
471
|
+
const livenessDue = force || t - lastEmitMs >= livenessIntervalMs;
|
|
472
|
+
if (!livenessDue && signature === lastEmittedSignature) return;
|
|
473
|
+
lastEmittedSignature = signature;
|
|
474
|
+
lastEmitMs = t;
|
|
475
|
+
// A TypeScript void-return callback may still be implemented by an
|
|
476
|
+
// async function. Observe its runtime result so a rejected promise or
|
|
477
|
+
// thenable cannot become an unhandled rejection outside this span.
|
|
478
|
+
const updateResult = (onUpdate as (update: AgentToolResult<SubagentToolDetails>) => unknown)(result);
|
|
479
|
+
if (isPromiseLike(updateResult)) void Promise.resolve(updateResult).catch(disableStreaming);
|
|
480
|
+
} catch (error) {
|
|
481
|
+
// The liveness timer fires outside this function's promise chain, so a
|
|
482
|
+
// throwing progress consumer would otherwise escape `setInterval` as an
|
|
483
|
+
// uncaught exception, leave the wait's cleanup unreached, and let the
|
|
484
|
+
// interval keep firing and rethrowing for the rest of the await. Retire
|
|
485
|
+
// the streaming channel instead and keep waiting: losing progress output
|
|
486
|
+
// is recoverable, losing the timer and the watch registration is not.
|
|
487
|
+
disableStreaming(error);
|
|
488
|
+
}
|
|
415
489
|
};
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
490
|
+
// The initial emission and the timer own process-lifetime resources together
|
|
491
|
+
// with the watch registration and the terminal-wait handle, so they all live
|
|
492
|
+
// inside one guarded span rather than straddling it.
|
|
493
|
+
let progressTimer: Timer | undefined;
|
|
419
494
|
let waitOutcome: "completed" | "timed_out_wait" | "interrupted";
|
|
420
495
|
let onAbort: (() => void) | undefined;
|
|
496
|
+
let terminalJobIds: string[] | undefined;
|
|
421
497
|
try {
|
|
498
|
+
progressTimer = onUpdate && heartbeatMs > 0 ? setInterval(() => emitIfChanged(false), heartbeatMs) : undefined;
|
|
499
|
+
stopProgressTimer = () => {
|
|
500
|
+
if (progressTimer) clearInterval(progressTimer);
|
|
501
|
+
progressTimer = undefined;
|
|
502
|
+
};
|
|
503
|
+
emitIfChanged(true);
|
|
422
504
|
const abortPromise = new Promise<"interrupted">(resolve => {
|
|
423
505
|
onAbort = () => resolve("interrupted");
|
|
424
506
|
if (signal?.aborted) onAbort();
|
|
@@ -432,14 +514,16 @@ export class SubagentTool implements AgentTool<typeof subagentSchema, SubagentTo
|
|
|
432
514
|
Bun.sleep(timeoutMs).then(() => "timed_out_wait" as const),
|
|
433
515
|
abortPromise,
|
|
434
516
|
]);
|
|
517
|
+
if (waitOutcome === "completed") {
|
|
518
|
+
terminalJobIds = (await handle.result).terminalJobIds;
|
|
519
|
+
handle.acknowledge(terminalJobIds);
|
|
520
|
+
}
|
|
435
521
|
} finally {
|
|
436
522
|
if (signal && onAbort) signal.removeEventListener("abort", onAbort);
|
|
437
|
-
|
|
523
|
+
stopProgressTimer();
|
|
524
|
+
watchHandle.close();
|
|
525
|
+
handle.close();
|
|
438
526
|
}
|
|
439
|
-
const waitResult = waitOutcome === "completed" ? await handle.result : undefined;
|
|
440
|
-
if (waitOutcome === "completed") handle.acknowledge(waitResult?.terminalJobIds);
|
|
441
|
-
manager.unwatchJobs(watchedJobIds);
|
|
442
|
-
handle.close();
|
|
443
527
|
const awaitOutcome: SubagentAwaitOutcome =
|
|
444
528
|
waitOutcome === "completed" ? "completed" : waitOutcome === "timed_out_wait" ? "timed_out" : "interrupted";
|
|
445
529
|
const finalRecords = this.#visibleRecordsByIds(
|
|
@@ -456,7 +540,7 @@ export class SubagentTool implements AgentTool<typeof subagentSchema, SubagentTo
|
|
|
456
540
|
awaitOutcome,
|
|
457
541
|
waitOutcome,
|
|
458
542
|
condition,
|
|
459
|
-
terminalIds:
|
|
543
|
+
terminalIds: terminalJobIds,
|
|
460
544
|
});
|
|
461
545
|
}
|
|
462
546
|
|
|
@@ -558,11 +642,10 @@ export class SubagentTool implements AgentTool<typeof subagentSchema, SubagentTo
|
|
|
558
642
|
records: SubagentRecord[],
|
|
559
643
|
attachLiveProgress = false,
|
|
560
644
|
): AgentToolResult<SubagentToolDetails> {
|
|
645
|
+
const subagents = this.#recordSnapshots(manager, records, false, "receipt", new Set(), attachLiveProgress);
|
|
561
646
|
return {
|
|
562
|
-
content: [{ type: "text", text:
|
|
563
|
-
details: {
|
|
564
|
-
subagents: this.#recordSnapshots(manager, records, false, "receipt", new Set(), attachLiveProgress),
|
|
565
|
-
},
|
|
647
|
+
content: [{ type: "text", text: awaitProgressSummary(subagents) }],
|
|
648
|
+
details: { subagents },
|
|
566
649
|
};
|
|
567
650
|
}
|
|
568
651
|
|
|
@@ -810,6 +893,41 @@ export class SubagentTool implements AgentTool<typeof subagentSchema, SubagentTo
|
|
|
810
893
|
}
|
|
811
894
|
}
|
|
812
895
|
|
|
896
|
+
/**
|
|
897
|
+
* Human-readable line for streamed `await` progress.
|
|
898
|
+
*
|
|
899
|
+
* Consumers that render structured content (ACP) previously received an empty
|
|
900
|
+
* text block here, which made `extractStructuredText` fail and the mapper fall
|
|
901
|
+
* back to serializing the whole result object as the human-readable content. A
|
|
902
|
+
* real sentence keeps the elapsed time legible there and in any log that only
|
|
903
|
+
* shows tool text.
|
|
904
|
+
*/
|
|
905
|
+
function awaitProgressSummary(subagents: readonly SubagentSnapshot[]): string {
|
|
906
|
+
const waiting = subagents.filter(snapshot => !isTerminalStatus(snapshot.status));
|
|
907
|
+
if (waiting.length === 0) return "";
|
|
908
|
+
// Accumulate rather than spreading into Math.max: explicit `ids` are not
|
|
909
|
+
// capped by MAX_LIST_LIMIT, so a large await would hit the argument limit.
|
|
910
|
+
let longestMs = 0;
|
|
911
|
+
for (const snapshot of waiting) if (snapshot.durationMs > longestMs) longestMs = snapshot.durationMs;
|
|
912
|
+
return `Awaiting ${waiting.length} subagent(s) for ${formatDuration(longestMs)}: ${waiting
|
|
913
|
+
.map(snapshot => snapshot.id)
|
|
914
|
+
.join(", ")}`;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
function isPromiseLike(value: unknown): value is PromiseLike<unknown> {
|
|
918
|
+
if ((typeof value !== "object" || value === null) && typeof value !== "function") return false;
|
|
919
|
+
return typeof (value as { then?: unknown }).then === "function";
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
function safeThrownValue(error: unknown): string {
|
|
923
|
+
try {
|
|
924
|
+
if (error instanceof Error) return error.message;
|
|
925
|
+
return String(error);
|
|
926
|
+
} catch {
|
|
927
|
+
return "[unprintable thrown value]";
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
|
|
813
931
|
function isTerminalStatus(status: SubagentStatus): boolean {
|
|
814
932
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
815
933
|
}
|
|
@@ -58,7 +58,7 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
58
58
|
"bash": {
|
|
59
59
|
"name": "bash",
|
|
60
60
|
"label": "Bash",
|
|
61
|
-
"description": "Executes bash command in shell session for terminal operations like git, bun, cargo, python.\n\n<instruction>\n- Use `cwd` to set working directory, not `cd dir && …`\n- Prefer `env: { NAME: \"…\" }` for multiline, quote-heavy, or untrusted values; reference as `$NAME`\n- Quote variable expansions like `\"$NAME\"` to preserve exact content\n- PTY mode is opt-in: set `pty: true` only when the command needs a real terminal (e.g. `sudo`, `ssh` requiring user input); default is `false`\n- Use `;` only when later commands should run regardless of earlier failures\n- Internal URIs (`agent://`, `artifact://`, `rule://`, `local://`) are auto-resolved to filesystem paths\n</instruction>\n\n<critical>\n- Use bash only for terminal operations that dedicated tools do not cover.\n- Never pipe through `| head -n N` or `| tail -n N` — output is already truncated. Recover omitted output only when the result includes an `artifact://<id>` footer or metadata reference; truncation without a reference leaves the visible output incomplete with no recoverable artifact.\n- Never redirect with `2>&1` or `2>/dev/null` — stdout and stderr are already merged.\n</critical>\n\n<output>\n- Returns output and exit code.\n- Truncated output is recoverable only when the result includes an `artifact://<id>` footer or metadata reference; truncation evidence without such a reference means the visible output is incomplete and no artifact is recoverable.\n- Exit codes shown on non-zero exit\n</output>\n# Output minimizer\n\n- Bash stdout/stderr may be rewritten before you see it: long output keeps only the last 1 KiB by default to reduce noise and input-token use. Explicit `tools.artifactTailBytes` / `tools.artifactHeadBytes` settings can set the tail budget or retain both ends. Prefer focused commands and dedicated `search`/`find` tools over producing broad output. Test/lint runners (e.g. `bun test`, `cargo test`, ESLint) are also passed through heuristic filters that drop noise and keep failures.\n- When the local minimizer changes visible text, successful artifact storage appends a footer containing an `artifact://<id>` reference. Complete artifacts are labeled as full output; hard-capped artifacts report omitted bytes instead. If artifact allocation/storage is unavailable before a writer/save operation is attempted, truncation may have no reference or diagnostic. If an artifact writer/save operation is attempted and fails, a bounded diagnostic is emitted without inventing an artifact URI.\n- ACP/client-terminal output can arrive already truncated from the beginning. Treat any truncation notice or metadata as evidence that the visible tail is incomplete. Recover omitted output only when an `artifact://` footer or metadata reference is present; truncation evidence without a reference means the visible output is incomplete and no artifact is recoverable. Output with neither truncation evidence nor an artifact reference is the complete emitted output.",
|
|
61
|
+
"description": "Executes bash command in shell session for terminal operations like git, bun, cargo, python.\n\n<instruction>\n- Use `cwd` to set working directory, not `cd dir && …`\n- Prefer `env: { NAME: \"…\" }` for multiline, quote-heavy, or untrusted values; reference as `$NAME`\n- Quote variable expansions like `\"$NAME\"` to preserve exact content\n- PTY mode is opt-in: set `pty: true` only when the command needs a real terminal (e.g. `sudo`, `ssh` requiring user input); default is `false`\n- Use `;` only when later commands should run regardless of earlier failures\n- Internal URIs (`agent://`, `artifact://`, `rule://`, `local://`) are auto-resolved to filesystem paths\n</instruction>\n\n<critical>\n- Use bash only for terminal operations that dedicated tools do not cover.\n- Never pipe through `| head -n N` or `| tail -n N` — output is already truncated. Recover omitted output only when the result includes an `artifact://<id>` footer or metadata reference; truncation without a reference leaves the visible output incomplete with no recoverable artifact.\n- Never redirect with `2>&1` or `2>/dev/null` — stdout and stderr are already merged.\n</critical>\n\n<output>\n- Returns output and exit code.\n- Truncated output is recoverable only when the result includes an `artifact://<id>` footer or metadata reference; truncation evidence without such a reference means the visible output is incomplete and no artifact is recoverable.\n- Exit codes shown on non-zero exit\n</output>\n\n# Waiting for background work\n\n- A long blocking `sleep N` (or `sleep N && …`) emits nothing for the entire duration and is indistinguishable from a hung session. Never use it to wait for subagents or background jobs.\n- To wait for detached task subagents, use `subagent await` — it emits periodic liveness while waiting.\n- To wait for background bash jobs, use `job poll` — it reports status on each tick.\n- Short sleeps for rate-limiting or pacing (e.g. `sleep 2` between retries) are fine.\n\n# Output minimizer\n\n- Bash stdout/stderr may be rewritten before you see it: long output keeps only the last 1 KiB by default to reduce noise and input-token use. Explicit `tools.artifactTailBytes` / `tools.artifactHeadBytes` settings can set the tail budget or retain both ends. Prefer focused commands and dedicated `search`/`find` tools over producing broad output. Test/lint runners (e.g. `bun test`, `cargo test`, ESLint) are also passed through heuristic filters that drop noise and keep failures.\n- When the local minimizer changes visible text, successful artifact storage appends a footer containing an `artifact://<id>` reference. Complete artifacts are labeled as full output; hard-capped artifacts report omitted bytes instead. If artifact allocation/storage is unavailable before a writer/save operation is attempted, truncation may have no reference or diagnostic. If an artifact writer/save operation is attempted and fails, a bounded diagnostic is emitted without inventing an artifact URI.\n- ACP/client-terminal output can arrive already truncated from the beginning. Treat any truncation notice or metadata as evidence that the visible tail is incomplete. Recover omitted output only when an `artifact://` footer or metadata reference is present; truncation evidence without a reference means the visible output is incomplete and no artifact is recoverable. Output with neither truncation evidence nor an artifact reference is the complete emitted output.",
|
|
62
62
|
"parameters": {
|
|
63
63
|
"type": "object",
|
|
64
64
|
"properties": {
|
|
@@ -1073,7 +1073,7 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
1073
1073
|
"browser": {
|
|
1074
1074
|
"name": "browser",
|
|
1075
1075
|
"label": "Browser",
|
|
1076
|
-
"description": "Drives a real Chromium tab with full puppeteer access via JS execution.\n\n<instruction>\n- For static web content (articles, docs, issues/PRs, JSON, PDFs, feeds), prefer the `read` tool with a URL. Use this tool only when you need JS execution, authentication, or interactive actions.\n- Four actions:\n - `open` — acquire (or reuse) a named tab. `name` defaults to `\"main\"`. Optional `url`, `viewport`, and `dialogs: \"accept\" | \"dismiss\"` (auto-handles `alert`/`confirm`/`beforeunload`). The `app` field selects the browser kind (spawned binary, saved Chrome profile, or existing CDP endpoint); omitted means headless Chromium with stealth patches.\n - `close` — release a tab by `name`, or every tab with `all: true`. `kill: true` also terminates a spawned-app process tree.\n - `act` — run a list of structured `actions` against an existing tab without writing JS (preferred for routine navigation/interaction). Each step is `{ verb, … }`; verbs: `navigate {url, wait_until?}`, `click {id|selector}`, `type {id|selector, text}`, `fill {selector, value}`, `select {selector, values}`, `press {key, selector?}`, `scroll {dx?, dy?}`, `back`, `wait {selector?|ms?}`, `observe {viewport_only?, include_all?}`, `extract {format?}`, `screenshot`. Address elements by the numeric `id` from a prior `observe` (preferred) or a selector. Steps run in order; the tool returns per-step results.\n - `run` — execute JS against an existing tab. `code` is the body of an async function with `page`, `browser`, `tab`, `display`, `assert`, `wait` in scope. The return value is JSON-stringified into the tool result; `display(value)` calls accumulate text/images. Use `run` only when an `act` verb does not cover what you need.\n- Tabs survive across `run` calls and across in-process subagents. Open once, reuse many times.\n- Browser kinds: no `app` launches headless Chromium; `app.path` reuses CDP or kills stale same-path processes before spawning — NEVER use it for a daily Chrome profile; use explicit `app.browser: \"chrome\"` profile mode instead. Saved-profile/CDP automation has access to that profile's cookies and authenticated accounts. Profile mode refuses a matching non-CDP Chrome instead of killing/relaunching it, and `kill: true` can terminate only a Chrome process GJC launched; `app.cdp_url` is externally owned and disconnect-only. CDP must stay on `127.0.0.1`: it grants full browser-account access.\n- Inside `run`, `tab` exposes high-level helpers (`goto`, `observe`, `id`, `click`, `type`, `fill`, `press`, `waitFor`, `screenshot`, `extract`, …); reach for `page` (raw puppeteer Page) when they don't cover it.\n- Selectors accept CSS as well as puppeteer query handlers: `aria/Sign in`, `text/Continue`, `xpath/…`, `pierce/…`.\n- Runtime diagnostics are opt-in: pass `diagnostics: true` to `open` to subscribe the tab to page `Runtime.exceptionThrown` and `console.error` events. The next successful `act`/`run` response then includes at most 20 `runtimeDiagnostics` entries plus `runtimeDiagnosticsDropped`, then drains them. Entries contain only kind, time, origin-only URL, line/column, and a built-in error class from a fixed allowlist — never path segments, query strings, messages, console arguments, values, or stacks. Output is byte-bounded and marks truncation explicitly.\n- Full reference — helpers, browser kinds, CDP/security details, and more examples — read `gjc://tools/browser.md`.\n</instruction>\n\n<critical>\n- You MUST call `open` before `run` or `act`. Neither implicitly creates a tab.\n- You MUST observe before taking a screenshot to understand page state; screenshot only when visual appearance matters.\n- After a `tab.goto()` or any navigation, prior element ids from `tab.observe()` are invalidated. Re-observe before referencing them.\n- `code` runs with full Node access. Treat it as your code, not sandboxed code.\n</critical>\n\n<examples>\n# Open a tab and read structured page data\n`{\"action\":\"open\",\"name\":\"docs\",\"url\":\"https://example.com\"}`\n`{\"action\":\"act\",\"name\":\"docs\",\"actions\":[{\"verb\":\"observe\"}]}`\n\n# Click an observed element, then fill and submit a form\n`{\"action\":\"act\",\"name\":\"docs\",\"actions\":[{\"verb\":\"click\",\"id\":12},{\"verb\":\"fill\",\"selector\":\"input[name=email]\",\"value\":\"me@example.com\"},{\"verb\":\"click\",\"selector\":\"text/Continue\"}]}`\n\n# Use `run` only when `act` has no suitable verb\n`{\"action\":\"run\",\"name\":\"docs\",\"code\":\"const count = await page.locator('canvas').count(); return { count };\"}`\n</examples>\n\n<output>\n- Per call: any `display(value)` outputs (text/images) followed by the JSON-stringified return value of the `code` function. `run` always produces at least a status line.\n</output>",
|
|
1076
|
+
"description": "Drives a real Chromium tab with full puppeteer access via JS execution.\n\n<instruction>\n- For static web content (articles, docs, issues/PRs, JSON, PDFs, feeds), prefer the `read` tool with a URL. Use this tool only when you need JS execution, authentication, or interactive actions.\n- Four actions:\n - `open` — acquire (or reuse) a named tab. `name` defaults to `\"main\"`. Optional `url`, `viewport`, and `dialogs: \"accept\" | \"dismiss\"` (auto-handles `alert`/`confirm`/`beforeunload`). The `app` field selects the browser kind (spawned binary, saved Chrome profile, or existing CDP endpoint); omitted means headless Chromium with stealth patches.\n - `close` — release a tab by `name`, or every tab with `all: true`. `kill: true` also terminates a spawned-app process tree.\n - `act` — run a list of structured `actions` against an existing tab without writing JS (preferred for routine navigation/interaction). Each step is `{ verb, … }`; verbs: `navigate {url, wait_until?}`, `click {id|selector}`, `type {id|selector, text}`, `fill {selector, value}`, `select {selector, values}`, `press {key, selector?}`, `scroll {dx?, dy?}`, `back`, `wait {selector?|ms?}`, `observe {viewport_only?, include_all?}`, `extract {format?}`, `screenshot`. Address elements by the numeric `id` from a prior `observe` (preferred) or a selector. Steps run in order; the tool returns per-step results.\n - `run` — execute JS against an existing tab. `code` is the body of an async function with `page`, `browser`, `tab`, `display`, `assert`, `wait` in scope. The return value is JSON-stringified into the tool result; `display(value)` calls accumulate text/images. Use `run` only when an `act` verb does not cover what you need.\n- Tabs survive across `run` calls and across in-process subagents. Open once, reuse many times.\n- Browser kinds: no `app` launches headless Chromium; `app.path` reuses CDP or kills stale same-path processes before spawning — NEVER use it for a daily Chrome profile; use explicit `app.browser: \"chrome\"` profile mode instead. In profile mode, `path` defaults to installed Chrome/Chromium and `profile_directory` defaults to `\"Default\"`, but `user_data_dir` must name a separate non-default Chrome data directory: Chrome 136+ disables remote debugging for its default data directory. Only Chrome/Chromium executables are admitted; Edge, Brave, Vivaldi, Opera, unknown browser brands, and default Chrome data roots are rejected. Use `app.cdp_url` to attach to an already-authorized browser. Saved-profile/CDP automation has access to that profile's cookies and authenticated accounts. Profile mode refuses a matching non-CDP Chrome instead of killing/relaunching it, and `kill: true` can terminate only a Chrome process GJC launched; `app.cdp_url` is externally owned and disconnect-only. CDP must stay on `127.0.0.1`: it grants full browser-account access.\n- Inside `run`, `tab` exposes high-level helpers (`goto`, `observe`, `id`, `click`, `type`, `fill`, `press`, `waitFor`, `screenshot`, `extract`, …); reach for `page` (raw puppeteer Page) when they don't cover it.\n- Selectors accept CSS as well as puppeteer query handlers: `aria/Sign in`, `text/Continue`, `xpath/…`, `pierce/…`.\n- Runtime diagnostics are opt-in: pass `diagnostics: true` to `open` to subscribe the tab to page `Runtime.exceptionThrown` and `console.error` events. The next successful `act`/`run` response then includes at most 20 `runtimeDiagnostics` entries plus `runtimeDiagnosticsDropped`, then drains them. Entries contain only kind, time, origin-only URL, line/column, and a built-in error class from a fixed allowlist — never path segments, query strings, messages, console arguments, values, or stacks. Output is byte-bounded and marks truncation explicitly.\n- Full reference — helpers, browser kinds, CDP/security details, and more examples — read `gjc://tools/browser.md`.\n</instruction>\n\n<critical>\n- You MUST call `open` before `run` or `act`. Neither implicitly creates a tab.\n- You MUST observe before taking a screenshot to understand page state; screenshot only when visual appearance matters.\n- After a `tab.goto()` or any navigation, prior element ids from `tab.observe()` are invalidated. Re-observe before referencing them.\n- `code` runs with full Node access. Treat it as your code, not sandboxed code.\n</critical>\n\n<examples>\n# Open a tab and read structured page data\n`{\"action\":\"open\",\"name\":\"docs\",\"url\":\"https://example.com\"}`\n`{\"action\":\"act\",\"name\":\"docs\",\"actions\":[{\"verb\":\"observe\"}]}`\n\n# Click an observed element, then fill and submit a form\n`{\"action\":\"act\",\"name\":\"docs\",\"actions\":[{\"verb\":\"click\",\"id\":12},{\"verb\":\"fill\",\"selector\":\"input[name=email]\",\"value\":\"me@example.com\"},{\"verb\":\"click\",\"selector\":\"text/Continue\"}]}`\n\n# Use `run` only when `act` has no suitable verb\n`{\"action\":\"run\",\"name\":\"docs\",\"code\":\"const count = await page.locator('canvas').count(); return { count };\"}`\n</examples>\n\n<output>\n- Per call: any `display(value)` outputs (text/images) followed by the JSON-stringified return value of the `code` function. `run` always produces at least a status line.\n</output>",
|
|
1077
1077
|
"parameters": {
|
|
1078
1078
|
"type": "object",
|
|
1079
1079
|
"properties": {
|
|
@@ -1100,7 +1100,7 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
1100
1100
|
"properties": {
|
|
1101
1101
|
"path": {
|
|
1102
1102
|
"type": "string",
|
|
1103
|
-
"description": "binary path to spawn"
|
|
1103
|
+
"description": "binary path to spawn (default: the installed Chrome/Chromium)"
|
|
1104
1104
|
},
|
|
1105
1105
|
"cdp_url": {
|
|
1106
1106
|
"type": "string",
|
|
@@ -1115,11 +1115,11 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
1115
1115
|
},
|
|
1116
1116
|
"user_data_dir": {
|
|
1117
1117
|
"type": "string",
|
|
1118
|
-
"description": "Chrome user data directory containing profiles"
|
|
1118
|
+
"description": "non-default Chrome user data directory containing profiles (required for Chrome 136+ CDP)"
|
|
1119
1119
|
},
|
|
1120
1120
|
"profile_directory": {
|
|
1121
1121
|
"type": "string",
|
|
1122
|
-
"description": "Chrome profile directory name, e.g. Profile 10"
|
|
1122
|
+
"description": "Chrome profile directory name, e.g. \"Profile 10\" (default \"Default\")"
|
|
1123
1123
|
},
|
|
1124
1124
|
"background": {
|
|
1125
1125
|
"type": "boolean",
|
|
@@ -2708,7 +2708,7 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
2708
2708
|
"skill_discovery": {
|
|
2709
2709
|
"name": "skill_discovery",
|
|
2710
2710
|
"label": "SkillDiscovery",
|
|
2711
|
-
"description": "Discover project and user runtime skills without loading full skill content.\n\n<instruction>\n- Searches
|
|
2711
|
+
"description": "Discover project and user runtime skills without loading full skill content.\n\n<instruction>\n- Searches canonical GJC skill locations in precedence order: project `.gjc/skills` (ancestors from cwd to repo root, closest first), then user locations under the home directory: canonical `<config>/agent/skills`, configured legacy `<config>/skills`, and historical legacy `.gjc/skills`. `<config>` is the home-relative directory name from `GJC_CONFIG_DIR`, then `PI_CONFIG_DIR`, then `.gjc`; even an absolute-looking configured name is joined beneath `<home>`. Project scope shadows user scope; within a scope, earlier locations above win. Bundled GJC workflow skills (`deep-interview`, `ralplan`, `team`, `ultragoal`) are always available and cannot be replaced by filesystem skills.\n- Returns thin metadata only: name, description, source scope, path, and use conditions when present.\n- Claude Code (`.claude/skills`) and Codex (`.codex/skills`) layouts are explicit import sources into `.gjc`, never invokable candidates. They are not returned as candidates; instead, each convention skill found in a trusted scope is reported in `diagnostics` with the exact copy command that enables it (copy into `.gjc/skills`), so a skill placed in a documented convention location is discoverable in a normal session without being silently loaded.\n- Discovery is on by default in a normal session. When zero candidates are returned because discovery config is disabled (`skills.enabled` master switch, or `skills.trustProjectSkills` / `skills.trustUserSkills` scope trust), the result carries a `notice` explaining which setting blocked the search — an empty result without a `notice` means the searched scopes genuinely contain no matching skills.\n- When skills were scanned but not advertised (protected-name collision with a bundled workflow skill, include/ignore/disable policy filters, invalid frontmatter, shadowing), the result carries a bounded `diagnostics` list explaining why.\n- To load a selected skill's full `SKILL.md`, invoke it through the existing `skill` tool with the exact `name` returned here.\n</instruction>\n\nInput:\n- `query` (optional): words to match against skill name, description, source, or use conditions.\n- `source` (optional): `all`, `project`, or `user`.\n- `limit` (optional): maximum results, 1-50.",
|
|
2712
2712
|
"parameters": {
|
|
2713
2713
|
"type": "object",
|
|
2714
2714
|
"properties": {
|
|
@@ -41,7 +41,11 @@ export function formatUltragoalAskBlockMessage(diagnostic: UltragoalAskBlockDiag
|
|
|
41
41
|
].join("\n");
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export async function assertUltragoalAskAllowed(
|
|
44
|
+
export async function assertUltragoalAskAllowed(
|
|
45
|
+
cwd: string,
|
|
46
|
+
context: UltragoalAskGuardContext = {},
|
|
47
|
+
agentDir?: string,
|
|
48
|
+
): Promise<void> {
|
|
45
49
|
const activeSkill = normalizedActiveSkill(context);
|
|
46
50
|
// Deep-interview and ralplan are upstream planning workflows whose core gates
|
|
47
51
|
// are `ask` calls. Scope their Ultragoal check to the current session so stale
|
|
@@ -51,7 +55,7 @@ export async function assertUltragoalAskAllowed(cwd: string, context: UltragoalA
|
|
|
51
55
|
const sessionId = sessionScopedAskGuardId(context, activeSkill);
|
|
52
56
|
const diagnostic = await isUltragoalAskBlocked(cwd, { sessionId });
|
|
53
57
|
if (!diagnostic.active) return;
|
|
54
|
-
const nudge = await consumeUltragoalAskNudge(cwd, sessionId);
|
|
58
|
+
const nudge = await consumeUltragoalAskNudge(cwd, sessionId, agentDir);
|
|
55
59
|
if (nudge.nudged) throw new ToolError(nudge.message);
|
|
56
60
|
throw new ToolError(formatUltragoalAskBlockMessage(diagnostic));
|
|
57
61
|
}
|
|
@@ -60,6 +64,7 @@ export function guardToolForUltragoalAsk<T extends AgentTool>(
|
|
|
60
64
|
tool: T,
|
|
61
65
|
getCwd: () => string,
|
|
62
66
|
getContext: () => UltragoalAskGuardContext = () => ({}),
|
|
67
|
+
getSessionAgentDir: () => string | undefined = () => undefined,
|
|
63
68
|
): T {
|
|
64
69
|
if (tool.name !== "ask") return tool;
|
|
65
70
|
const candidate = tool as GuardedTool;
|
|
@@ -69,7 +74,9 @@ export function guardToolForUltragoalAsk<T extends AgentTool>(
|
|
|
69
74
|
if (prop === ULTRAGOAL_ASK_GUARD) return true;
|
|
70
75
|
if (prop !== "execute") return Reflect.get(target, prop, receiver);
|
|
71
76
|
return async (...args: unknown[]): Promise<unknown> => {
|
|
72
|
-
|
|
77
|
+
// The wrapper runs BEFORE AskTool.execute(): resolve the nudge
|
|
78
|
+
// budget against the SESSION profile, never the process-global one.
|
|
79
|
+
await assertUltragoalAskAllowed(getCwd(), getContext(), getSessionAgentDir());
|
|
73
80
|
return Reflect.apply(target.execute, target, args);
|
|
74
81
|
};
|
|
75
82
|
},
|