@gajae-code/coding-agent 0.18.11 → 0.19.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 +760 -0
- package/dist/types/async/job-manager.d.ts +7 -3
- package/dist/types/async/result-formatting.d.ts +2 -0
- package/dist/types/autoresearch/git.d.ts +1 -1
- package/dist/types/capability/fs.d.ts +2 -2
- package/dist/types/capability/rule.d.ts +7 -2
- package/dist/types/cli/accounts-cli.d.ts +2 -2
- package/dist/types/cli/append-system-prompt.d.ts +6 -0
- package/dist/types/cli/args.d.ts +7 -2
- package/dist/types/cli/customize-doctor-precedence.d.ts +16 -0
- package/dist/types/cli/customize-doctor.d.ts +4 -3
- package/dist/types/cli/doctor/install-repairs.d.ts +4 -1
- package/dist/types/cli/install-activation.d.ts +10 -4
- package/dist/types/cli/public-command-errors.d.ts +2 -0
- package/dist/types/cli/root-flags.d.ts +0 -12
- package/dist/types/cli/update-cli.d.ts +21 -3
- package/dist/types/cli-main.d.ts +0 -6
- package/dist/types/cli-ordinary.d.ts +2 -2
- package/dist/types/commands/accounts.d.ts +2 -1
- package/dist/types/commands/launch.d.ts +0 -6
- package/dist/types/commands/migrate.d.ts +1 -1
- package/dist/types/commands/sdk.d.ts +13 -0
- package/dist/types/commit/changelog/index.d.ts +1 -0
- package/dist/types/commit/map-reduce/index.d.ts +4 -4
- package/dist/types/config/autorouting-tier-map.d.ts +53 -1
- package/dist/types/config/config-hot-reload-trust.d.ts +12 -0
- package/dist/types/config/config-hot-reload.d.ts +44 -0
- package/dist/types/config/file-lock.d.ts +52 -3
- package/dist/types/config/model-discovery-manager.d.ts +2 -0
- package/dist/types/config/model-profile-activation.d.ts +79 -9
- package/dist/types/config/model-registry.d.ts +72 -8
- package/dist/types/config/model-resolver.d.ts +7 -4
- package/dist/types/config/models-config-schema.d.ts +10 -0
- package/dist/types/config/settings-schema.d.ts +57 -4
- package/dist/types/config/settings.d.ts +33 -1
- package/dist/types/coordinator-mcp/server.d.ts +4 -0
- package/dist/types/customization/import.d.ts +2 -0
- package/dist/types/customization/types.d.ts +1 -1
- package/dist/types/dap/config.d.ts +8 -4
- package/dist/types/dap/session.d.ts +11 -2
- package/dist/types/debug/system-info.d.ts +6 -1
- package/dist/types/discovery/helpers.d.ts +7 -2
- package/dist/types/discovery/mcp-compat.d.ts +3 -1
- package/dist/types/edit/index.d.ts +5 -0
- package/dist/types/edit/modes/patch.d.ts +14 -0
- package/dist/types/edit/modes/replace.d.ts +3 -0
- package/dist/types/eval/py/runtime.d.ts +9 -0
- package/dist/types/exec/bash-executor.d.ts +12 -0
- package/dist/types/export/ttsr.d.ts +19 -0
- package/dist/types/extensibility/extensions/types.d.ts +5 -1
- package/dist/types/extensibility/slash-commands.d.ts +1 -0
- package/dist/types/gjc-runtime/managed-owner-admission.d.ts +3 -0
- package/dist/types/gjc-runtime/ralplan-current-final.d.ts +54 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +5 -0
- package/dist/types/gjc-runtime/session-state-lock.d.ts +2 -0
- package/dist/types/gjc-runtime/state-runtime.d.ts +0 -2
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +24 -0
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +6 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +1 -0
- package/dist/types/harness-control-plane/receipt-spool.d.ts +4 -0
- package/dist/types/hindsight/content.d.ts +5 -6
- package/dist/types/internal-urls/types.d.ts +2 -0
- package/dist/types/lsp/clients/swiftlint-client.d.ts +0 -4
- package/dist/types/main.d.ts +23 -18
- package/dist/types/migrate/action-planner.d.ts +10 -1
- package/dist/types/migrate/adapters/codex.d.ts +2 -1
- package/dist/types/migrate/adapters/index.d.ts +42 -1
- package/dist/types/migrate/executor.d.ts +3 -1
- package/dist/types/migrate/hook-module.d.ts +23 -0
- package/dist/types/migrate/report.d.ts +2 -1
- package/dist/types/migrate/types.d.ts +82 -3
- package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
- package/dist/types/modes/components/model-selector.d.ts +43 -0
- package/dist/types/modes/components/settings-selector.d.ts +6 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +2 -0
- package/dist/types/modes/prompt-suggestion-controller.d.ts +1 -1
- package/dist/types/modes/theme/theme.d.ts +1 -0
- package/dist/types/modes/utils/host-status.d.ts +15 -11
- package/dist/types/runtime-mcp/content-limits.d.ts +4 -0
- package/dist/types/runtime-mcp/manager.d.ts +7 -0
- package/dist/types/runtime-mcp/plugin-mcp-name-filter.d.ts +22 -0
- package/dist/types/runtime-mcp/project-host-values.d.ts +11 -5
- package/dist/types/runtime-mcp/tool-bridge.d.ts +4 -0
- package/dist/types/sdk/broker/broker-exit.d.ts +3 -3
- package/dist/types/sdk/broker/broker.d.ts +29 -2
- package/dist/types/sdk/broker/daemon-entry.d.ts +11 -1
- package/dist/types/sdk/broker/doctor-restart.d.ts +1 -1
- package/dist/types/sdk/broker/ensure.d.ts +141 -9
- package/dist/types/sdk/broker/hop.d.ts +45 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +18 -10
- package/dist/types/sdk/broker/lifecycle.d.ts +22 -0
- package/dist/types/sdk/broker/lock-host-identity.d.ts +5 -0
- package/dist/types/sdk/broker/session-index.d.ts +6 -1
- package/dist/types/sdk/broker/transport.d.ts +2 -0
- package/dist/types/sdk/bus/chat-command-policy.d.ts +2 -1
- package/dist/types/sdk/bus/index.d.ts +44 -0
- package/dist/types/sdk/bus/reconciliation-store.d.ts +10 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +9 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +2 -0
- package/dist/types/sdk/bus/threaded-render.d.ts +2 -1
- package/dist/types/sdk/cli/session-cli.d.ts +0 -1
- package/dist/types/sdk/host/control/operations.d.ts +5 -1
- package/dist/types/sdk/host/events.d.ts +4 -0
- package/dist/types/sdk/host/host.d.ts +2 -1
- package/dist/types/sdk/host/prompt-image-upload.d.ts +43 -0
- package/dist/types/sdk/host/session-runtime.d.ts +40 -8
- package/dist/types/sdk/host/surface-policy.d.ts +2 -1
- package/dist/types/sdk/lifecycle/service.d.ts +12 -0
- package/dist/types/sdk/prompt-deadline-flush.d.ts +42 -4
- package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -0
- package/dist/types/sdk/prompt-status.d.ts +11 -4
- package/dist/types/sdk/protocol/adapter-validation.d.ts +10 -4
- package/dist/types/sdk/reconciliation-extensions.d.ts +1 -1
- package/dist/types/sdk/session-list.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +107 -9
- package/dist/types/session/internal/managed-session-scope.d.ts +2 -2
- package/dist/types/session/internal/managed-session-storage.d.ts +1 -1
- package/dist/types/session/internal/native-publish-outcome.d.ts +1 -1
- package/dist/types/session/messages.d.ts +5 -1
- package/dist/types/session/session-manager.d.ts +29 -3
- package/dist/types/session/startup-auth-config.d.ts +24 -2
- package/dist/types/session/streaming-output.d.ts +11 -0
- package/dist/types/session/terminal-abort.d.ts +3 -1
- package/dist/types/session-import/service.d.ts +1 -1
- package/dist/types/skill-state/workflow-mutation-guard.d.ts +20 -4
- package/dist/types/slash-commands/helpers/mcp.d.ts +5 -0
- package/dist/types/slash-commands/helpers/provider-auth-status.d.ts +8 -0
- package/dist/types/ssh/ssh-executor.d.ts +8 -1
- package/dist/types/system-prompt.d.ts +3 -2
- package/dist/types/task/executor.d.ts +19 -2
- package/dist/types/task/role-body.d.ts +11 -0
- package/dist/types/tools/ast-edit-write-path.d.ts +10 -0
- package/dist/types/tools/atomic-file-write.d.ts +9 -7
- package/dist/types/tools/awaiting-input.d.ts +28 -0
- package/dist/types/tools/bash-allowed-prefixes.d.ts +17 -0
- package/dist/types/tools/bash-skill-urls.d.ts +4 -0
- package/dist/types/tools/bash.d.ts +7 -0
- package/dist/types/tools/descriptors.d.ts +15 -2
- package/dist/types/tools/fetch.d.ts +7 -1
- package/dist/types/tools/index.d.ts +2 -0
- package/dist/types/tools/irc.d.ts +5 -3
- package/dist/types/tools/python.d.ts +1 -1
- package/dist/types/tools/report-issue.d.ts +41 -0
- package/dist/types/tools/subagent.d.ts +23 -0
- package/dist/types/tools/tmux-self-injection-guard.d.ts +2 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +1 -1
- package/dist/types/tools/write.d.ts +2 -0
- package/dist/types/utils/file-mentions.d.ts +5 -0
- package/dist/types/utils/image-limits.d.ts +7 -0
- package/dist/types/utils/image-loading.d.ts +0 -1
- package/dist/types/utils/open.d.ts +0 -1
- package/dist/types/utils/pasted-image-loading.d.ts +1 -5
- package/dist/types/utils/prompt-suggestion.d.ts +2 -2
- package/dist/types/utils/shell-snapshot.d.ts +2 -0
- package/dist/types/utils/title-generator.d.ts +13 -3
- package/dist/types/web/scrapers/types.d.ts +8 -1
- package/dist/types/web/search/providers/codex.d.ts +6 -7
- package/dist/types/web/search/providers/insane.d.ts +7 -1
- package/dist/types/web/search/providers/searxng.d.ts +5 -0
- package/package.json +10 -9
- package/scripts/acp-conformance-agent.ts +12 -2
- package/scripts/build-binary.ts +2 -1
- package/scripts/capture-subagent-compact-panel-showcase.ts +105 -0
- package/scripts/generate-docs-index.ts +8 -1
- package/scripts/generate-sdk-operation-inventory.ts +38 -4
- package/src/async/job-manager.ts +356 -56
- package/src/async/result-formatting.ts +40 -0
- package/src/autoresearch/git.ts +9 -2
- package/src/autoresearch/prompts/prompt-setup.md +1 -1
- package/src/capability/fs.ts +58 -22
- package/src/capability/index.ts +2 -2
- package/src/capability/rule.ts +11 -2
- package/src/cli/accounts-cli.ts +176 -8
- package/src/cli/append-system-prompt.ts +12 -0
- package/src/cli/args.ts +11 -7
- package/src/cli/auth-broker-cli.ts +21 -11
- package/src/cli/customize-doctor-precedence.ts +31 -0
- package/src/cli/customize-doctor.ts +49 -39
- package/src/cli/doctor/install-repairs.ts +35 -5
- package/src/cli/fast-help.ts +1 -3
- package/src/cli/install-activation.ts +47 -4
- package/src/cli/migrate-cli.ts +19 -6
- package/src/cli/public-command-errors.ts +6 -0
- package/src/cli/root-flags.ts +2 -4
- package/src/cli/stats-cli.ts +9 -5
- package/src/cli/update-cli.ts +471 -13
- package/src/cli-ordinary.ts +7 -2
- package/src/commands/accounts.ts +10 -5
- package/src/commands/harness.ts +25 -15
- package/src/commands/migrate.ts +3 -3
- package/src/commands/sdk.ts +277 -50
- package/src/commands/ultragoal.ts +16 -8
- package/src/commit/agentic/agent.ts +6 -6
- package/src/commit/analysis/conventional.ts +14 -5
- package/src/commit/changelog/index.ts +39 -1
- package/src/commit/map-reduce/index.ts +7 -7
- package/src/commit/message.ts +10 -3
- package/src/commit/pipeline.ts +12 -12
- package/src/config/autorouting-tier-map.ts +50 -1
- package/src/config/config-file.ts +106 -3
- package/src/config/config-hot-reload-trust.ts +148 -0
- package/src/config/config-hot-reload.ts +742 -0
- package/src/config/file-lock.ts +1615 -328
- package/src/config/keybindings.ts +154 -7
- package/src/config/model-bindings-applier.ts +85 -47
- package/src/config/model-discovery-manager.ts +10 -0
- package/src/config/model-profile-activation.ts +889 -148
- package/src/config/model-registry.ts +1706 -205
- package/src/config/model-resolver.ts +52 -22
- package/src/config/models-config-schema.ts +6 -0
- package/src/config/settings-schema.ts +73 -4
- package/src/config/settings.ts +460 -24
- package/src/coordinator-mcp/policy.ts +26 -1
- package/src/coordinator-mcp/server.ts +37 -2
- package/src/crash/sanitize.ts +7 -1
- package/src/customization/import.ts +279 -8
- package/src/customization/inventory.ts +24 -8
- package/src/customization/types.ts +1 -0
- package/src/dap/client.ts +3 -2
- package/src/dap/config.ts +31 -11
- package/src/dap/defaults.json +1 -1
- package/src/dap/session.ts +161 -36
- package/src/debug/crash-diagnostics.ts +89 -6
- package/src/debug/report-bundle.ts +90 -2
- package/src/debug/system-info.ts +8 -3
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/shared/base-url.ts +21 -7
- package/src/discovery/agents-md.ts +1 -1
- package/src/discovery/builtin.ts +4 -3
- package/src/discovery/helpers.ts +25 -16
- package/src/discovery/mcp-compat.ts +120 -17
- package/src/edit/apply-patch/index.ts +12 -1
- package/src/edit/index.ts +204 -22
- package/src/edit/modes/patch.ts +214 -8
- package/src/edit/modes/replace.ts +136 -0
- package/src/eval/js/context-manager.ts +29 -3
- package/src/eval/js/worker-entry.ts +51 -18
- package/src/eval/py/executor.ts +14 -4
- package/src/eval/py/runner.py +144 -5
- package/src/eval/py/runtime.ts +44 -4
- package/src/exec/bash-executor.ts +81 -4
- package/src/exec/bash-shell-guardian.ts +4 -1
- package/src/exec/bash-shell-supervisor.ts +8 -4
- package/src/exec/isolated-shell.ts +5 -1
- package/src/exec/non-interactive-env.ts +0 -1
- package/src/export/html/index.ts +86 -6
- package/src/export/ttsr.ts +176 -1
- package/src/extensibility/custom-tools/wrapper.ts +3 -1
- package/src/extensibility/extensions/loader.ts +10 -1
- package/src/extensibility/extensions/ouroboros-ooo-bridge.ts +63 -1
- package/src/extensibility/extensions/types.ts +5 -1
- package/src/extensibility/hooks/loader.ts +10 -2
- package/src/extensibility/plugins/marketplace/fetcher.ts +2 -2
- package/src/extensibility/plugins/marketplace/manager.ts +36 -10
- package/src/extensibility/slash-commands.ts +5 -0
- package/src/gjc-runtime/gc-runtime.ts +37 -7
- package/src/gjc-runtime/launch-tmux.ts +30 -15
- package/src/gjc-runtime/launch-worktree.test.ts +148 -0
- package/src/gjc-runtime/launch-worktree.ts +101 -14
- package/src/gjc-runtime/managed-owner-admission.ts +46 -2
- package/src/gjc-runtime/ralplan-current-final.ts +294 -0
- package/src/gjc-runtime/ralplan-runtime.ts +95 -1
- package/src/gjc-runtime/session-resolution.ts +38 -6
- package/src/gjc-runtime/session-state-lock.ts +59 -14
- package/src/gjc-runtime/state-runtime.ts +23 -19
- package/src/gjc-runtime/state-writer.ts +109 -5
- package/src/gjc-runtime/tmux-sessions.ts +93 -13
- package/src/gjc-runtime/ultragoal-change-set.ts +90 -11
- package/src/gjc-runtime/ultragoal-guard.ts +9 -1
- package/src/gjc-runtime/ultragoal-runtime.ts +15 -5
- package/src/harness-control-plane/finalize.ts +11 -0
- package/src/harness-control-plane/receipt-spool.ts +105 -28
- package/src/harness-control-plane/storage.ts +124 -6
- package/src/hindsight/content.ts +116 -16
- package/src/hindsight/mental-models.ts +22 -10
- package/src/hindsight/state.ts +7 -4
- package/src/hooks/native-skill-hook.ts +17 -12
- package/src/internal-urls/artifact-protocol.ts +3 -1
- package/src/internal-urls/docs-index.generated.ts +23 -22
- package/src/internal-urls/local-protocol.ts +167 -8
- package/src/internal-urls/types.ts +2 -0
- package/src/lsp/client.ts +2 -1
- package/src/lsp/clients/biome-client.ts +2 -0
- package/src/lsp/clients/swiftlint-client.ts +2 -0
- package/src/lsp/index.ts +29 -0
- package/src/lsp/workspace-path.ts +23 -0
- package/src/main.ts +330 -92
- package/src/memories/index.ts +25 -2
- package/src/migrate/action-planner.ts +574 -2
- package/src/migrate/adapters/claude-code.ts +162 -5
- package/src/migrate/adapters/codex.ts +77 -7
- package/src/migrate/adapters/index.ts +258 -5
- package/src/migrate/adapters/opencode.ts +10 -1
- package/src/migrate/executor.ts +222 -7
- package/src/migrate/hook-module.ts +193 -0
- package/src/migrate/report.ts +63 -2
- package/src/migrate/types.ts +84 -4
- package/src/modes/DESIGN.md +51 -0
- package/src/modes/acp/acp-agent.ts +10 -1
- package/src/modes/acp/permission-mode.ts +18 -1
- package/src/modes/components/agent-dashboard.ts +20 -4
- package/src/modes/components/assistant-message.ts +55 -1
- package/src/modes/components/customization/customization-dashboard.ts +7 -0
- package/src/modes/components/customization/import-wizard.ts +29 -3
- package/src/modes/components/model-selector.ts +157 -103
- package/src/modes/components/settings-selector.ts +103 -37
- package/src/modes/components/welcome.ts +3 -1
- package/src/modes/controllers/command-controller.ts +300 -9
- package/src/modes/controllers/event-controller.ts +1 -1
- package/src/modes/controllers/extension-ui-controller.ts +31 -1
- package/src/modes/controllers/goal-mode-controller.ts +79 -10
- package/src/modes/controllers/input-controller.ts +2 -0
- package/src/modes/controllers/plan-mode-controller.ts +66 -11
- package/src/modes/controllers/runtime-mcp-command-controller.ts +7 -6
- package/src/modes/controllers/selector-controller.ts +76 -7
- package/src/modes/interactive-mode.ts +123 -4
- package/src/modes/prompt-suggestion-controller.ts +1 -1
- package/src/modes/runtime-init.ts +5 -1
- package/src/modes/theme/theme.ts +15 -0
- package/src/modes/utils/host-status.ts +21 -10
- package/src/prompts/agent-fragments/browser-aside.md +2 -2
- package/src/prompts/system/irc-incoming.md +3 -1
- package/src/prompts/tools/debug.md +1 -1
- package/src/prompts/tools/irc.md +1 -1
- package/src/prompts/tools/read.md +1 -1
- package/src/prompts/tools/report-issue.md +13 -0
- package/src/prompts/tools/task.md +1 -1
- package/src/runtime-credential-selector.ts +2 -2
- package/src/runtime-mcp/content-limits.ts +7 -0
- package/src/runtime-mcp/manager-pool.test.ts +5 -4
- package/src/runtime-mcp/manager.ts +40 -3
- package/src/runtime-mcp/oauth-flow.ts +32 -6
- package/src/runtime-mcp/plugin-mcp-name-filter.ts +62 -0
- package/src/runtime-mcp/project-host-values.ts +12 -8
- package/src/runtime-mcp/render.ts +16 -1
- package/src/runtime-mcp/tool-bridge.ts +194 -21
- package/src/runtime-mcp/transports/stdio.ts +2 -1
- package/src/sdk/broker/broker-exit.ts +10 -5
- package/src/sdk/broker/broker.ts +484 -85
- package/src/sdk/broker/daemon-entry.ts +338 -116
- package/src/sdk/broker/doctor-restart.ts +2 -1
- package/src/sdk/broker/ensure.ts +1214 -268
- package/src/sdk/broker/hop.ts +286 -0
- package/src/sdk/broker/lifecycle-ledger.ts +38 -11
- package/src/sdk/broker/lifecycle.ts +102 -6
- package/src/sdk/broker/lock-host-identity.ts +29 -0
- package/src/sdk/broker/session-index.ts +91 -16
- package/src/sdk/broker/transport.ts +17 -1
- package/src/sdk/bus/chat-command-policy.ts +16 -3
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/index.ts +460 -35
- package/src/sdk/bus/reconciliation-store.ts +201 -8
- package/src/sdk/bus/session-control.ts +2 -0
- package/src/sdk/bus/slack-daemon.ts +105 -9
- package/src/sdk/bus/telegram-daemon-contract.ts +9 -1
- package/src/sdk/bus/telegram-daemon.ts +10 -2
- package/src/sdk/bus/threaded-render.ts +20 -1
- package/src/sdk/cli/session-cli.ts +23 -6
- package/src/sdk/host/control/dispatch.ts +13 -1
- package/src/sdk/host/control/operations.ts +10 -1
- package/src/sdk/host/events.ts +67 -4
- package/src/sdk/host/host.ts +8 -2
- package/src/sdk/host/prompt-image-upload.ts +438 -0
- package/src/sdk/host/sdk-surface-parity.test.ts +15 -0
- package/src/sdk/host/session-runtime.test.ts +1737 -129
- package/src/sdk/host/session-runtime.ts +684 -83
- package/src/sdk/host/surface-policy.ts +4 -0
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +90 -2
- package/src/sdk/host/websocket-transport.ts +19 -7
- package/src/sdk/lifecycle/service.ts +15 -1
- package/src/sdk/prompt-deadline-flush.ts +78 -5
- package/src/sdk/prompt-deadline-manager.ts +68 -14
- package/src/sdk/prompt-status.ts +6 -4
- package/src/sdk/protocol/adapter-validation.ts +81 -12
- package/src/sdk/protocol/operation-inventory.generated.json +261 -2
- package/src/sdk/protocol/operation-registry.ts +33 -3
- package/src/sdk/reconciliation-extensions.ts +1 -0
- package/src/sdk/session-list.ts +1 -0
- package/src/sdk/session.ts +237 -97
- package/src/session/agent-session.ts +2726 -479
- package/src/session/history-storage.ts +182 -12
- package/src/session/internal/managed-session-scope.ts +173 -57
- package/src/session/internal/managed-session-storage.ts +85 -12
- package/src/session/internal/native-publish-outcome.ts +5 -1
- package/src/session/messages.ts +47 -6
- package/src/session/session-manager.ts +326 -19
- package/src/session/startup-auth-config.ts +116 -8
- package/src/session/streaming-output.ts +262 -4
- package/src/session/terminal-abort.ts +14 -2
- package/src/session-import/redact.ts +53 -2
- package/src/session-import/service.ts +1 -0
- package/src/skill-state/workflow-mutation-guard.ts +2145 -206
- package/src/slash-commands/builtin-registry.ts +21 -6
- package/src/slash-commands/helpers/credential-switch.ts +10 -5
- package/src/slash-commands/helpers/mcp.ts +11 -3
- package/src/slash-commands/helpers/provider-auth-status.ts +456 -0
- package/src/ssh/ssh-executor.ts +9 -2
- package/src/stt/recorder.ts +26 -9
- package/src/system-prompt.ts +61 -16
- package/src/task/executor.ts +115 -20
- package/src/task/index.ts +389 -175
- package/src/task/role-body.ts +84 -0
- package/src/task/token-log-mode.test.ts +162 -0
- package/src/task/token-log.ts +91 -2
- package/src/tools/archive-reader.ts +650 -37
- package/src/tools/ask.ts +1 -0
- package/src/tools/ast-edit-write-path.ts +64 -0
- package/src/tools/ast-edit.ts +18 -1
- package/src/tools/ast-grep.ts +7 -2
- package/src/tools/atomic-file-write.ts +46 -15
- package/src/tools/auto-generated-guard.ts +15 -3
- package/src/tools/awaiting-input.ts +114 -0
- package/src/tools/bash-allowed-prefixes.ts +214 -6
- package/src/tools/bash-interactive.ts +14 -2
- package/src/tools/bash-skill-urls.ts +58 -5
- package/src/tools/bash.ts +113 -26
- package/src/tools/browser/tab-worker.ts +39 -13
- package/src/tools/browser.ts +17 -7
- package/src/tools/cron.ts +10 -1
- package/src/tools/debug.ts +16 -8
- package/src/tools/descriptors.test.ts +44 -0
- package/src/tools/descriptors.ts +50 -6
- package/src/tools/eval.ts +15 -0
- package/src/tools/fetch.ts +93 -4
- package/src/tools/gh.ts +27 -12
- package/src/tools/image-gen.ts +20 -6
- package/src/tools/index.ts +2 -0
- package/src/tools/irc.ts +5 -3
- package/src/tools/monitor.ts +9 -1
- package/src/tools/output-meta.ts +74 -5
- package/src/tools/python.ts +1 -1
- package/src/tools/read.ts +26 -37
- package/src/tools/recipe/runner.ts +23 -12
- package/src/tools/render-utils.ts +2 -2
- package/src/tools/report-issue.ts +184 -0
- package/src/tools/search.ts +3 -2
- package/src/tools/ssh.ts +274 -8
- package/src/tools/subagent-render.ts +114 -12
- package/src/tools/subagent.ts +118 -5
- package/src/tools/tmux-self-injection-guard.ts +3301 -122
- package/src/tools/todo-write.ts +41 -3
- package/src/tools/tool-catalog.generated.ts +32 -4
- package/src/tools/ultragoal-ask-guard.ts +13 -1
- package/src/tools/write.ts +42 -3
- package/src/tui/tree-list.ts +15 -1
- package/src/utils/commit-message-generator.ts +12 -4
- package/src/utils/external-editor.ts +21 -7
- package/src/utils/file-mentions.ts +75 -7
- package/src/utils/git.ts +38 -7
- package/src/utils/image-limits.ts +8 -0
- package/src/utils/image-loading.ts +1 -1
- package/src/utils/open.ts +73 -4
- package/src/utils/pasted-image-loading.ts +9 -8
- package/src/utils/prompt-suggestion.ts +5 -4
- package/src/utils/shell-snapshot.ts +9 -1
- package/src/utils/title-generator.ts +72 -22
- package/src/web/scrapers/index.ts +3 -1
- package/src/web/scrapers/types.ts +8 -0
- package/src/web/scrapers/youtube.ts +3 -2
- package/src/web/search/index.ts +2 -1
- package/src/web/search/providers/codex.ts +29 -32
- package/src/web/search/providers/insane.ts +91 -28
- package/src/web/search/providers/searxng.ts +62 -10
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
AuthStorage,
|
|
26
26
|
type CredentialDisabledEvent,
|
|
27
27
|
DEFAULT_AUTH_BROKER_BIND,
|
|
28
|
+
formatOAuthIdentityLabel,
|
|
28
29
|
getEnvApiKey,
|
|
29
30
|
getOAuthProviders,
|
|
30
31
|
listProvidersWithEnvKey,
|
|
@@ -568,19 +569,21 @@ interface MigrateSkip {
|
|
|
568
569
|
|
|
569
570
|
function credentialIdentity(provider: string, credential: AuthCredential): string {
|
|
570
571
|
if (credential.type === "api_key") return "(api key)";
|
|
571
|
-
return credential
|
|
572
|
+
return formatOAuthIdentityLabel(credential) ?? `<${provider} oauth>`;
|
|
572
573
|
}
|
|
573
574
|
|
|
574
575
|
/**
|
|
575
576
|
* Build the set of "identities already on the broker" so re-runs are idempotent.
|
|
576
|
-
* For OAuth, identity = email|accountId|projectId
|
|
577
|
-
*
|
|
578
|
-
*
|
|
577
|
+
* For OAuth, identity = email|accountId|projectId, scoped to the organization
|
|
578
|
+
* when the credential carries one (one account can sign in to several
|
|
579
|
+
* organizations). For api_key, we collapse to a single marker per provider
|
|
580
|
+
* (broker has no concept of "multiple api keys per provider with different
|
|
581
|
+
* identities"; upsert would coalesce them).
|
|
579
582
|
*/
|
|
580
583
|
function indexBrokerSnapshot(snapshot: {
|
|
581
584
|
credentials: Array<{
|
|
582
585
|
provider: string;
|
|
583
|
-
credential: { type: string; email?: string; accountId?: string; projectId?: string };
|
|
586
|
+
credential: { type: string; email?: string; accountId?: string; projectId?: string; organizationId?: string };
|
|
584
587
|
}>;
|
|
585
588
|
}): Map<string, Set<string>> {
|
|
586
589
|
const out = new Map<string, Set<string>>();
|
|
@@ -589,22 +592,29 @@ function indexBrokerSnapshot(snapshot: {
|
|
|
589
592
|
if (entry.credential.type === "api_key") {
|
|
590
593
|
ids.add("@api_key");
|
|
591
594
|
} else {
|
|
592
|
-
|
|
593
|
-
if (entry.credential.
|
|
594
|
-
if (entry.credential.
|
|
595
|
+
const org = organizationSuffix(entry.credential.organizationId);
|
|
596
|
+
if (entry.credential.email) ids.add(`email:${entry.credential.email}${org}`);
|
|
597
|
+
if (entry.credential.accountId) ids.add(`accountId:${entry.credential.accountId}${org}`);
|
|
598
|
+
if (entry.credential.projectId) ids.add(`projectId:${entry.credential.projectId}${org}`);
|
|
595
599
|
}
|
|
596
600
|
out.set(entry.provider, ids);
|
|
597
601
|
}
|
|
598
602
|
return out;
|
|
599
603
|
}
|
|
600
604
|
|
|
605
|
+
function organizationSuffix(organizationId: string | undefined): string {
|
|
606
|
+
const trimmed = organizationId?.trim();
|
|
607
|
+
return trimmed ? `|org:${trimmed}` : "";
|
|
608
|
+
}
|
|
609
|
+
|
|
601
610
|
function brokerAlreadyHas(existing: Map<string, Set<string>>, provider: string, credential: AuthCredential): boolean {
|
|
602
611
|
const ids = existing.get(provider);
|
|
603
612
|
if (!ids) return false;
|
|
604
613
|
if (credential.type === "api_key") return ids.has("@api_key");
|
|
605
|
-
|
|
606
|
-
if (credential.
|
|
607
|
-
if (credential.
|
|
614
|
+
const org = organizationSuffix(credential.organizationId);
|
|
615
|
+
if (credential.email && ids.has(`email:${credential.email}${org}`)) return true;
|
|
616
|
+
if (credential.accountId && ids.has(`accountId:${credential.accountId}${org}`)) return true;
|
|
617
|
+
if (credential.projectId && ids.has(`projectId:${credential.projectId}${org}`)) return true;
|
|
608
618
|
return false;
|
|
609
619
|
}
|
|
610
620
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface DiscoveryPrecedenceCandidate {
|
|
2
|
+
key: string | undefined;
|
|
3
|
+
provider: string;
|
|
4
|
+
scope: "user" | "project" | "native";
|
|
5
|
+
eligible: boolean;
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface DiscoveryPrecedenceResult {
|
|
10
|
+
shadowed: boolean;
|
|
11
|
+
shadowedBy?: { provider: string; scope: DiscoveryPrecedenceCandidate["scope"] };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Resolve ordered discovery candidates without allowing ineligible or disabled entries to own keys. */
|
|
15
|
+
export function resolveDiscoveryPrecedence(
|
|
16
|
+
candidates: readonly DiscoveryPrecedenceCandidate[],
|
|
17
|
+
): DiscoveryPrecedenceResult[] {
|
|
18
|
+
const winners = new Map<string, { provider: string; scope: DiscoveryPrecedenceCandidate["scope"] }>();
|
|
19
|
+
|
|
20
|
+
return candidates.map(candidate => {
|
|
21
|
+
if (!candidate.eligible || candidate.key === undefined) return { shadowed: false };
|
|
22
|
+
|
|
23
|
+
const winner = winners.get(candidate.key);
|
|
24
|
+
if (winner) return { shadowed: true, shadowedBy: winner };
|
|
25
|
+
|
|
26
|
+
if (candidate.enabled) {
|
|
27
|
+
winners.set(candidate.key, { provider: candidate.provider, scope: candidate.scope });
|
|
28
|
+
}
|
|
29
|
+
return { shadowed: false };
|
|
30
|
+
});
|
|
31
|
+
}
|
|
@@ -54,6 +54,7 @@ import {
|
|
|
54
54
|
isCanonicalGjcWorkflowSkillFilesystemAlias,
|
|
55
55
|
} from "../skill-state/canonical-skills";
|
|
56
56
|
import { expandTilde } from "../tools/path-utils";
|
|
57
|
+
import { resolveDiscoveryPrecedence } from "./customize-doctor-precedence";
|
|
57
58
|
|
|
58
59
|
// =============================================================================
|
|
59
60
|
// Public types (stable JSON contract)
|
|
@@ -67,9 +68,10 @@ export type CustomizeSurfaceKind = "mcp" | "skill" | "hook" | "tool" | "extensio
|
|
|
67
68
|
*
|
|
68
69
|
* - `canonical`: project/global `.gjc` entries and GJC bundled defaults — the
|
|
69
70
|
* primary load path and the persisted authority for sessions.
|
|
70
|
-
* - `convention`: items
|
|
71
|
-
*
|
|
72
|
-
*
|
|
71
|
+
* - `convention`: items exposed by registered non-native discovery providers
|
|
72
|
+
* (claude-plugins, claude/codex hooks, agents, cursor, gemini, opencode,
|
|
73
|
+
* windsurf, cline, github, mcp-json, ssh). The item status identifies whether
|
|
74
|
+
* a discovered item is active, stored-only, or otherwise excluded at runtime.
|
|
73
75
|
* - `import-candidate`: Claude Code / Codex project (+ global) files on
|
|
74
76
|
* surfaces GJC deliberately never loads. Reported for provenance only; never
|
|
75
77
|
* active runtime authority. Candidates for a future import flow (#4291).
|
|
@@ -267,7 +269,7 @@ const SOURCE_CLASS_DESCRIPTIONS: Array<{ sourceClass: CustomizeSourceClass; desc
|
|
|
267
269
|
{
|
|
268
270
|
sourceClass: "convention",
|
|
269
271
|
description:
|
|
270
|
-
"Items
|
|
272
|
+
"Items exposed by registered convention providers (claude-plugins, claude/codex hooks, agents, cursor, gemini, opencode, windsurf, cline, github, mcp-json, ssh); item status identifies runtime eligibility.",
|
|
271
273
|
},
|
|
272
274
|
{
|
|
273
275
|
sourceClass: "import-candidate",
|
|
@@ -394,6 +396,7 @@ async function discoverCapability<T extends { _source: SourceMeta }>(
|
|
|
394
396
|
nameOf: (item: T) => string;
|
|
395
397
|
pathOf: (item: T) => string;
|
|
396
398
|
extensionIdOf?: (item: T) => string | undefined;
|
|
399
|
+
precedenceEligible?: (item: T) => boolean;
|
|
397
400
|
},
|
|
398
401
|
): Promise<DiscoveredSet<T>> {
|
|
399
402
|
const disabledProviders = new Set(activeSettings.get("disabledProviders"));
|
|
@@ -405,41 +408,34 @@ async function discoverCapability<T extends { _source: SourceMeta }>(
|
|
|
405
408
|
includeDisabledProviders: true,
|
|
406
409
|
});
|
|
407
410
|
|
|
408
|
-
//
|
|
409
|
-
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
// higher-priority provider must never shadow an enabled
|
|
424
|
-
// lower-priority source (includeDisabledProviders reports it
|
|
425
|
-
// as a listed item without giving it effective precedence).
|
|
426
|
-
winners.set(key, { provider: item._source.provider, scope });
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
entries.push({
|
|
411
|
+
// Resolve provider-order winners only after applying surface eligibility and
|
|
412
|
+
// the configured provider-disabled policy.
|
|
413
|
+
const resolvedPrecedence = resolveDiscoveryPrecedence(
|
|
414
|
+
result.all.map(item => ({
|
|
415
|
+
key: capability.key(item),
|
|
416
|
+
provider: item._source.provider,
|
|
417
|
+
scope: scopeOf(item._source),
|
|
418
|
+
eligible: options.precedenceEligible?.(item) ?? true,
|
|
419
|
+
enabled: !disabledProviders.has(item._source.provider),
|
|
420
|
+
})),
|
|
421
|
+
);
|
|
422
|
+
const entries: DiscoveredEntry<T>[] = result.all.map((item, index) => {
|
|
423
|
+
const precedence = resolvedPrecedence[index];
|
|
424
|
+
if (!precedence) throw new Error("discovery precedence result is missing an item");
|
|
425
|
+
return {
|
|
430
426
|
item,
|
|
431
427
|
name: options.nameOf(item),
|
|
432
428
|
path: options.pathOf(item),
|
|
433
429
|
provider: item._source.provider,
|
|
434
430
|
providerName: item._source.providerName,
|
|
435
|
-
scope,
|
|
431
|
+
scope: scopeOf(item._source),
|
|
436
432
|
priority: capability.providers.find(p => p.id === item._source.provider)?.priority ?? 0,
|
|
437
|
-
shadowed,
|
|
438
|
-
shadowedBy,
|
|
433
|
+
shadowed: precedence.shadowed,
|
|
434
|
+
shadowedBy: precedence.shadowedBy,
|
|
439
435
|
invalidReason: capability.validate?.(item),
|
|
440
436
|
extensionId: options.extensionIdOf?.(item),
|
|
441
|
-
}
|
|
442
|
-
}
|
|
437
|
+
};
|
|
438
|
+
});
|
|
443
439
|
|
|
444
440
|
entries.sort((a, b) => a.name.localeCompare(b.name) || a.provider.localeCompare(b.provider));
|
|
445
441
|
|
|
@@ -954,6 +950,7 @@ async function collectHooks(cwd: string, activeSettings: SettingsInstance): Prom
|
|
|
954
950
|
return collectNotExecutedAtStartup("hook", hookCapability, cwd, activeSettings, {
|
|
955
951
|
nameOf: hook => hook.name,
|
|
956
952
|
pathOf: hook => hook.path,
|
|
953
|
+
precedenceEligible: hook => hook.level !== "project",
|
|
957
954
|
notExecutedDetail:
|
|
958
955
|
"Trusted filesystem hook module discovered for session-start activation. Doctor does not execute the module, so dynamic Function Hook registrations and effective runtime order remain opaque until a session loads it.",
|
|
959
956
|
notExecutedRemediation: [
|
|
@@ -989,6 +986,7 @@ async function collectExtensions(cwd: string, activeSettings: SettingsInstance):
|
|
|
989
986
|
interface NotExecutedOptions<T extends { _source: SourceMeta }> {
|
|
990
987
|
nameOf: (item: T) => string;
|
|
991
988
|
pathOf: (item: T) => string;
|
|
989
|
+
precedenceEligible?: (item: T) => boolean;
|
|
992
990
|
notExecutedDetail: string;
|
|
993
991
|
notExecutedRemediation: string[];
|
|
994
992
|
}
|
|
@@ -1004,6 +1002,7 @@ async function collectNotExecutedAtStartup<T extends { _source: SourceMeta }>(
|
|
|
1004
1002
|
nameOf: options.nameOf,
|
|
1005
1003
|
pathOf: options.pathOf,
|
|
1006
1004
|
extensionIdOf: item => capability.toExtensionId?.(item),
|
|
1005
|
+
precedenceEligible: options.precedenceEligible,
|
|
1007
1006
|
});
|
|
1008
1007
|
const disabledExts = disabledExtensionIds(activeSettings);
|
|
1009
1008
|
const disabledProviders = new Set(activeSettings.get("disabledProviders"));
|
|
@@ -1019,6 +1018,18 @@ async function collectNotExecutedAtStartup<T extends { _source: SourceMeta }>(
|
|
|
1019
1018
|
[`Fix ${entry.path}`],
|
|
1020
1019
|
);
|
|
1021
1020
|
}
|
|
1021
|
+
if (kind === "hook" && entry.scope === "project") {
|
|
1022
|
+
return finalizeItem(
|
|
1023
|
+
base,
|
|
1024
|
+
"stored-only",
|
|
1025
|
+
"storage-only",
|
|
1026
|
+
"Project-scoped hooks are stored for inspection, but ordinary sessions do not load repository hook modules.",
|
|
1027
|
+
[
|
|
1028
|
+
"Import the hook into Global .gjc to load it for future sessions",
|
|
1029
|
+
"or configure an explicit hook path if repository-local activation is intentional",
|
|
1030
|
+
],
|
|
1031
|
+
);
|
|
1032
|
+
}
|
|
1022
1033
|
if (entry.extensionId !== undefined && disabledExts.has(entry.extensionId)) {
|
|
1023
1034
|
return finalizeItem(
|
|
1024
1035
|
base,
|
|
@@ -1360,13 +1371,12 @@ async function collectPluginBundles(cwd: string): Promise<CustomizeDoctorSurface
|
|
|
1360
1371
|
// Foreign conventions (Claude project / Codex project)
|
|
1361
1372
|
//
|
|
1362
1373
|
// Claude Code / Codex project hooks are discovered by the registered
|
|
1363
|
-
// claude-hooks/codex-hooks providers (see discovery/index.ts)
|
|
1364
|
-
//
|
|
1365
|
-
//
|
|
1366
|
-
//
|
|
1367
|
-
//
|
|
1368
|
-
//
|
|
1369
|
-
// marks every such item as `ignored`.
|
|
1374
|
+
// claude-hooks/codex-hooks providers (see discovery/index.ts), but like native
|
|
1375
|
+
// project hooks are stored-only and are not imported by ordinary sessions.
|
|
1376
|
+
// Every OTHER `.claude`/`.codex` surface (MCP, skills, tools, extensions,
|
|
1377
|
+
// commands, prompts, settings) is deliberately not part of the load path: the
|
|
1378
|
+
// doctor reports those files by invoking canonical provider load functions
|
|
1379
|
+
// directly (without registering the providers) and marks them `ignored`.
|
|
1370
1380
|
// =============================================================================
|
|
1371
1381
|
|
|
1372
1382
|
interface ForeignConventionDescriptor {
|
|
@@ -1468,7 +1478,7 @@ function foreignItem(
|
|
|
1468
1478
|
async function collectForeignConventions(cwd: string): Promise<ForeignConventionCollection> {
|
|
1469
1479
|
const ctx: LoadContext = { cwd, home: os.homedir(), repoRoot: await findRepoRoot(cwd) };
|
|
1470
1480
|
const itemsByKind: Map<CustomizeSurfaceKind, CustomizeDoctorItem[]> = new Map();
|
|
1471
|
-
const policyNote = `${FOREIGN_CONVENTIONS.map(d => d.dirName).join(" and ")} project hooks are
|
|
1481
|
+
const policyNote = `${FOREIGN_CONVENTIONS.map(d => d.dirName).join(" and ")} project hooks are shown as stored-only (see the Hooks surface); ordinary sessions do not load repository hook modules. All other ${FOREIGN_CONVENTIONS.map(d => d.providerName).join(" / ")} project config surfaces (MCP servers, skills, tools, extensions, commands, prompts, settings) are not part of the GJC load path and are reported below as import candidates for provenance.`;
|
|
1472
1482
|
|
|
1473
1483
|
for (const desc of FOREIGN_CONVENTIONS) {
|
|
1474
1484
|
const inspection = await desc.inspect(ctx);
|
|
@@ -14,7 +14,7 @@ import { randomUUID } from "node:crypto";
|
|
|
14
14
|
import { realpathSync } from "node:fs";
|
|
15
15
|
import * as fs from "node:fs/promises";
|
|
16
16
|
import * as path from "node:path";
|
|
17
|
-
import { isCompiledBinary, VERSION } from "@gajae-code/utils";
|
|
17
|
+
import { isCompiledBinary, logger, VERSION } from "@gajae-code/utils";
|
|
18
18
|
import { isUpdateChannel } from "../../config/update-channel";
|
|
19
19
|
import {
|
|
20
20
|
activationRecordPath,
|
|
@@ -27,8 +27,10 @@ import {
|
|
|
27
27
|
snapshotRegularFile,
|
|
28
28
|
} from "../install-activation";
|
|
29
29
|
import {
|
|
30
|
+
ActivationRetryCandidateRepointError,
|
|
30
31
|
acquireBinaryUpdateLock,
|
|
31
32
|
fetchAndVerifyOfficialPinnedCandidate,
|
|
33
|
+
InstallationAccessDeniedError,
|
|
32
34
|
isProtectedSourcePathForInstall,
|
|
33
35
|
replaceBinaryForUpdate,
|
|
34
36
|
smokeTestPinnedCandidate,
|
|
@@ -111,8 +113,10 @@ export interface InstallRepairResult {
|
|
|
111
113
|
readonly reason?: string;
|
|
112
114
|
readonly recordPath?: string;
|
|
113
115
|
readonly sideEffectStarted: boolean;
|
|
114
|
-
/**
|
|
116
|
+
/** Native Windows status returned by exact replacement. */
|
|
115
117
|
readonly windowsErrorCode?: string;
|
|
118
|
+
readonly stagingCleanupWarning?: string;
|
|
119
|
+
readonly retainedPaths?: InstallationAccessDeniedError["retainedPaths"];
|
|
116
120
|
readonly before?: { readonly identity?: FileIdentity; readonly digest?: string };
|
|
117
121
|
readonly after?: { readonly identity?: FileIdentity; readonly digest?: string; readonly version?: string };
|
|
118
122
|
}
|
|
@@ -317,17 +321,43 @@ export async function repairStandaloneBinary(
|
|
|
317
321
|
};
|
|
318
322
|
} catch (error) {
|
|
319
323
|
const pendingActivation = error instanceof Error && error.message === "installation_pending_activation";
|
|
324
|
+
const accessDeniedError = error instanceof InstallationAccessDeniedError ? error : undefined;
|
|
325
|
+
const repointError = error instanceof ActivationRetryCandidateRepointError ? error : undefined;
|
|
320
326
|
const reason = pendingActivation
|
|
321
327
|
? "sharing_violation"
|
|
322
|
-
:
|
|
323
|
-
?
|
|
324
|
-
:
|
|
328
|
+
: accessDeniedError
|
|
329
|
+
? accessDeniedError.code
|
|
330
|
+
: repointError
|
|
331
|
+
? repointError.reasonCode
|
|
332
|
+
: error instanceof Error && /^[a-z][a-z0-9_]{0,63}$/.test(error.message)
|
|
333
|
+
? error.message
|
|
334
|
+
: "installation_execution_unverified";
|
|
335
|
+
if (accessDeniedError)
|
|
336
|
+
logger.warn("Doctor standalone binary restore failed with access denied", {
|
|
337
|
+
targetPath,
|
|
338
|
+
code: accessDeniedError.code,
|
|
339
|
+
...(accessDeniedError.windowsErrorCode ? { windowsErrorCode: accessDeniedError.windowsErrorCode } : {}),
|
|
340
|
+
...(accessDeniedError.stagingCleanupWarning
|
|
341
|
+
? { stagingCleanupWarning: accessDeniedError.stagingCleanupWarning }
|
|
342
|
+
: {}),
|
|
343
|
+
...(accessDeniedError.retainedPaths ? { retainedPaths: accessDeniedError.retainedPaths } : {}),
|
|
344
|
+
});
|
|
345
|
+
if (repointError)
|
|
346
|
+
logger.warn("Doctor standalone binary restore retained a retry candidate after record repoint failed", {
|
|
347
|
+
path: repointError.candidatePath,
|
|
348
|
+
reason: repointError.reasonCode,
|
|
349
|
+
});
|
|
325
350
|
return {
|
|
326
351
|
state: pendingActivation ? "pending_activation" : started ? "failed" : "blocked",
|
|
327
352
|
reason,
|
|
328
353
|
sideEffectStarted: started,
|
|
329
354
|
before,
|
|
330
355
|
recordPath,
|
|
356
|
+
...(accessDeniedError?.windowsErrorCode ? { windowsErrorCode: accessDeniedError.windowsErrorCode } : {}),
|
|
357
|
+
...(accessDeniedError?.stagingCleanupWarning
|
|
358
|
+
? { stagingCleanupWarning: accessDeniedError.stagingCleanupWarning }
|
|
359
|
+
: {}),
|
|
360
|
+
...(accessDeniedError?.retainedPaths ? { retainedPaths: accessDeniedError.retainedPaths } : {}),
|
|
331
361
|
};
|
|
332
362
|
} finally {
|
|
333
363
|
await release();
|
package/src/cli/fast-help.ts
CHANGED
|
@@ -8,7 +8,7 @@ export function getExtraHelpText(): string {
|
|
|
8
8
|
${APP_NAME} session - List, inspect, create, remove, or attach sessions
|
|
9
9
|
${APP_NAME} state - Inspect or manage persisted GJC state
|
|
10
10
|
${APP_NAME} auth-broker - Manage the auth-broker (credential vault)
|
|
11
|
-
${APP_NAME} accounts - List, check, pin, and remove stored OAuth accounts
|
|
11
|
+
${APP_NAME} accounts - List, check, pin, prefer, and remove stored OAuth accounts
|
|
12
12
|
${APP_NAME} models presets - Inspect, refresh, pin, rollback, or disable the signed model preset registry
|
|
13
13
|
${APP_NAME} auth-gateway - Run an auth-gateway forward proxy
|
|
14
14
|
${APP_NAME} harness - Run harness control-plane commands
|
|
@@ -81,8 +81,6 @@ Environment Variables:
|
|
|
81
81
|
GJC_CODING_AGENT_DIR - Session storage directory (default: ~/${CONFIG_DIR_NAME}/agent)
|
|
82
82
|
GJC_UI_LANGUAGE - Explicit first-use onboarding language (en, ko, zh, or ja); invalid values use English without prompting
|
|
83
83
|
GJC_PACKAGE_DIR - Override package directory (for Nix/Guix store paths)
|
|
84
|
-
GJC_SMOL_MODEL - Override smol/fast model (see --smol)
|
|
85
|
-
GJC_SLOW_MODEL - Override slow/reasoning model (see --slow)
|
|
86
84
|
GJC_PLAN_MODEL - Override planning model (see --plan)
|
|
87
85
|
GJC_MODEL_PRESET_REGISTRY_URL - HTTPS latest.json override for the signed preset registry
|
|
88
86
|
GJC_MODEL_PRESET_REGISTRY_DISABLED - Disable registry fetch/use (1/true/yes/on)
|
|
@@ -504,8 +504,12 @@ export interface ReconcileResult {
|
|
|
504
504
|
readonly record?: ActivationRecordV1;
|
|
505
505
|
readonly recordIdentity?: FileIdentity;
|
|
506
506
|
readonly reason?: string;
|
|
507
|
-
/** Present only for a pre-mutation Windows
|
|
507
|
+
/** Present only for a pre-mutation Windows exact-replacement failure. */
|
|
508
508
|
readonly windowsErrorCode?: string;
|
|
509
|
+
readonly detachedPath?: string;
|
|
510
|
+
readonly retainedSuccessorPath?: string;
|
|
511
|
+
readonly retainedPlaceholderPath?: string;
|
|
512
|
+
readonly retainedUnknownPath?: string;
|
|
509
513
|
}
|
|
510
514
|
|
|
511
515
|
/**
|
|
@@ -519,9 +523,11 @@ export interface ReconcileResult {
|
|
|
519
523
|
* records are re-verified and advanced to `verified` once the target
|
|
520
524
|
* digest/identity matches the candidate. `verified` records are read-only
|
|
521
525
|
* re-confirmations. Anything else (target/parent drift, missing staged
|
|
522
|
-
* candidate, an already-occupied backup name
|
|
523
|
-
*
|
|
524
|
-
*
|
|
526
|
+
* candidate, an already-occupied backup name) is reported as `conflict` with
|
|
527
|
+
* the exact reason and never silently promoted. A pre-mutation Windows
|
|
528
|
+
* sharing violation becomes `pending_activation`; an access-denied result is
|
|
529
|
+
* also recorded as pending for safe reuse but remains a `conflict` so the
|
|
530
|
+
* caller reports the publication failure.
|
|
525
531
|
*/
|
|
526
532
|
export async function reconcileActivationRecord(
|
|
527
533
|
targetPath: string,
|
|
@@ -637,11 +643,48 @@ export async function reconcileActivationRecord(
|
|
|
637
643
|
};
|
|
638
644
|
}
|
|
639
645
|
}
|
|
646
|
+
if (
|
|
647
|
+
record.targetIdentity &&
|
|
648
|
+
record.stagingIdentity &&
|
|
649
|
+
result.code === "access_denied" &&
|
|
650
|
+
(process.platform === "win32" || result.windowsErrorCode === "0xC0000022") &&
|
|
651
|
+
!result.detachedPath &&
|
|
652
|
+
!result.retainedSuccessorPath &&
|
|
653
|
+
!result.retainedUnknownPath &&
|
|
654
|
+
!result.retainedPlaceholderPath
|
|
655
|
+
) {
|
|
656
|
+
const unchangedTarget = await snapshotRegularFile(targetPath);
|
|
657
|
+
const unchangedStaging = await snapshotRegularFile(record.stagingPath);
|
|
658
|
+
if (
|
|
659
|
+
unchangedTarget &&
|
|
660
|
+
unchangedStaging &&
|
|
661
|
+
sameFileIdentity(record.targetIdentity, unchangedTarget.identity) &&
|
|
662
|
+
sameFileIdentity(record.stagingIdentity, unchangedStaging.identity)
|
|
663
|
+
) {
|
|
664
|
+
const pending: ActivationRecordV1 = { ...record, phase: "pending_activation" };
|
|
665
|
+
const pendingIdentity = await updateActivationRecordFile(pending, recordIdentity);
|
|
666
|
+
return {
|
|
667
|
+
status: "conflict",
|
|
668
|
+
record: pending,
|
|
669
|
+
recordIdentity: pendingIdentity,
|
|
670
|
+
reason: "access_denied",
|
|
671
|
+
...(result.windowsErrorCode ? { windowsErrorCode: result.windowsErrorCode } : {}),
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
}
|
|
640
675
|
return {
|
|
641
676
|
status: "conflict",
|
|
642
677
|
record,
|
|
643
678
|
reason: result.code ?? "activation_promotion_failed",
|
|
644
679
|
...(result.windowsErrorCode ? { windowsErrorCode: result.windowsErrorCode } : {}),
|
|
680
|
+
...(result.detachedPath !== undefined ? { detachedPath: result.detachedPath } : {}),
|
|
681
|
+
...(result.retainedSuccessorPath !== undefined
|
|
682
|
+
? { retainedSuccessorPath: result.retainedSuccessorPath }
|
|
683
|
+
: {}),
|
|
684
|
+
...(result.retainedPlaceholderPath !== undefined
|
|
685
|
+
? { retainedPlaceholderPath: result.retainedPlaceholderPath }
|
|
686
|
+
: {}),
|
|
687
|
+
...(result.retainedUnknownPath !== undefined ? { retainedUnknownPath: result.retainedUnknownPath } : {}),
|
|
645
688
|
};
|
|
646
689
|
}
|
|
647
690
|
const promoted = await snapshotRegularFile(targetPath);
|
package/src/cli/migrate-cli.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `gjc migrate` — import MCP servers and
|
|
2
|
+
* `gjc migrate` — import MCP servers, skills, slash commands, and instruction files from other coding agents.
|
|
3
3
|
*/
|
|
4
4
|
import * as os from "node:os";
|
|
5
5
|
import * as path from "node:path";
|
|
@@ -53,8 +53,20 @@ export function resolveSources(from: string[]): MigrateSource[] {
|
|
|
53
53
|
|
|
54
54
|
function resolveDestinations(project: boolean, cwd: string): MigrateDestinations {
|
|
55
55
|
const scope = project ? "project" : "user";
|
|
56
|
-
const
|
|
57
|
-
|
|
56
|
+
const agentDir = project ? getProjectAgentDir(cwd) : getAgentDir();
|
|
57
|
+
const skillsDir = path.join(agentDir, "skills");
|
|
58
|
+
const commandsDir = path.join(agentDir, "commands");
|
|
59
|
+
const agentsDir = path.join(agentDir, "agents");
|
|
60
|
+
const hooksDir = path.join(agentDir, "hooks");
|
|
61
|
+
const instructionsPath = path.join(agentDir, "AGENTS.md");
|
|
62
|
+
return {
|
|
63
|
+
mcpConfigPath: getMCPConfigPath(scope, cwd),
|
|
64
|
+
skillsDir,
|
|
65
|
+
commandsDir,
|
|
66
|
+
agentsDir,
|
|
67
|
+
hooksDir,
|
|
68
|
+
instructionsPath,
|
|
69
|
+
};
|
|
58
70
|
}
|
|
59
71
|
|
|
60
72
|
/** Run the migration and return the report (does not set process.exitCode). */
|
|
@@ -66,15 +78,16 @@ export async function runMigrate(args: MigrateCommandArgs): Promise<MigrateRepor
|
|
|
66
78
|
|
|
67
79
|
const results: AdapterResult[] = [];
|
|
68
80
|
for (const source of sources) {
|
|
69
|
-
results.push(await getAdapter(source).collect({ homeDir }));
|
|
81
|
+
results.push(await getAdapter(source).collect({ homeDir, cwd, scope: args.project ? "project" : "user" }));
|
|
70
82
|
}
|
|
71
83
|
|
|
72
|
-
const { actions, warnings } = await planMigration({ results, destinations, force: args.force });
|
|
73
|
-
const finalActions = args.dryRun ? actions : await executeActions(actions);
|
|
84
|
+
const { actions, warnings, manualActions } = await planMigration({ results, destinations, force: args.force });
|
|
85
|
+
const finalActions = args.dryRun ? actions : await executeActions(actions, { project: args.project });
|
|
74
86
|
|
|
75
87
|
return buildReport({
|
|
76
88
|
actions: finalActions,
|
|
77
89
|
warnings,
|
|
90
|
+
manualActions,
|
|
78
91
|
sources,
|
|
79
92
|
destinations,
|
|
80
93
|
dryRun: args.dryRun,
|
|
@@ -111,6 +111,12 @@ export const PUBLIC_COMMAND_DIAGNOSTICS = {
|
|
|
111
111
|
// of them and never implies that another key would be safe.
|
|
112
112
|
lifecycle_idempotency_conflict:
|
|
113
113
|
"The broker reported an idempotency conflict. Reconcile existing lifecycle state before deciding whether another request is safe.",
|
|
114
|
+
lifecycle_legacy_history_ambiguous:
|
|
115
|
+
"The broker refused admission because legacy lifecycle history cannot prove this target is unrelated. This request was not dispatched; this refusal does not settle earlier effects. Preserve the ledger and original operation, request key, and target. For a prior session.create, use read-only session.lookup with its original key and create target; not_found is not proof of no effect. An empty transcript, stopped host, or fresh key does not resolve this fence. Do not edit the ledger, force deletion, or retry with another key; missing identity or terminal effect evidence requires operator investigation.",
|
|
116
|
+
// Refusals of the request payload itself: the broker's own text names the missing field
|
|
117
|
+
// (a required `sessionPath`, for one), and it is never rendered, so the class is named here.
|
|
118
|
+
lifecycle_input_refused:
|
|
119
|
+
"The broker refused the request as invalid input. Correct the request payload and reconcile existing lifecycle state before deciding whether another request is safe.",
|
|
114
120
|
usage_transport_exclusive: "Specify exactly one of --stdio or --socket <path>.",
|
|
115
121
|
usage_duplicate_option: "Each option on this command may occur at most once.",
|
|
116
122
|
usage_unknown_argument: "An unrecognized argument was supplied; re-read the command help for its accepted grammar.",
|
package/src/cli/root-flags.ts
CHANGED
|
@@ -10,8 +10,6 @@ export type RootThinkingLevel = (typeof ROOT_THINKING_LEVELS)[number];
|
|
|
10
10
|
/** Public launch flags shared by root help, completion, and the launch command. */
|
|
11
11
|
export const ROOT_LAUNCH_FLAGS = {
|
|
12
12
|
model: Flags.string({ description: 'Model to use (fuzzy match: "opus", "gpt-5.2", or "openai/gpt-5.2")' }),
|
|
13
|
-
smol: Flags.string({ description: "Smol/fast model for lightweight tasks (or GJC_SMOL_MODEL env)" }),
|
|
14
|
-
slow: Flags.string({ description: "Slow/reasoning model for thorough analysis (or GJC_SLOW_MODEL env)" }),
|
|
15
13
|
plan: Flags.string({ description: "Plan model for architectural planning (or GJC_PLAN_MODEL env)" }),
|
|
16
14
|
mpreset: Flags.string({ description: "Model profile preset to activate for this session" }),
|
|
17
15
|
default: Flags.boolean({ description: "Persist --mpreset as the default model profile" }),
|
|
@@ -19,11 +17,11 @@ export const ROOT_LAUNCH_FLAGS = {
|
|
|
19
17
|
"api-key": Flags.string({ description: "API key (defaults to env vars)" }),
|
|
20
18
|
credential: Flags.string({
|
|
21
19
|
description:
|
|
22
|
-
"Stored credential selector: email:<addr>, id:<n>, account:<id>, project:<id>, or provider/email:<addr>",
|
|
20
|
+
"Stored credential selector: email:<addr>, id:<n>, account:<id>, project:<id>, org:<id|name>, or provider/email:<addr>",
|
|
23
21
|
}),
|
|
24
22
|
"prefer-credential": Flags.string({
|
|
25
23
|
description:
|
|
26
|
-
"Preferred stored credential with quota fallback: email:<addr>, id:<n>, account:<id>, project:<id>, or provider/id:<n>",
|
|
24
|
+
"Preferred stored credential with quota fallback: email:<addr>, id:<n>, account:<id>, project:<id>, org:<id|name>, or provider/id:<n>",
|
|
27
25
|
}),
|
|
28
26
|
"system-prompt": Flags.string({ description: "System prompt (default: coding assistant prompt)" }),
|
|
29
27
|
"append-system-prompt": Flags.string({ description: "Append text or file contents to the system prompt" }),
|
package/src/cli/stats-cli.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Handles `gjc stats` subcommand for viewing AI usage statistics.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { APP_NAME, formatDuration, formatNumber, formatPercent } from "@gajae-code/utils";
|
|
7
|
+
import { APP_NAME, formatDuration, formatNumber, formatPercent, sanitizeDisplayLine } from "@gajae-code/utils";
|
|
8
8
|
import chalk from "chalk";
|
|
9
9
|
import { openPath } from "../utils/open";
|
|
10
10
|
|
|
@@ -168,7 +168,7 @@ async function printStatsSummary(): Promise<void> {
|
|
|
168
168
|
console.log(chalk.bold("\nBy Model:"));
|
|
169
169
|
for (const m of byModel.slice(0, 10)) {
|
|
170
170
|
console.log(
|
|
171
|
-
` ${m.model}: ${formatNumber(m.totalRequests)} reqs, ${formatCost(m.totalCost)}, ${formatPercent(m.cacheRate)} cache`,
|
|
171
|
+
` ${sanitizeDisplayLine(m.model)}: ${formatNumber(m.totalRequests)} reqs, ${formatCost(m.totalCost)}, ${formatPercent(m.cacheRate)} cache`,
|
|
172
172
|
);
|
|
173
173
|
}
|
|
174
174
|
}
|
|
@@ -177,7 +177,7 @@ async function printStatsSummary(): Promise<void> {
|
|
|
177
177
|
console.log(chalk.bold("\nBy Agent Role:"));
|
|
178
178
|
for (const agent of byAgent) {
|
|
179
179
|
console.log(
|
|
180
|
-
` ${agent.agent}: ${formatNumber(agent.totalRequests)} reqs, ${formatNumber(agent.totalInputTokens)} input / ${formatNumber(agent.totalOutputTokens)} output, ${formatPercent(agent.cacheRate)} cache, ${formatCost(agent.totalCost)}`,
|
|
180
|
+
` ${sanitizeDisplayLine(agent.agent)}: ${formatNumber(agent.totalRequests)} reqs, ${formatNumber(agent.totalInputTokens)} input / ${formatNumber(agent.totalOutputTokens)} output, ${formatPercent(agent.cacheRate)} cache, ${formatCost(agent.totalCost)}`,
|
|
181
181
|
);
|
|
182
182
|
}
|
|
183
183
|
}
|
|
@@ -185,7 +185,9 @@ async function printStatsSummary(): Promise<void> {
|
|
|
185
185
|
if (byFolder.length > 0) {
|
|
186
186
|
console.log(chalk.bold("\nBy Folder:"));
|
|
187
187
|
for (const f of byFolder.slice(0, 10)) {
|
|
188
|
-
console.log(
|
|
188
|
+
console.log(
|
|
189
|
+
` ${sanitizeDisplayLine(f.folder)}: ${formatNumber(f.totalRequests)} reqs, ${formatCost(f.totalCost)}`,
|
|
190
|
+
);
|
|
189
191
|
}
|
|
190
192
|
}
|
|
191
193
|
|
|
@@ -201,7 +203,9 @@ async function printStatsSummary(): Promise<void> {
|
|
|
201
203
|
console.log(` Provider-side (prefix intact): ${formatNumber(misses.providerSideMisses)}`);
|
|
202
204
|
console.log(` Model switch: ${formatNumber(misses.modelSwitchMisses)}`);
|
|
203
205
|
for (const cause of misses.byCause) {
|
|
204
|
-
const label =
|
|
206
|
+
const label = sanitizeDisplayLine(
|
|
207
|
+
cause.divergedRole ? `${cause.change} (${cause.divergedRole})` : cause.change,
|
|
208
|
+
);
|
|
205
209
|
console.log(` ${label}: ${formatNumber(cause.misses)}`);
|
|
206
210
|
}
|
|
207
211
|
}
|