@gajae-code/coding-agent 0.11.1 → 0.11.3
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 +64 -0
- package/dist/types/cli/config-cli.d.ts +11 -1
- package/dist/types/cli/launch-disposition.d.ts +23 -0
- package/dist/types/cli/notify-cli.d.ts +1 -0
- package/dist/types/cli/session-picker.d.ts +2 -1
- package/dist/types/cli/setup-cli.d.ts +1 -1
- package/dist/types/commands/mcp-serve.d.ts +33 -0
- package/dist/types/commands/mcp.d.ts +1 -1
- package/dist/types/commands/notify.d.ts +0 -2
- package/dist/types/commands/sdk.d.ts +1 -1
- package/dist/types/config/atomic-yaml-patch.d.ts +18 -0
- package/dist/types/config/file-lock.d.ts +14 -4
- package/dist/types/config/keybindings.d.ts +42 -1
- package/dist/types/config/model-auth.d.ts +3 -0
- package/dist/types/config/model-bindings-applier.d.ts +13 -0
- package/dist/types/config/model-discovery-manager.d.ts +49 -0
- package/dist/types/config/model-equivalence.d.ts +20 -0
- package/dist/types/config/model-registry.d.ts +16 -15
- package/dist/types/config/model-resolver.d.ts +28 -18
- package/dist/types/config/models-config-schema.d.ts +11 -0
- package/dist/types/config/settings-schema.d.ts +141 -11
- package/dist/types/config/settings.d.ts +14 -11
- package/dist/types/coordinator-mcp/policy.d.ts +5 -0
- package/dist/types/coordinator-mcp/question-gate-codec.d.ts +129 -0
- package/dist/types/coordinator-mcp/question-state.d.ts +356 -0
- package/dist/types/coordinator-mcp/server.d.ts +4 -0
- package/dist/types/discovery/helpers.d.ts +0 -6
- package/dist/types/edit/index.d.ts +3 -0
- package/dist/types/eval/py/env.d.ts +9 -0
- package/dist/types/extensibility/extensions/loader.d.ts +2 -1
- package/dist/types/extensibility/extensions/runner.d.ts +2 -2
- package/dist/types/extensibility/extensions/types.d.ts +34 -3
- package/dist/types/extensibility/hooks/runner.d.ts +1 -1
- package/dist/types/extensibility/shared-events.d.ts +2 -0
- package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +10 -1
- package/dist/types/gjc-runtime/deep-interview-state.d.ts +44 -0
- package/dist/types/gjc-runtime/goal-mode-request.d.ts +11 -1
- package/dist/types/gjc-runtime/launch-worktree.d.ts +4 -2
- package/dist/types/gjc-runtime/linux-proc.d.ts +29 -0
- package/dist/types/gjc-runtime/session-resolution.d.ts +2 -2
- package/dist/types/gjc-runtime/state-migrations.d.ts +1 -1
- package/dist/types/gjc-runtime/state-writer.d.ts +2 -1
- package/dist/types/gjc-runtime/team-launch.d.ts +59 -0
- package/dist/types/gjc-runtime/team-notify.d.ts +45 -0
- package/dist/types/gjc-runtime/team-runtime.d.ts +29 -121
- package/dist/types/gjc-runtime/team-store.d.ts +160 -0
- package/dist/types/gjc-runtime/team-workers.d.ts +78 -0
- package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +8 -0
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +13 -0
- package/dist/types/gjc-runtime/ultragoal-evidence.d.ts +38 -0
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +7 -0
- package/dist/types/gjc-runtime/ultragoal-pipeline.d.ts +23 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +55 -33
- package/dist/types/gjc-runtime/workflow-cli-common.d.ts +8 -0
- package/dist/types/gjc-runtime/workflow-manifest.d.ts +3 -0
- package/dist/types/goals/continuation-timeout-guard.d.ts +22 -0
- package/dist/types/goals/runtime.d.ts +1 -0
- package/dist/types/goals/state.d.ts +8 -0
- package/dist/types/harness-control-plane/lifecycle-reconciliation.d.ts +17 -0
- package/dist/types/harness-control-plane/phase-rollup.d.ts +4 -7
- package/dist/types/harness-control-plane/receipt-ingest.d.ts +5 -0
- package/dist/types/harness-control-plane/receipt-spool.d.ts +4 -0
- package/dist/types/hindsight/state.d.ts +11 -4
- package/dist/types/lsp/lspmux.d.ts +5 -3
- package/dist/types/lsp/path-trust.d.ts +1 -0
- package/dist/types/main.d.ts +4 -2
- package/dist/types/memories/storage.d.ts +1 -0
- package/dist/types/modes/action-registry.d.ts +29 -0
- package/dist/types/modes/components/chrome.d.ts +14 -0
- package/dist/types/modes/components/command-palette.d.ts +27 -0
- package/dist/types/modes/components/custom-provider-wizard.d.ts +1 -0
- package/dist/types/modes/components/index.d.ts +2 -1
- package/dist/types/modes/components/pet-selector.d.ts +1 -1
- package/dist/types/modes/components/plan-preview-overlay.d.ts +43 -0
- package/dist/types/modes/components/queue-mode-selector.d.ts +1 -1
- package/dist/types/modes/components/queue-pane.d.ts +12 -0
- package/dist/types/modes/components/read-tool-group.d.ts +6 -0
- package/dist/types/modes/components/session-observer-overlay.d.ts +3 -4
- package/dist/types/modes/components/sessions-dashboard.d.ts +32 -0
- package/dist/types/modes/components/settings-selector.d.ts +1 -1
- package/dist/types/modes/components/show-images-selector.d.ts +1 -1
- package/dist/types/modes/components/status-line/types.d.ts +1 -1
- package/dist/types/modes/components/status-line.d.ts +1 -94
- package/dist/types/modes/components/tasks-pane.d.ts +15 -0
- package/dist/types/modes/components/theme-selector.d.ts +1 -1
- package/dist/types/modes/components/tool-execution.d.ts +15 -0
- package/dist/types/modes/components/tool-status-header.d.ts +111 -0
- package/dist/types/modes/components/transcript-viewer-overlay.d.ts +42 -0
- package/dist/types/modes/controllers/goal-mode-controller.d.ts +62 -0
- package/dist/types/modes/controllers/input-controller.d.ts +8 -1
- package/dist/types/modes/controllers/mode-gate.d.ts +8 -0
- package/dist/types/modes/controllers/plan-mode-controller.d.ts +65 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +15 -3
- package/dist/types/modes/controllers/stt-controller.d.ts +26 -0
- package/dist/types/modes/interactive-mode.d.ts +19 -17
- package/dist/types/modes/jobs-observer.d.ts +2 -0
- package/dist/types/modes/prompt-action-autocomplete.d.ts +4 -0
- package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -11
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +20 -2
- package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +31 -0
- package/dist/types/modes/tasks-aggregator.d.ts +39 -0
- package/dist/types/modes/transcript-item-registry.d.ts +60 -0
- package/dist/types/modes/types.d.ts +20 -13
- package/dist/types/modes/utils/ui-helpers.d.ts +2 -2
- package/dist/types/runtime-mcp/manager.d.ts +1 -1
- package/dist/types/sdk/broker/broker.d.ts +78 -12
- package/dist/types/sdk/broker/lifecycle-codec.d.ts +4 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +15 -1
- package/dist/types/sdk/broker/lifecycle.d.ts +6 -2
- package/dist/types/sdk/broker/process-incarnation.d.ts +2 -0
- package/dist/types/sdk/broker/session-index.d.ts +0 -1
- package/dist/types/sdk/broker/state-version.d.ts +2 -0
- package/dist/types/sdk/bus/chat-effect-journal.d.ts +1 -0
- package/dist/types/sdk/bus/config-commands.d.ts +1 -1
- package/dist/types/sdk/bus/config.d.ts +11 -0
- package/dist/types/sdk/bus/daemon-paths.d.ts +1 -0
- package/dist/types/sdk/bus/html-format.d.ts +3 -2
- package/dist/types/sdk/bus/index.d.ts +29 -0
- package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +4 -0
- package/dist/types/sdk/bus/notification-service.d.ts +20 -0
- package/dist/types/sdk/bus/rate-limit-pool.d.ts +13 -2
- package/dist/types/sdk/bus/recent-activity.d.ts +21 -12
- package/dist/types/sdk/bus/rich-document.d.ts +7 -0
- package/dist/types/sdk/bus/rich-render.d.ts +18 -41
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +9 -4
- package/dist/types/sdk/bus/telegram-daemon.d.ts +46 -3
- package/dist/types/sdk/bus/threaded-inbound.d.ts +1 -1
- package/dist/types/sdk/bus/threaded-render.d.ts +13 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +24 -2
- package/dist/types/sdk/host/control/operations.d.ts +1 -1
- package/dist/types/sdk/host/host.d.ts +2 -0
- package/dist/types/sdk/index.d.ts +1 -0
- package/dist/types/sdk/session-directory.d.ts +56 -0
- package/dist/types/sdk/session.d.ts +2 -0
- package/dist/types/session/agent-session.d.ts +82 -47
- package/dist/types/session/agent-storage.d.ts +7 -0
- package/dist/types/session/fallback-chain-controller.d.ts +10 -2
- package/dist/types/session/internal/managed-session-scope.d.ts +102 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +38 -0
- package/dist/types/session/messages.d.ts +16 -0
- package/dist/types/session/session-manager-internal.d.ts +14 -0
- package/dist/types/session/session-manager.d.ts +82 -12
- package/dist/types/session/session-storage.d.ts +43 -3
- package/dist/types/session/volatile-context-pruning.d.ts +15 -0
- package/dist/types/skill-state/{deep-interview-mutation-guard.d.ts → workflow-mutation-guard.d.ts} +24 -8
- package/dist/types/skill-state/workflow-state-contract.d.ts +1 -3
- package/dist/types/slash-commands/builtin-registry.d.ts +4 -1
- package/dist/types/system-prompt.d.ts +2 -11
- package/dist/types/task/executor.d.ts +3 -1
- package/dist/types/thinking.d.ts +7 -0
- package/dist/types/tool-discovery/tool-index.d.ts +1 -50
- package/dist/types/tools/ask.d.ts +64 -2
- package/dist/types/tools/bash.d.ts +3 -0
- package/dist/types/tools/browser/dead-tab-recovery.d.ts +24 -0
- package/dist/types/tools/browser/tab-supervisor.d.ts +21 -0
- package/dist/types/tools/cron.d.ts +2 -0
- package/dist/types/tools/fetch.d.ts +1 -0
- package/dist/types/tools/index.d.ts +30 -15
- package/dist/types/tools/output-meta.d.ts +1 -0
- package/dist/types/tools/read.d.ts +5 -0
- package/dist/types/tools/search-tool-bm25.d.ts +3 -4
- package/dist/types/tools/subagent.d.ts +1 -0
- package/dist/types/utils/event-bus.d.ts +1 -1
- package/dist/types/utils/file-mentions.d.ts +3 -3
- package/dist/types/web/search/index.d.ts +3 -1
- package/package.json +21 -9
- package/scripts/build-sdk-package-smoke.ts +34 -1
- package/scripts/generate-hotkeys-docs.ts +74 -0
- package/scripts/generate-sdk-operation-inventory.ts +64 -20
- package/scripts/verify-gjc-sdk-canonicalization.ts +182 -2
- package/src/async/job-manager.ts +49 -6
- package/src/cli/config-cli.ts +75 -2
- package/src/cli/launch-disposition.ts +42 -0
- package/src/cli/notify-cli.ts +92 -26
- package/src/cli/session-picker.ts +20 -3
- package/src/cli/setup-cli.ts +1 -1
- package/src/cli.ts +1 -1
- package/src/commands/config.ts +1 -1
- package/src/commands/harness.ts +34 -106
- package/src/commands/launch.ts +6 -4
- package/src/commands/mcp-serve.ts +85 -8
- package/src/commands/mcp.ts +2 -2
- package/src/commands/notify.ts +8 -4
- package/src/commands/sdk.ts +61 -40
- package/src/commands/ultragoal.ts +4 -1
- package/src/config/atomic-yaml-patch.ts +80 -13
- package/src/config/file-lock.ts +105 -43
- package/src/config/keybindings.ts +64 -20
- package/src/config/model-auth.ts +9 -0
- package/src/config/model-bindings-applier.ts +139 -0
- package/src/config/model-discovery-manager.ts +224 -0
- package/src/config/model-equivalence.ts +66 -0
- package/src/config/model-registry.ts +169 -302
- package/src/config/model-resolver.ts +361 -369
- package/src/config/models-config-schema.ts +5 -4
- package/src/config/settings-schema.ts +214 -12
- package/src/config/settings.ts +458 -482
- package/src/coordinator-mcp/policy.ts +76 -11
- package/src/coordinator-mcp/question-gate-codec.ts +274 -0
- package/src/coordinator-mcp/question-state.ts +778 -0
- package/src/coordinator-mcp/server.ts +1702 -238
- package/src/debug/index.ts +1 -1
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +13 -1
- package/src/defaults/gjc/skills/team/SKILL.md +16 -0
- package/src/discovery/helpers.ts +1 -50
- package/src/edit/index.ts +64 -0
- package/src/eval/py/env.ts +26 -0
- package/src/eval/py/kernel.ts +5 -3
- package/src/extensibility/extensions/loader.ts +9 -1
- package/src/extensibility/extensions/runner.ts +12 -3
- package/src/extensibility/extensions/types.ts +39 -1
- package/src/extensibility/gjc-plugins/installer.ts +16 -16
- package/src/extensibility/hooks/runner.ts +2 -2
- package/src/extensibility/runtime-skill-discovery.ts +33 -13
- package/src/extensibility/shared-events.ts +2 -0
- package/src/gjc-runtime/deep-interview-recorder.ts +63 -3
- package/src/gjc-runtime/deep-interview-runtime.ts +76 -27
- package/src/gjc-runtime/deep-interview-state.ts +317 -5
- package/src/gjc-runtime/goal-mode-request.ts +55 -8
- package/src/gjc-runtime/launch-tmux.ts +2 -5
- package/src/gjc-runtime/launch-worktree.ts +5 -5
- package/src/gjc-runtime/linux-proc.ts +71 -0
- package/src/gjc-runtime/ralplan-runtime.ts +74 -90
- package/src/gjc-runtime/session-resolution.ts +18 -3
- package/src/gjc-runtime/session-state-sidecar.ts +6 -107
- package/src/gjc-runtime/state-migrations.ts +1 -1
- package/src/gjc-runtime/state-runtime.ts +327 -249
- package/src/gjc-runtime/state-writer.ts +36 -40
- package/src/gjc-runtime/team-launch.ts +319 -0
- package/src/gjc-runtime/team-notify.ts +326 -0
- package/src/gjc-runtime/team-runtime.ts +1099 -1482
- package/src/gjc-runtime/team-store.ts +828 -0
- package/src/gjc-runtime/team-workers.ts +962 -0
- package/src/gjc-runtime/tmux-owner-isolation-cli.ts +2 -11
- package/src/gjc-runtime/tmux-owner-isolation.ts +14 -9
- package/src/gjc-runtime/tmux-sessions.ts +4 -21
- package/src/gjc-runtime/ultragoal-change-set.ts +172 -0
- package/src/gjc-runtime/ultragoal-evidence.ts +874 -0
- package/src/gjc-runtime/ultragoal-guard.ts +29 -5
- package/src/gjc-runtime/ultragoal-pipeline.ts +306 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +84 -1311
- package/src/gjc-runtime/workflow-cli-common.ts +30 -0
- package/src/gjc-runtime/workflow-manifest.generated.json +58 -0
- package/src/gjc-runtime/workflow-manifest.ts +18 -0
- package/src/goals/continuation-timeout-guard.ts +79 -0
- package/src/goals/runtime.ts +7 -5
- package/src/goals/state.ts +18 -0
- package/src/harness-control-plane/lifecycle-reconciliation.ts +64 -0
- package/src/harness-control-plane/phase-rollup.ts +4 -7
- package/src/harness-control-plane/receipt-ingest.ts +5 -0
- package/src/harness-control-plane/receipt-spool.ts +51 -7
- package/src/harness-control-plane/session-lease.ts +12 -130
- package/src/hindsight/backend.ts +26 -27
- package/src/hindsight/state.ts +101 -32
- package/src/hooks/skill-state.ts +17 -11
- package/src/internal-urls/docs-index.generated.ts +21 -18
- package/src/lsp/client.ts +1 -1
- package/src/lsp/config.ts +145 -26
- package/src/lsp/index.ts +1 -1
- package/src/lsp/lspmux.ts +39 -10
- package/src/lsp/path-trust.ts +81 -0
- package/src/main.ts +127 -30
- package/src/memories/index.ts +1 -0
- package/src/memories/storage.ts +6 -2
- package/src/modes/action-registry.ts +165 -0
- package/src/modes/components/chrome.ts +40 -0
- package/src/modes/components/command-palette.ts +168 -0
- package/src/modes/components/custom-editor.ts +1 -1
- package/src/modes/components/custom-provider-wizard.ts +51 -14
- package/src/modes/components/index.ts +2 -1
- package/src/modes/components/pet-selector.ts +11 -17
- package/src/modes/components/plan-preview-overlay.ts +295 -0
- package/src/modes/components/queue-mode-selector.ts +10 -27
- package/src/modes/components/queue-pane.ts +79 -0
- package/src/modes/components/read-tool-group.ts +13 -0
- package/src/modes/components/session-observer-overlay.ts +207 -772
- package/src/modes/components/sessions-dashboard.ts +181 -0
- package/src/modes/components/settings-selector.ts +1 -1
- package/src/modes/components/show-images-selector.ts +10 -24
- package/src/modes/components/status-line/types.ts +1 -1
- package/src/modes/components/status-line.ts +1 -969
- package/src/modes/components/tasks-pane.ts +73 -0
- package/src/modes/components/theme-selector.ts +11 -31
- package/src/modes/components/tool-execution.ts +22 -0
- package/src/modes/components/tool-status-header.ts +1056 -0
- package/src/modes/components/transcript-viewer-overlay.ts +384 -0
- package/src/modes/controllers/btw-controller.ts +1 -0
- package/src/modes/controllers/event-controller.ts +3 -2
- package/src/modes/controllers/extension-ui-controller.ts +24 -1
- package/src/modes/controllers/goal-mode-controller.ts +474 -0
- package/src/modes/controllers/input-controller.ts +764 -229
- package/src/modes/controllers/mode-gate.ts +24 -0
- package/src/modes/controllers/plan-mode-controller.ts +517 -0
- package/src/modes/controllers/selector-controller.ts +225 -10
- package/src/modes/controllers/stt-controller.ts +125 -0
- package/src/modes/interactive-mode.ts +289 -1150
- package/src/modes/jobs-observer.ts +3 -0
- package/src/modes/prompt-action-autocomplete.ts +7 -0
- package/src/modes/runtime-init.ts +8 -0
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +31 -106
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +71 -16
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +177 -0
- package/src/modes/tasks-aggregator.ts +199 -0
- package/src/modes/transcript-item-registry.ts +229 -0
- package/src/modes/types.ts +45 -18
- package/src/modes/utils/ui-helpers.ts +17 -9
- package/src/prompts/agent-fragments/ralplan-persistence.md +6 -0
- package/src/prompts/agent-fragments/restricted-bash.md +1 -0
- package/src/prompts/agents/architect.md +2 -8
- package/src/prompts/agents/critic.md +2 -8
- package/src/prompts/agents/executor.md +3 -0
- package/src/prompts/agents/planner.md +4 -12
- package/src/prompts/system/custom-system-prompt.md +1 -23
- package/src/prompts/system/plan-mode-approved.md +8 -0
- package/src/prompts/system/system-prompt.md +17 -96
- package/src/prompts/tools/bash.md +4 -4
- package/src/prompts/tools/browser.md +15 -52
- package/src/prompts/tools/find.md +2 -2
- package/src/prompts/tools/hashline.md +13 -55
- package/src/prompts/tools/read.md +3 -6
- package/src/prompts/tools/search-tool-bm25.md +0 -2
- package/src/prompts/tools/search.md +2 -4
- package/src/prompts/tools/skill-discovery.md +1 -2
- package/src/prompts/tools/task.md +1 -1
- package/src/runtime-mcp/manager.ts +1 -1
- package/src/sdk/broker/broker.ts +206 -78
- package/src/sdk/broker/discovery.ts +1 -1
- package/src/sdk/broker/ensure.ts +3 -1
- package/src/sdk/broker/lifecycle-codec.ts +11 -0
- package/src/sdk/broker/lifecycle-ledger.ts +371 -74
- package/src/sdk/broker/lifecycle.ts +1399 -142
- package/src/sdk/broker/process-incarnation.ts +5 -13
- package/src/sdk/broker/session-index.ts +145 -56
- package/src/sdk/broker/state-version.ts +21 -0
- package/src/sdk/broker/transport.ts +1 -1
- package/src/sdk/bus/chat-daemon-cli.ts +2 -0
- package/src/sdk/bus/chat-daemon-control.ts +8 -28
- package/src/sdk/bus/chat-effect-journal.ts +10 -2
- package/src/sdk/bus/config-commands.ts +5 -4
- package/src/sdk/bus/config.ts +98 -0
- package/src/sdk/bus/conversation-store.ts +5 -29
- package/src/sdk/bus/daemon-paths.ts +2 -0
- package/src/sdk/bus/html-format.ts +20 -3
- package/src/sdk/bus/index.ts +782 -94
- package/src/sdk/bus/lifecycle-control-runtime.ts +91 -33
- package/src/sdk/bus/natives-augment.d.ts +26 -1
- package/src/sdk/bus/notification-service.ts +168 -20
- package/src/sdk/bus/rate-limit-pool.ts +58 -14
- package/src/sdk/bus/recent-activity.ts +188 -74
- package/src/sdk/bus/rich-document.ts +258 -0
- package/src/sdk/bus/rich-render.ts +62 -70
- package/src/sdk/bus/telegram-daemon-cli.ts +15 -59
- package/src/sdk/bus/telegram-daemon-contract.ts +9 -4
- package/src/sdk/bus/telegram-daemon.ts +1389 -237
- package/src/sdk/bus/threaded-inbound.ts +8 -3
- package/src/sdk/bus/threaded-render.ts +57 -1
- package/src/sdk/bus/topic-registry.ts +120 -13
- package/src/sdk/host/control/dispatch.ts +14 -2
- package/src/sdk/host/control/operations.ts +6 -1
- package/src/sdk/host/host.ts +44 -2
- package/src/sdk/host/query/handlers.ts +20 -22
- package/src/sdk/host/query/revision-store.ts +80 -57
- package/src/sdk/index.ts +1 -0
- package/src/sdk/protocol/operation-inventory.generated.json +943 -1907
- package/src/sdk/session-directory.ts +141 -0
- package/src/sdk/session.ts +462 -480
- package/src/session/agent-session.ts +1700 -583
- package/src/session/agent-storage.ts +18 -0
- package/src/session/cache-economics.ts +25 -8
- package/src/session/fallback-chain-controller.ts +53 -3
- package/src/session/internal/managed-session-scope.ts +2226 -0
- package/src/session/internal/managed-session-storage.ts +453 -0
- package/src/session/messages.ts +91 -2
- package/src/session/session-manager-internal.ts +33 -0
- package/src/session/session-manager.ts +1112 -333
- package/src/session/session-storage.ts +444 -39
- package/src/session/volatile-context-pruning.ts +78 -0
- package/src/setup/credential-auto-import.ts +2 -1
- package/src/setup/hermes/templates/operator-instructions.v1.md +1 -1
- package/src/setup/provider-onboarding.ts +36 -61
- package/src/setup/provider-presets.json +5 -0
- package/src/skill-state/active-state.ts +3 -13
- package/src/skill-state/{deep-interview-mutation-guard.ts → workflow-mutation-guard.ts} +47 -29
- package/src/skill-state/workflow-state-contract.ts +6 -41
- package/src/slash-commands/builtin-registry.ts +46 -11
- package/src/system-prompt.ts +37 -44
- package/src/task/agents.ts +19 -1
- package/src/task/executor.ts +90 -6
- package/src/task/index.ts +36 -21
- package/src/thinking.ts +21 -6
- package/src/tool-discovery/tool-index.ts +2 -134
- package/src/tools/ask.ts +157 -21
- package/src/tools/ast-edit.ts +1 -1
- package/src/tools/bash.ts +38 -0
- package/src/tools/browser/dead-tab-recovery.ts +78 -0
- package/src/tools/browser/tab-supervisor.ts +282 -36
- package/src/tools/computer.ts +10 -3
- package/src/tools/cron.ts +30 -16
- package/src/tools/eval.ts +1 -2
- package/src/tools/fetch.ts +11 -4
- package/src/tools/index.ts +76 -24
- package/src/tools/output-meta.ts +19 -7
- package/src/tools/read.ts +219 -64
- package/src/tools/resource-gc.ts +2 -2
- package/src/tools/search-tool-bm25.ts +11 -74
- package/src/tools/subagent.ts +43 -2
- package/src/utils/event-bus.ts +9 -4
- package/src/utils/file-mentions.ts +4 -4
- package/src/web/search/index.ts +3 -3
- package/dist/types/discovery/plugin-dir-roots.d.ts +0 -15
- package/dist/types/runtime-mcp/discoverable-tool-metadata.d.ts +0 -7
- package/src/discovery/plugin-dir-roots.ts +0 -28
- package/src/runtime-mcp/discoverable-tool-metadata.ts +0 -25
package/src/async/job-manager.ts
CHANGED
|
@@ -12,6 +12,7 @@ const DELIVERY_MAX_TEXT_BYTES = 64 * 1024;
|
|
|
12
12
|
const DELIVERY_PREVIEW_HEAD_BYTES = 32 * 1024;
|
|
13
13
|
const DELIVERY_PREVIEW_TAIL_BYTES = 32 * 1024;
|
|
14
14
|
const DELIVERY_MAX_ATTEMPTS = 3;
|
|
15
|
+
const MAX_DEAD_LETTERED_DELIVERIES = 50;
|
|
15
16
|
|
|
16
17
|
export interface AsyncJob {
|
|
17
18
|
id: string;
|
|
@@ -207,6 +208,12 @@ interface AsyncJobDelivery {
|
|
|
207
208
|
promise?: Promise<void>;
|
|
208
209
|
}
|
|
209
210
|
|
|
211
|
+
interface DeadLetteredDelivery {
|
|
212
|
+
jobId: string;
|
|
213
|
+
attempt: number;
|
|
214
|
+
lastError?: string;
|
|
215
|
+
}
|
|
216
|
+
|
|
210
217
|
export interface AsyncJobDeliveryState {
|
|
211
218
|
queued: number;
|
|
212
219
|
delivering: boolean;
|
|
@@ -381,7 +388,8 @@ export class AsyncJobManager {
|
|
|
381
388
|
* resume fails closed with reason "no_runner".
|
|
382
389
|
*/
|
|
383
390
|
readonly #descriptorResumeRunners = new Map<string, ResumeRunner>();
|
|
384
|
-
readonly #deadLetteredDeliveries = new Map<string,
|
|
391
|
+
readonly #deadLetteredDeliveries = new Map<string, DeadLetteredDelivery>();
|
|
392
|
+
readonly #deadLetteredDeliveryOwners = new Map<string, string | undefined>();
|
|
385
393
|
readonly #ownerSubagentShutdownLeases = new Map<string, OwnerSubagentShutdownLeaseState>();
|
|
386
394
|
#ownerSubagentShutdownSeq = 0;
|
|
387
395
|
#lastDisposeDiagnostics: AsyncJobDisposeDiagnostics = { stuckJobIds: [], deliveriesDrained: true };
|
|
@@ -1333,12 +1341,16 @@ export class AsyncJobManager {
|
|
|
1333
1341
|
}
|
|
1334
1342
|
|
|
1335
1343
|
getDeliveryState(filter?: AsyncJobFilter): AsyncJobDeliveryState {
|
|
1344
|
+
this.#expireMonitorTombstones();
|
|
1345
|
+
this.#pruneEvictedDeadLetters();
|
|
1336
1346
|
const deliveries = this.#filterDeliveries(filter);
|
|
1337
1347
|
const inFlightDeliveries = this.#filterInFlightDeliveries(filter);
|
|
1338
1348
|
const ownerId = filter?.ownerId;
|
|
1339
|
-
const deadLettered =
|
|
1340
|
-
|
|
1341
|
-
|
|
1349
|
+
const deadLettered = ownerId
|
|
1350
|
+
? Array.from(this.#deadLetteredDeliveries.keys()).filter(
|
|
1351
|
+
jobId => this.#deadLetteredDeliveryOwners.get(jobId) === ownerId,
|
|
1352
|
+
).length
|
|
1353
|
+
: this.#deadLetteredDeliveries.size;
|
|
1342
1354
|
const nextRetryAt = deliveries.reduce<number | undefined>((next, delivery) => {
|
|
1343
1355
|
if (next === undefined) return delivery.nextAttemptAt;
|
|
1344
1356
|
return Math.min(next, delivery.nextAttemptAt);
|
|
@@ -1553,6 +1565,7 @@ export class AsyncJobManager {
|
|
|
1553
1565
|
this.#deliveries.length = 0;
|
|
1554
1566
|
this.#inFlightDeliveries.length = 0;
|
|
1555
1567
|
this.#deadLetteredDeliveries.clear();
|
|
1568
|
+
this.#deadLetteredDeliveryOwners.clear();
|
|
1556
1569
|
this.#suppressedDeliveries.clear();
|
|
1557
1570
|
this.#watchedJobs.clear();
|
|
1558
1571
|
this.#outputState.clear();
|
|
@@ -1615,12 +1628,15 @@ export class AsyncJobManager {
|
|
|
1615
1628
|
}
|
|
1616
1629
|
|
|
1617
1630
|
#evictJob(jobId: string): void {
|
|
1631
|
+
this.#expireMonitorTombstones();
|
|
1618
1632
|
this.#recordMonitorTombstone(jobId);
|
|
1619
1633
|
this.#runLifecycle(jobId, "evict");
|
|
1620
1634
|
this.#purgeTerminalSubagentStateForJob(jobId);
|
|
1621
1635
|
this.#jobs.delete(jobId);
|
|
1622
1636
|
this.#lifecycles.delete(jobId);
|
|
1623
1637
|
this.#lifecyclePhases.delete(jobId);
|
|
1638
|
+
this.#deadLetteredDeliveries.delete(jobId);
|
|
1639
|
+
this.#deadLetteredDeliveryOwners.delete(jobId);
|
|
1624
1640
|
this.#suppressedDeliveries.delete(jobId);
|
|
1625
1641
|
this.#watchedJobs.delete(jobId);
|
|
1626
1642
|
this.#outputState.delete(jobId);
|
|
@@ -1700,6 +1716,33 @@ export class AsyncJobManager {
|
|
|
1700
1716
|
return this.#isDeliveryAcknowledged(jobId) || this.#watchedJobs.has(jobId);
|
|
1701
1717
|
}
|
|
1702
1718
|
|
|
1719
|
+
#pruneEvictedDeadLetters(): void {
|
|
1720
|
+
for (const jobId of this.#deadLetteredDeliveries.keys()) {
|
|
1721
|
+
if (this.#jobs.has(jobId)) continue;
|
|
1722
|
+
this.#deadLetteredDeliveries.delete(jobId);
|
|
1723
|
+
this.#deadLetteredDeliveryOwners.delete(jobId);
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
#recordDeadLetter(delivery: AsyncJobDelivery): void {
|
|
1728
|
+
this.#pruneEvictedDeadLetters();
|
|
1729
|
+
if (!this.#jobs.has(delivery.jobId)) return;
|
|
1730
|
+
this.#deadLetteredDeliveries.delete(delivery.jobId);
|
|
1731
|
+
this.#deadLetteredDeliveryOwners.delete(delivery.jobId);
|
|
1732
|
+
this.#deadLetteredDeliveries.set(delivery.jobId, {
|
|
1733
|
+
jobId: delivery.jobId,
|
|
1734
|
+
attempt: delivery.attempt,
|
|
1735
|
+
lastError: delivery.lastError,
|
|
1736
|
+
});
|
|
1737
|
+
this.#deadLetteredDeliveryOwners.set(delivery.jobId, delivery.ownerId);
|
|
1738
|
+
while (this.#deadLetteredDeliveries.size > MAX_DEAD_LETTERED_DELIVERIES) {
|
|
1739
|
+
const oldestJobId = this.#deadLetteredDeliveries.keys().next().value;
|
|
1740
|
+
if (oldestJobId === undefined) return;
|
|
1741
|
+
this.#deadLetteredDeliveries.delete(oldestJobId);
|
|
1742
|
+
this.#deadLetteredDeliveryOwners.delete(oldestJobId);
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1703
1746
|
#enqueueDelivery(jobId: string, text: string): void {
|
|
1704
1747
|
// Skip delivery if already acknowledged
|
|
1705
1748
|
if (this.#isDeliveryAcknowledged(jobId)) {
|
|
@@ -1717,7 +1760,7 @@ export class AsyncJobManager {
|
|
|
1717
1760
|
});
|
|
1718
1761
|
while (this.#deliveries.length > DEFAULT_MAX_DELIVERY_QUEUE) {
|
|
1719
1762
|
const dropped = this.#deliveries.shift();
|
|
1720
|
-
if (dropped) this.#
|
|
1763
|
+
if (dropped) this.#recordDeadLetter(dropped);
|
|
1721
1764
|
}
|
|
1722
1765
|
this.#ensureDeliveryLoop();
|
|
1723
1766
|
}
|
|
@@ -1781,7 +1824,7 @@ export class AsyncJobManager {
|
|
|
1781
1824
|
delivery.attempt += 1;
|
|
1782
1825
|
delivery.lastError = error instanceof Error ? error.message : String(error);
|
|
1783
1826
|
if (delivery.attempt >= DELIVERY_MAX_ATTEMPTS) {
|
|
1784
|
-
this.#
|
|
1827
|
+
this.#recordDeadLetter(delivery);
|
|
1785
1828
|
logger.warn("Async job completion delivery reached retry cap", {
|
|
1786
1829
|
jobId: delivery.jobId,
|
|
1787
1830
|
attempt: delivery.attempt,
|
package/src/cli/config-cli.ts
CHANGED
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
* Uses the settings schema as the source of truth for available settings.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import * as fs from "node:fs/promises";
|
|
9
|
+
import type * as path from "node:path";
|
|
8
10
|
import { APP_NAME, getAgentDir } from "@gajae-code/utils";
|
|
11
|
+
import { YAML } from "bun";
|
|
9
12
|
import chalk from "chalk";
|
|
10
13
|
import {
|
|
11
14
|
getDefault,
|
|
@@ -25,7 +28,7 @@ import { initXdg } from "./commands/init-xdg";
|
|
|
25
28
|
// Types
|
|
26
29
|
// =============================================================================
|
|
27
30
|
|
|
28
|
-
export type ConfigAction = "list" | "get" | "set" | "reset" | "path" | "init-xdg";
|
|
31
|
+
export type ConfigAction = "list" | "get" | "set" | "reset" | "path" | "doctor" | "init-xdg";
|
|
29
32
|
|
|
30
33
|
export interface ConfigCommandArgs {
|
|
31
34
|
action: ConfigAction;
|
|
@@ -111,7 +114,7 @@ function getSettingValues(def: CliSettingDef): readonly string[] | undefined {
|
|
|
111
114
|
// Argument Parser
|
|
112
115
|
// =============================================================================
|
|
113
116
|
|
|
114
|
-
const VALID_ACTIONS: ConfigAction[] = ["list", "get", "set", "reset", "path", "init-xdg"];
|
|
117
|
+
const VALID_ACTIONS: ConfigAction[] = ["list", "get", "set", "reset", "path", "doctor", "init-xdg"];
|
|
115
118
|
|
|
116
119
|
/**
|
|
117
120
|
* Parse config subcommand arguments.
|
|
@@ -299,6 +302,9 @@ export async function runConfigCommand(cmd: ConfigCommandArgs): Promise<void> {
|
|
|
299
302
|
case "path":
|
|
300
303
|
handlePath();
|
|
301
304
|
break;
|
|
305
|
+
case "doctor":
|
|
306
|
+
handleDoctor(cmd.flags);
|
|
307
|
+
break;
|
|
302
308
|
case "init-xdg":
|
|
303
309
|
await initXdg();
|
|
304
310
|
break;
|
|
@@ -443,6 +449,70 @@ function handlePath(): void {
|
|
|
443
449
|
console.log(getAgentDir());
|
|
444
450
|
}
|
|
445
451
|
|
|
452
|
+
function handleDoctor(flags: { json?: boolean }): void {
|
|
453
|
+
const report = settings.getSchemaReport();
|
|
454
|
+
if (flags.json) {
|
|
455
|
+
console.log(JSON.stringify(report, null, 2));
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
if (report.issues.length === 0) {
|
|
459
|
+
console.log(chalk.green("Settings schema is healthy."));
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
for (const issue of report.issues) console.log(`${issue.kind}\t${issue.path}\t${issue.detail}`);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
type ConfigDoctorReport = {
|
|
466
|
+
unknownKeys: string[];
|
|
467
|
+
invalidValues: Array<{ path: string; value: unknown }>;
|
|
468
|
+
legacyShapes: string[];
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
function flattenConfig(value: unknown, prefix = ""): Array<[string, unknown]> {
|
|
472
|
+
if (prefix && ALL_SETTING_PATHS.includes(prefix as SettingPath)) return [[prefix, value]];
|
|
473
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return prefix ? [[prefix, value]] : [];
|
|
474
|
+
return Object.entries(value).flatMap(([key, child]) => flattenConfig(child, prefix ? `${prefix}.${key}` : key));
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
function matchesSettingType(path: SettingPath, value: unknown): boolean {
|
|
478
|
+
const definition = SETTINGS_SCHEMA[path];
|
|
479
|
+
switch (definition.type) {
|
|
480
|
+
case "string":
|
|
481
|
+
case "enum":
|
|
482
|
+
return (
|
|
483
|
+
typeof value === "string" && (definition.type !== "enum" || getEnumValues(path)?.includes(value) === true)
|
|
484
|
+
);
|
|
485
|
+
case "number":
|
|
486
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
487
|
+
case "boolean":
|
|
488
|
+
return typeof value === "boolean";
|
|
489
|
+
case "array":
|
|
490
|
+
return Array.isArray(value);
|
|
491
|
+
case "record":
|
|
492
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
export async function inspectConfigFile(configPath: string): Promise<ConfigDoctorReport> {
|
|
497
|
+
const report: ConfigDoctorReport = { unknownKeys: [], invalidValues: [], legacyShapes: [] };
|
|
498
|
+
try {
|
|
499
|
+
const raw = YAML.parse(await fs.readFile(configPath, "utf8"));
|
|
500
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
501
|
+
report.legacyShapes.push("config root is not a mapping");
|
|
502
|
+
return report;
|
|
503
|
+
}
|
|
504
|
+
for (const [settingPath, value] of flattenConfig(raw)) {
|
|
505
|
+
if (!ALL_SETTING_PATHS.includes(settingPath as SettingPath)) report.unknownKeys.push(settingPath);
|
|
506
|
+
else if (!matchesSettingType(settingPath as SettingPath, value))
|
|
507
|
+
report.invalidValues.push({ path: settingPath, value: redactConfigValue(settingPath, value) });
|
|
508
|
+
}
|
|
509
|
+
} catch (error) {
|
|
510
|
+
if ((error as NodeJS.ErrnoException).code !== "ENOENT")
|
|
511
|
+
report.legacyShapes.push(`unable to parse config: ${String(error)}`);
|
|
512
|
+
}
|
|
513
|
+
return report;
|
|
514
|
+
}
|
|
515
|
+
|
|
446
516
|
// =============================================================================
|
|
447
517
|
// Help
|
|
448
518
|
// =============================================================================
|
|
@@ -455,8 +525,10 @@ ${chalk.bold("Commands:")}
|
|
|
455
525
|
get <key> Get a specific setting value
|
|
456
526
|
set <key> <value> Set a setting value
|
|
457
527
|
reset <key> Reset a setting to its default value
|
|
528
|
+
doctor Report unknown, invalid, and pending settings migrations
|
|
458
529
|
path Print the config directory path
|
|
459
530
|
init-xdg Initialize XDG Base Directory structure
|
|
531
|
+
doctor Report unknown, invalid, and legacy config entries
|
|
460
532
|
|
|
461
533
|
${chalk.bold("Options:")}
|
|
462
534
|
--json Output as JSON
|
|
@@ -472,6 +544,7 @@ ${chalk.bold("Examples:")}
|
|
|
472
544
|
${APP_NAME} config list --json
|
|
473
545
|
${APP_NAME} config get auth.broker.token --show-secrets
|
|
474
546
|
${APP_NAME} config init-xdg
|
|
547
|
+
${APP_NAME} config doctor --json
|
|
475
548
|
|
|
476
549
|
${chalk.bold("Boolean Values:")}
|
|
477
550
|
true, false, yes, no, on, off, 1, 0
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type LaunchMode = "text" | "json" | "acp";
|
|
2
|
+
|
|
3
|
+
export interface LaunchDisposition {
|
|
4
|
+
autoPrint: boolean;
|
|
5
|
+
isInteractive: boolean;
|
|
6
|
+
/** Set when an interactive launch is impossible (non-TTY stdin, nothing to run). */
|
|
7
|
+
nonInteractiveError?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Decides between interactive, auto-print, and fail-fast launches.
|
|
12
|
+
*
|
|
13
|
+
* A non-TTY stdin means the TUI can never receive input, so an interactive
|
|
14
|
+
* launch would execute the initial prompt and then block in the event loop
|
|
15
|
+
* forever. Prepared command-line input degrades to print mode; without any
|
|
16
|
+
* input to run we fail fast instead of hanging. Explicit `--print` and
|
|
17
|
+
* `--mode` launches are left untouched.
|
|
18
|
+
*/
|
|
19
|
+
export function resolveLaunchDisposition(args: {
|
|
20
|
+
stdinIsTTY: boolean | undefined;
|
|
21
|
+
pipedInput: string | undefined;
|
|
22
|
+
hasPreparedInput: boolean;
|
|
23
|
+
print: boolean;
|
|
24
|
+
mode: LaunchMode | undefined;
|
|
25
|
+
}): LaunchDisposition {
|
|
26
|
+
const explicitNonInteractive = args.print || args.mode !== undefined;
|
|
27
|
+
const hasPreparedInput = args.pipedInput !== undefined || args.hasPreparedInput;
|
|
28
|
+
const hasNonTtyStdin = args.stdinIsTTY !== true;
|
|
29
|
+
const autoPrint = !explicitNonInteractive && hasNonTtyStdin && hasPreparedInput;
|
|
30
|
+
const isInteractive = !explicitNonInteractive && !autoPrint;
|
|
31
|
+
|
|
32
|
+
if (isInteractive && args.stdinIsTTY !== true) {
|
|
33
|
+
return {
|
|
34
|
+
autoPrint: false,
|
|
35
|
+
isInteractive: false,
|
|
36
|
+
nonInteractiveError:
|
|
37
|
+
"stdin is not a TTY and no prompt or prepared input was provided; use -p/--print (or pass a prompt or @file) for non-interactive runs.",
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return { autoPrint, isInteractive };
|
|
42
|
+
}
|
package/src/cli/notify-cli.ts
CHANGED
|
@@ -75,6 +75,7 @@ export interface NotifyCommandDeps {
|
|
|
75
75
|
tokenPrompt?: () => Promise<string>;
|
|
76
76
|
setExitCode?: (code: number) => void;
|
|
77
77
|
exitProcess?: (code: number) => void;
|
|
78
|
+
valuePrompt?: (label: string, masked: boolean) => Promise<string>;
|
|
78
79
|
/** Optional daemon ownership facts collected by an embedding host. */
|
|
79
80
|
setupPreflight?: TelegramSetupPreflight;
|
|
80
81
|
/** Injectable timers and cancellation for setup pairing. */
|
|
@@ -99,6 +100,27 @@ export function parseNotifyArgs(args: string[]): NotifyCommandArgs | undefined {
|
|
|
99
100
|
const i = rest.indexOf(name);
|
|
100
101
|
return i >= 0 ? rest[i + 1] : undefined;
|
|
101
102
|
};
|
|
103
|
+
const valueFlags = [
|
|
104
|
+
"--token",
|
|
105
|
+
"--chat-id",
|
|
106
|
+
"--discord-bot-token",
|
|
107
|
+
"--discord-application-id",
|
|
108
|
+
"--discord-guild-id",
|
|
109
|
+
"--discord-parent-channel-id",
|
|
110
|
+
"--slack-bot-token",
|
|
111
|
+
"--slack-app-token",
|
|
112
|
+
"--slack-workspace-id",
|
|
113
|
+
"--slack-channel-id",
|
|
114
|
+
"--slack-authorized-user-id",
|
|
115
|
+
];
|
|
116
|
+
if (
|
|
117
|
+
valueFlags.some(name => {
|
|
118
|
+
const index = rest.indexOf(name);
|
|
119
|
+
const value = index >= 0 ? rest[index + 1] : undefined;
|
|
120
|
+
return index >= 0 && (!value || value.startsWith("--"));
|
|
121
|
+
})
|
|
122
|
+
)
|
|
123
|
+
return undefined;
|
|
102
124
|
const provider = rest[0]?.startsWith("--") ? undefined : rest[0];
|
|
103
125
|
if (provider !== undefined && provider !== "telegram" && provider !== "discord" && provider !== "slack") {
|
|
104
126
|
return undefined;
|
|
@@ -144,7 +166,7 @@ export function parseNotifyArgs(args: string[]): NotifyCommandArgs | undefined {
|
|
|
144
166
|
};
|
|
145
167
|
}
|
|
146
168
|
|
|
147
|
-
return
|
|
169
|
+
return undefined;
|
|
148
170
|
}
|
|
149
171
|
|
|
150
172
|
export async function runNotifyCommand(cmd: NotifyCommandArgs, deps: NotifyCommandDeps = {}): Promise<void> {
|
|
@@ -221,22 +243,41 @@ async function runSetup(cmd: NotifyCommandArgs, deps: NotifyCommandDeps): Promis
|
|
|
221
243
|
|
|
222
244
|
function requiredSetupValue(value: string | undefined, flag: string): string {
|
|
223
245
|
if (!value?.trim()) throw new Error(`${flag} is required for non-interactive setup.`);
|
|
246
|
+
if (value.trim().startsWith("--")) throw new Error(`${flag} must not start with --.`);
|
|
224
247
|
return value.trim();
|
|
225
248
|
}
|
|
226
249
|
|
|
250
|
+
async function promptSetupValue(
|
|
251
|
+
value: string | undefined,
|
|
252
|
+
flag: string,
|
|
253
|
+
masked: boolean,
|
|
254
|
+
deps: NotifyCommandDeps,
|
|
255
|
+
): Promise<string> {
|
|
256
|
+
if (value?.trim()) return requiredSetupValue(value, flag);
|
|
257
|
+
if (!resolveSetupInteractive(deps)) return requiredSetupValue(value, flag);
|
|
258
|
+
return requiredSetupValue(await (deps.valuePrompt ?? promptForValue)(`${flag.slice(2)}: `, masked), flag);
|
|
259
|
+
}
|
|
260
|
+
|
|
227
261
|
async function runDiscordSetup(cmd: NotifyCommandArgs, deps: NotifyCommandDeps): Promise<void> {
|
|
228
|
-
const botToken =
|
|
229
|
-
const applicationId =
|
|
230
|
-
const guildId =
|
|
231
|
-
const parentChannelId =
|
|
262
|
+
const botToken = await promptSetupValue(cmd.discordBotToken, "--discord-bot-token", true, deps);
|
|
263
|
+
const applicationId = await promptSetupValue(cmd.discordApplicationId, "--discord-application-id", false, deps);
|
|
264
|
+
const guildId = await promptSetupValue(cmd.discordGuildId, "--discord-guild-id", false, deps);
|
|
265
|
+
const parentChannelId = await promptSetupValue(
|
|
266
|
+
cmd.discordParentChannelId,
|
|
267
|
+
"--discord-parent-channel-id",
|
|
268
|
+
false,
|
|
269
|
+
deps,
|
|
270
|
+
);
|
|
232
271
|
const settings = await getSettings(deps);
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
272
|
+
const patches: SettingsAtomicPatch[] = [
|
|
273
|
+
{ path: "notifications.discord.botToken", op: "set", value: botToken },
|
|
274
|
+
{ path: "notifications.discord.applicationId", op: "set", value: applicationId },
|
|
275
|
+
{ path: "notifications.discord.guildId", op: "set", value: guildId },
|
|
276
|
+
{ path: "notifications.discord.parentChannelId", op: "set", value: parentChannelId },
|
|
277
|
+
{ path: "notifications.enabled", op: "set", value: true },
|
|
278
|
+
];
|
|
279
|
+
if (cmd.redact) patches.push({ path: "notifications.redact", op: "set", value: true });
|
|
280
|
+
await settings.commitAtomicBatch(patches);
|
|
240
281
|
const daemon = await ensureConfiguredProviderDaemon("discord", settings, deps);
|
|
241
282
|
process.stdout.write(
|
|
242
283
|
`Discord notifications enabled. botToken=${maskToken(botToken)} applicationId=${applicationId} guildId=${guildId} parentChannelId=${parentChannelId} daemon=${daemon}\n`,
|
|
@@ -244,20 +285,24 @@ async function runDiscordSetup(cmd: NotifyCommandArgs, deps: NotifyCommandDeps):
|
|
|
244
285
|
}
|
|
245
286
|
|
|
246
287
|
async function runSlackSetup(cmd: NotifyCommandArgs, deps: NotifyCommandDeps): Promise<void> {
|
|
247
|
-
const botToken =
|
|
248
|
-
const appToken =
|
|
249
|
-
const workspaceId =
|
|
250
|
-
const channelId =
|
|
288
|
+
const botToken = await promptSetupValue(cmd.slackBotToken, "--slack-bot-token", true, deps);
|
|
289
|
+
const appToken = await promptSetupValue(cmd.slackAppToken, "--slack-app-token", true, deps);
|
|
290
|
+
const workspaceId = await promptSetupValue(cmd.slackWorkspaceId, "--slack-workspace-id", false, deps);
|
|
291
|
+
const channelId = await promptSetupValue(cmd.slackChannelId, "--slack-channel-id", false, deps);
|
|
251
292
|
const authorizedUserId = cmd.slackAuthorizedUserId?.trim() || undefined;
|
|
252
293
|
const settings = await getSettings(deps);
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
294
|
+
const patches: SettingsAtomicPatch[] = [
|
|
295
|
+
{ path: "notifications.slack.botToken", op: "set", value: botToken },
|
|
296
|
+
{ path: "notifications.slack.appToken", op: "set", value: appToken },
|
|
297
|
+
{ path: "notifications.slack.workspaceId", op: "set", value: workspaceId },
|
|
298
|
+
{ path: "notifications.slack.channelId", op: "set", value: channelId },
|
|
299
|
+
authorizedUserId === undefined
|
|
300
|
+
? { path: "notifications.slack.authorizedUserId", op: "unset" }
|
|
301
|
+
: { path: "notifications.slack.authorizedUserId", op: "set", value: authorizedUserId },
|
|
302
|
+
{ path: "notifications.enabled", op: "set", value: true },
|
|
303
|
+
];
|
|
304
|
+
if (cmd.redact) patches.push({ path: "notifications.redact", op: "set", value: true });
|
|
305
|
+
await settings.commitAtomicBatch(patches);
|
|
261
306
|
const daemon = await ensureConfiguredProviderDaemon("slack", settings, deps);
|
|
262
307
|
process.stdout.write(
|
|
263
308
|
`Slack notifications enabled. botToken=${maskToken(botToken)} appToken=${maskToken(appToken)} workspaceId=${workspaceId} channelId=${channelId} authorizedUserId=${authorizedUserId ?? "(unset; inbound denied)"} daemon=${daemon}\n`,
|
|
@@ -437,7 +482,8 @@ type TokenPromptInput = NodeJS.ReadStream & {
|
|
|
437
482
|
|
|
438
483
|
type TokenPromptOutput = Pick<NodeJS.WriteStream, "write">;
|
|
439
484
|
|
|
440
|
-
|
|
485
|
+
async function promptForMaskedValue(
|
|
486
|
+
label: string,
|
|
441
487
|
input: TokenPromptInput = process.stdin,
|
|
442
488
|
output: TokenPromptOutput = process.stdout,
|
|
443
489
|
): Promise<string> {
|
|
@@ -448,7 +494,7 @@ export async function promptForToken(
|
|
|
448
494
|
throw new Error("notify setup requires a TTY with raw input support unless setupToken is injected.");
|
|
449
495
|
}
|
|
450
496
|
|
|
451
|
-
output.write(
|
|
497
|
+
output.write(label);
|
|
452
498
|
const wasRaw = input.isRaw === true;
|
|
453
499
|
input.setRawMode(true);
|
|
454
500
|
|
|
@@ -503,6 +549,26 @@ export async function promptForToken(
|
|
|
503
549
|
});
|
|
504
550
|
}
|
|
505
551
|
|
|
552
|
+
export async function promptForToken(
|
|
553
|
+
input: TokenPromptInput = process.stdin,
|
|
554
|
+
output: TokenPromptOutput = process.stdout,
|
|
555
|
+
): Promise<string> {
|
|
556
|
+
return await promptForMaskedValue("Telegram BotFather token: ", input, output);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
async function promptForValue(label: string, masked: boolean): Promise<string> {
|
|
560
|
+
if (masked) return await promptForMaskedValue(label);
|
|
561
|
+
if (!process.stdin.isTTY) {
|
|
562
|
+
throw new Error("notify setup requires an interactive TTY unless all setup values are supplied as flags.");
|
|
563
|
+
}
|
|
564
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: true });
|
|
565
|
+
try {
|
|
566
|
+
return (await rl.question(label)).trim();
|
|
567
|
+
} finally {
|
|
568
|
+
rl.close();
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
506
572
|
function resolveSetupInteractive(deps: NotifyCommandDeps): boolean {
|
|
507
573
|
if (deps.setupInteractive !== undefined) return deps.setupInteractive;
|
|
508
574
|
return Boolean(process.stdin.isTTY) && !deps.setupChatId?.trim();
|
|
@@ -1,13 +1,30 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
1
2
|
import { ProcessTerminal, TUI } from "@gajae-code/tui";
|
|
3
|
+
import { pathIsWithin } from "@gajae-code/utils";
|
|
2
4
|
import { type SessionSelectionResult, SessionSelectorComponent } from "../modes/components/session-selector";
|
|
3
5
|
import { type SessionInfo, SessionManager } from "../session/session-manager";
|
|
4
6
|
import { FileSessionStorage } from "../session/session-storage";
|
|
5
7
|
|
|
8
|
+
export async function deleteSessionPickerCandidate(sessionPath: string, explicitSessionDir?: string): Promise<void> {
|
|
9
|
+
if (!explicitSessionDir) {
|
|
10
|
+
await SessionManager.deleteManagedCandidate(sessionPath);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const root = path.resolve(explicitSessionDir);
|
|
14
|
+
const target = path.resolve(sessionPath);
|
|
15
|
+
if (!pathIsWithin(root, target))
|
|
16
|
+
throw new Error("Explicit session deletion escaped the configured session directory.");
|
|
17
|
+
await new FileSessionStorage().deleteSessionWithArtifacts(target);
|
|
18
|
+
}
|
|
19
|
+
|
|
6
20
|
/** Show the read-only TUI session picker and return the user's consent intent. */
|
|
7
|
-
export async function selectSession(
|
|
21
|
+
export async function selectSession(
|
|
22
|
+
sessions: SessionInfo[],
|
|
23
|
+
explicitSessionDir?: string,
|
|
24
|
+
): Promise<SessionSelectionResult> {
|
|
8
25
|
const { promise, resolve } = Promise.withResolvers<SessionSelectionResult>();
|
|
9
26
|
const ui = new TUI(new ProcessTerminal());
|
|
10
|
-
|
|
27
|
+
|
|
11
28
|
let settled = false;
|
|
12
29
|
const settle = (selection: SessionSelectionResult): void => {
|
|
13
30
|
if (settled) return;
|
|
@@ -21,7 +38,7 @@ export async function selectSession(sessions: SessionInfo[]): Promise<SessionSel
|
|
|
21
38
|
() => settle({ kind: "cancelled" }),
|
|
22
39
|
() => settle({ kind: "cancelled" }),
|
|
23
40
|
async session => {
|
|
24
|
-
await
|
|
41
|
+
await deleteSessionPickerCandidate(session.path, explicitSessionDir);
|
|
25
42
|
return true;
|
|
26
43
|
},
|
|
27
44
|
SessionManager.inspectSessionTailReadOnly,
|
package/src/cli/setup-cli.ts
CHANGED
|
@@ -564,7 +564,7 @@ async function confirmImport(count: number): Promise<boolean> {
|
|
|
564
564
|
*/
|
|
565
565
|
export interface CredentialsSetupDependencies {
|
|
566
566
|
openStore?: typeof SqliteAuthCredentialStore.open;
|
|
567
|
-
createAuthStorage?: (store:
|
|
567
|
+
createAuthStorage?: (store: SqliteAuthCredentialStore) => AuthStorage;
|
|
568
568
|
discover?: Parameters<typeof runExternalCredentialAutoImport>[0]["discover"];
|
|
569
569
|
}
|
|
570
570
|
|
package/src/cli.ts
CHANGED
|
@@ -9,7 +9,6 @@ import { Args, type CliConfig, Command, type CommandEntry, Flags, run } from "@g
|
|
|
9
9
|
import { APP_NAME, formatBunRuntimeError, MIN_BUN_VERSION, VERSION } from "@gajae-code/utils/dirs";
|
|
10
10
|
import { runFixtureReport } from "./cli/fixture-report";
|
|
11
11
|
import { isTmuxOwnerIsolationCliArgv, runTmuxOwnerIsolationCliFromStdin } from "./gjc-runtime/tmux-owner-isolation-cli";
|
|
12
|
-
import { runChatDaemonInternal } from "./sdk/bus/chat-daemon-cli";
|
|
13
12
|
|
|
14
13
|
if (Bun.semver.order(Bun.version, MIN_BUN_VERSION) < 0) {
|
|
15
14
|
process.stderr.write(
|
|
@@ -134,6 +133,7 @@ async function runChatDaemonInternalFastPath(argv: string[]): Promise<void> {
|
|
|
134
133
|
if (action !== "discord-internal" && action !== "slack-internal") {
|
|
135
134
|
throw new Error("invalid chat daemon internal fast path");
|
|
136
135
|
}
|
|
136
|
+
const { runChatDaemonInternal } = await import("./sdk/bus/chat-daemon-cli");
|
|
137
137
|
await runChatDaemonInternal(action === "discord-internal" ? "discord" : "slack", argv.slice(2));
|
|
138
138
|
}
|
|
139
139
|
|
package/src/commands/config.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Args, Command, Flags } from "@gajae-code/utils/cli";
|
|
|
5
5
|
import { type ConfigAction, type ConfigCommandArgs, runConfigCommand } from "../cli/config-cli";
|
|
6
6
|
import { initTheme } from "../modes/theme/theme";
|
|
7
7
|
|
|
8
|
-
const ACTIONS: ConfigAction[] = ["list", "get", "set", "reset", "path", "init-xdg"];
|
|
8
|
+
const ACTIONS: ConfigAction[] = ["list", "get", "set", "reset", "path", "init-xdg", "doctor"];
|
|
9
9
|
|
|
10
10
|
export default class Config extends Command {
|
|
11
11
|
static description = "Manage configuration settings";
|