@akon-labs/nexus-cli 0.1.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 +5342 -0
- package/LICENSE +22 -0
- package/README.md +677 -0
- package/dist/bun/cli.d.ts +3 -0
- package/dist/bun/cli.d.ts.map +1 -0
- package/dist/bun/cli.js +11 -0
- package/dist/bun/cli.js.map +1 -0
- package/dist/bun/register-bedrock.d.ts +2 -0
- package/dist/bun/register-bedrock.d.ts.map +1 -0
- package/dist/bun/register-bedrock.js +4 -0
- package/dist/bun/register-bedrock.js.map +1 -0
- package/dist/bun/restore-sandbox-env.d.ts +17 -0
- package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
- package/dist/bun/restore-sandbox-env.js +36 -0
- package/dist/bun/restore-sandbox-env.js.map +1 -0
- package/dist/cli/args.d.ts +59 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +408 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/config-selector.d.ts +16 -0
- package/dist/cli/config-selector.d.ts.map +1 -0
- package/dist/cli/config-selector.js +31 -0
- package/dist/cli/config-selector.js.map +1 -0
- package/dist/cli/credential-print.d.ts +23 -0
- package/dist/cli/credential-print.d.ts.map +1 -0
- package/dist/cli/credential-print.js +118 -0
- package/dist/cli/credential-print.js.map +1 -0
- package/dist/cli/experimental/auth.d.ts +16 -0
- package/dist/cli/experimental/auth.d.ts.map +1 -0
- package/dist/cli/experimental/auth.js +13 -0
- package/dist/cli/experimental/auth.js.map +1 -0
- package/dist/cli/experimental/cli.d.ts +6 -0
- package/dist/cli/experimental/cli.d.ts.map +1 -0
- package/dist/cli/experimental/cli.js +5 -0
- package/dist/cli/experimental/cli.js.map +1 -0
- package/dist/cli/experimental/command-options.d.ts +17 -0
- package/dist/cli/experimental/command-options.d.ts.map +1 -0
- package/dist/cli/experimental/command-options.js +35 -0
- package/dist/cli/experimental/command-options.js.map +1 -0
- package/dist/cli/experimental/command.d.ts +63 -0
- package/dist/cli/experimental/command.d.ts.map +1 -0
- package/dist/cli/experimental/command.js +130 -0
- package/dist/cli/experimental/command.js.map +1 -0
- package/dist/cli/experimental/commands/client.d.ts +13 -0
- package/dist/cli/experimental/commands/client.d.ts.map +1 -0
- package/dist/cli/experimental/commands/client.js +25 -0
- package/dist/cli/experimental/commands/client.js.map +1 -0
- package/dist/cli/experimental/commands/pi.d.ts +15 -0
- package/dist/cli/experimental/commands/pi.d.ts.map +1 -0
- package/dist/cli/experimental/commands/pi.js +28 -0
- package/dist/cli/experimental/commands/pi.js.map +1 -0
- package/dist/cli/experimental/commands/server.d.ts +13 -0
- package/dist/cli/experimental/commands/server.d.ts.map +1 -0
- package/dist/cli/experimental/commands/server.js +25 -0
- package/dist/cli/experimental/commands/server.js.map +1 -0
- package/dist/cli/experimental/transport-address.d.ts +10 -0
- package/dist/cli/experimental/transport-address.d.ts.map +1 -0
- package/dist/cli/experimental/transport-address.js +38 -0
- package/dist/cli/experimental/transport-address.js.map +1 -0
- package/dist/cli/file-processor.d.ts +15 -0
- package/dist/cli/file-processor.d.ts.map +1 -0
- package/dist/cli/file-processor.js +70 -0
- package/dist/cli/file-processor.js.map +1 -0
- package/dist/cli/initial-message.d.ts +18 -0
- package/dist/cli/initial-message.d.ts.map +1 -0
- package/dist/cli/initial-message.js +22 -0
- package/dist/cli/initial-message.js.map +1 -0
- package/dist/cli/list-models.d.ts +9 -0
- package/dist/cli/list-models.d.ts.map +1 -0
- package/dist/cli/list-models.js +98 -0
- package/dist/cli/list-models.js.map +1 -0
- package/dist/cli/project-trust.d.ts +10 -0
- package/dist/cli/project-trust.d.ts.map +1 -0
- package/dist/cli/project-trust.js +48 -0
- package/dist/cli/project-trust.js.map +1 -0
- package/dist/cli/require-login.d.ts +30 -0
- package/dist/cli/require-login.d.ts.map +1 -0
- package/dist/cli/require-login.js +96 -0
- package/dist/cli/require-login.js.map +1 -0
- package/dist/cli/session-picker.d.ts +10 -0
- package/dist/cli/session-picker.d.ts.map +1 -0
- package/dist/cli/session-picker.js +36 -0
- package/dist/cli/session-picker.js.map +1 -0
- package/dist/cli/startup-ui.d.ts +20 -0
- package/dist/cli/startup-ui.d.ts.map +1 -0
- package/dist/cli/startup-ui.js +185 -0
- package/dist/cli/startup-ui.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +69740 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +425 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/remote-session.d.ts +53 -0
- package/dist/client/remote-session.d.ts.map +1 -0
- package/dist/client/remote-session.js +340 -0
- package/dist/client/remote-session.js.map +1 -0
- package/dist/client/transcript.d.ts +12 -0
- package/dist/client/transcript.d.ts.map +1 -0
- package/dist/client/transcript.js +98 -0
- package/dist/client/transcript.js.map +1 -0
- package/dist/config.d.ts +99 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +482 -0
- package/dist/config.js.map +1 -0
- package/dist/core/agent-session-runtime.d.ts +119 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -0
- package/dist/core/agent-session-runtime.js +309 -0
- package/dist/core/agent-session-runtime.js.map +1 -0
- package/dist/core/agent-session-services.d.ts +86 -0
- package/dist/core/agent-session-services.d.ts.map +1 -0
- package/dist/core/agent-session-services.js +134 -0
- package/dist/core/agent-session-services.js.map +1 -0
- package/dist/core/agent-session.d.ts +644 -0
- package/dist/core/agent-session.d.ts.map +1 -0
- package/dist/core/agent-session.js +2687 -0
- package/dist/core/agent-session.js.map +1 -0
- package/dist/core/auth-guidance.d.ts +5 -0
- package/dist/core/auth-guidance.d.ts.map +1 -0
- package/dist/core/auth-guidance.js +39 -0
- package/dist/core/auth-guidance.js.map +1 -0
- package/dist/core/auth-storage.d.ts +62 -0
- package/dist/core/auth-storage.d.ts.map +1 -0
- package/dist/core/auth-storage.js +350 -0
- package/dist/core/auth-storage.js.map +1 -0
- package/dist/core/bash-executor.d.ts +32 -0
- package/dist/core/bash-executor.d.ts.map +1 -0
- package/dist/core/bash-executor.js +111 -0
- package/dist/core/bash-executor.js.map +1 -0
- package/dist/core/cache-stats.d.ts +49 -0
- package/dist/core/cache-stats.d.ts.map +1 -0
- package/dist/core/cache-stats.js +101 -0
- package/dist/core/cache-stats.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts +98 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
- package/dist/core/compaction/branch-summarization.js +246 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -0
- package/dist/core/compaction/compaction.d.ts +137 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -0
- package/dist/core/compaction/compaction.js +645 -0
- package/dist/core/compaction/compaction.js.map +1 -0
- package/dist/core/compaction/index.d.ts +7 -0
- package/dist/core/compaction/index.d.ts.map +1 -0
- package/dist/core/compaction/index.js +7 -0
- package/dist/core/compaction/index.js.map +1 -0
- package/dist/core/compaction/utils.d.ts +38 -0
- package/dist/core/compaction/utils.d.ts.map +1 -0
- package/dist/core/compaction/utils.js +142 -0
- package/dist/core/compaction/utils.js.map +1 -0
- package/dist/core/defaults.d.ts +3 -0
- package/dist/core/defaults.d.ts.map +1 -0
- package/dist/core/defaults.js +2 -0
- package/dist/core/defaults.js.map +1 -0
- package/dist/core/diagnostics.d.ts +15 -0
- package/dist/core/diagnostics.d.ts.map +1 -0
- package/dist/core/diagnostics.js +2 -0
- package/dist/core/diagnostics.js.map +1 -0
- package/dist/core/event-bus.d.ts +9 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +25 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/core/exec.d.ts +29 -0
- package/dist/core/exec.d.ts.map +1 -0
- package/dist/core/exec.js +75 -0
- package/dist/core/exec.js.map +1 -0
- package/dist/core/experimental.d.ts +2 -0
- package/dist/core/experimental.d.ts.map +1 -0
- package/dist/core/experimental.js +5 -0
- package/dist/core/experimental.js.map +1 -0
- package/dist/core/export-html/ansi-to-html.d.ts +22 -0
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
- package/dist/core/export-html/ansi-to-html.js +249 -0
- package/dist/core/export-html/ansi-to-html.js.map +1 -0
- package/dist/core/export-html/index.d.ts +37 -0
- package/dist/core/export-html/index.d.ts.map +1 -0
- package/dist/core/export-html/index.js +226 -0
- package/dist/core/export-html/index.js.map +1 -0
- package/dist/core/export-html/template.css +1066 -0
- package/dist/core/export-html/template.html +55 -0
- package/dist/core/export-html/template.js +1864 -0
- package/dist/core/export-html/tool-renderer.d.ts +34 -0
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
- package/dist/core/export-html/tool-renderer.js +108 -0
- package/dist/core/export-html/tool-renderer.js.map +1 -0
- package/dist/core/export-html/vendor/highlight.min.js +1213 -0
- package/dist/core/export-html/vendor/marked.min.js +78 -0
- package/dist/core/extensions/index.d.ts +12 -0
- package/dist/core/extensions/index.d.ts.map +1 -0
- package/dist/core/extensions/index.js +9 -0
- package/dist/core/extensions/index.js.map +1 -0
- package/dist/core/extensions/loader.d.ts +23 -0
- package/dist/core/extensions/loader.d.ts.map +1 -0
- package/dist/core/extensions/loader.js +581 -0
- package/dist/core/extensions/loader.js.map +1 -0
- package/dist/core/extensions/runner.d.ts +173 -0
- package/dist/core/extensions/runner.d.ts.map +1 -0
- package/dist/core/extensions/runner.js +967 -0
- package/dist/core/extensions/runner.js.map +1 -0
- package/dist/core/extensions/types.d.ts +1288 -0
- package/dist/core/extensions/types.d.ts.map +1 -0
- package/dist/core/extensions/types.js +45 -0
- package/dist/core/extensions/types.js.map +1 -0
- package/dist/core/extensions/wrapper.d.ts +20 -0
- package/dist/core/extensions/wrapper.d.ts.map +1 -0
- package/dist/core/extensions/wrapper.js +41 -0
- package/dist/core/extensions/wrapper.js.map +1 -0
- package/dist/core/footer-data-provider.d.ts +64 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -0
- package/dist/core/footer-data-provider.js +338 -0
- package/dist/core/footer-data-provider.js.map +1 -0
- package/dist/core/graph-rail-store.d.ts +94 -0
- package/dist/core/graph-rail-store.d.ts.map +1 -0
- package/dist/core/graph-rail-store.js +86 -0
- package/dist/core/graph-rail-store.js.map +1 -0
- package/dist/core/http-dispatcher.d.ts +22 -0
- package/dist/core/http-dispatcher.d.ts.map +1 -0
- package/dist/core/http-dispatcher.js +96 -0
- package/dist/core/http-dispatcher.js.map +1 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +13 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/keybindings.d.ts +395 -0
- package/dist/core/keybindings.d.ts.map +1 -0
- package/dist/core/keybindings.js +297 -0
- package/dist/core/keybindings.js.map +1 -0
- package/dist/core/messages.d.ts +77 -0
- package/dist/core/messages.d.ts.map +1 -0
- package/dist/core/messages.js +123 -0
- package/dist/core/messages.js.map +1 -0
- package/dist/core/model-config.d.ts +566 -0
- package/dist/core/model-config.d.ts.map +1 -0
- package/dist/core/model-config.js +253 -0
- package/dist/core/model-config.js.map +1 -0
- package/dist/core/model-registry.d.ts +45 -0
- package/dist/core/model-registry.d.ts.map +1 -0
- package/dist/core/model-registry.js +107 -0
- package/dist/core/model-registry.js.map +1 -0
- package/dist/core/model-resolver.d.ts +127 -0
- package/dist/core/model-resolver.d.ts.map +1 -0
- package/dist/core/model-resolver.js +541 -0
- package/dist/core/model-resolver.js.map +1 -0
- package/dist/core/model-runtime.d.ts +97 -0
- package/dist/core/model-runtime.d.ts.map +1 -0
- package/dist/core/model-runtime.js +594 -0
- package/dist/core/model-runtime.js.map +1 -0
- package/dist/core/models-dev-catalog.d.ts +63 -0
- package/dist/core/models-dev-catalog.d.ts.map +1 -0
- package/dist/core/models-dev-catalog.js +105 -0
- package/dist/core/models-dev-catalog.js.map +1 -0
- package/dist/core/models-store.d.ts +22 -0
- package/dist/core/models-store.d.ts.map +1 -0
- package/dist/core/models-store.js +114 -0
- package/dist/core/models-store.js.map +1 -0
- package/dist/core/observatory-cache.d.ts +16 -0
- package/dist/core/observatory-cache.d.ts.map +1 -0
- package/dist/core/observatory-cache.js +55 -0
- package/dist/core/observatory-cache.js.map +1 -0
- package/dist/core/output-guard.d.ts +7 -0
- package/dist/core/output-guard.d.ts.map +1 -0
- package/dist/core/output-guard.js +89 -0
- package/dist/core/output-guard.js.map +1 -0
- package/dist/core/package-manager.d.ts +213 -0
- package/dist/core/package-manager.d.ts.map +1 -0
- package/dist/core/package-manager.js +2169 -0
- package/dist/core/package-manager.js.map +1 -0
- package/dist/core/pi-manifest.d.ts +8 -0
- package/dist/core/pi-manifest.d.ts.map +1 -0
- package/dist/core/pi-manifest.js +25 -0
- package/dist/core/pi-manifest.js.map +1 -0
- package/dist/core/project-trust.d.ts +15 -0
- package/dist/core/project-trust.d.ts.map +1 -0
- package/dist/core/project-trust.js +59 -0
- package/dist/core/project-trust.js.map +1 -0
- package/dist/core/prompt-templates.d.ts +54 -0
- package/dist/core/prompt-templates.d.ts.map +1 -0
- package/dist/core/prompt-templates.js +236 -0
- package/dist/core/prompt-templates.js.map +1 -0
- package/dist/core/provider-attribution.d.ts +4 -0
- package/dist/core/provider-attribution.d.ts.map +1 -0
- package/dist/core/provider-attribution.js +73 -0
- package/dist/core/provider-attribution.js.map +1 -0
- package/dist/core/provider-composer.d.ts +56 -0
- package/dist/core/provider-composer.d.ts.map +1 -0
- package/dist/core/provider-composer.js +395 -0
- package/dist/core/provider-composer.js.map +1 -0
- package/dist/core/radius.d.ts +2 -0
- package/dist/core/radius.d.ts.map +1 -0
- package/dist/core/radius.js +2 -0
- package/dist/core/radius.js.map +1 -0
- package/dist/core/remote-catalog-provider.d.ts +5 -0
- package/dist/core/remote-catalog-provider.d.ts.map +1 -0
- package/dist/core/remote-catalog-provider.js +106 -0
- package/dist/core/remote-catalog-provider.js.map +1 -0
- package/dist/core/resolve-config-value.d.ts +30 -0
- package/dist/core/resolve-config-value.d.ts.map +1 -0
- package/dist/core/resolve-config-value.js +247 -0
- package/dist/core/resolve-config-value.js.map +1 -0
- package/dist/core/resource-loader.d.ts +221 -0
- package/dist/core/resource-loader.d.ts.map +1 -0
- package/dist/core/resource-loader.js +874 -0
- package/dist/core/resource-loader.js.map +1 -0
- package/dist/core/runtime-credentials.d.ts +15 -0
- package/dist/core/runtime-credentials.d.ts.map +1 -0
- package/dist/core/runtime-credentials.js +39 -0
- package/dist/core/runtime-credentials.js.map +1 -0
- package/dist/core/sdk.d.ts +106 -0
- package/dist/core/sdk.d.ts.map +1 -0
- package/dist/core/sdk.js +267 -0
- package/dist/core/sdk.js.map +1 -0
- package/dist/core/session-cwd.d.ts +19 -0
- package/dist/core/session-cwd.d.ts.map +1 -0
- package/dist/core/session-cwd.js +38 -0
- package/dist/core/session-cwd.js.map +1 -0
- package/dist/core/session-manager.d.ts +356 -0
- package/dist/core/session-manager.d.ts.map +1 -0
- package/dist/core/session-manager.js +1340 -0
- package/dist/core/session-manager.js.map +1 -0
- package/dist/core/settings-manager.d.ts +304 -0
- package/dist/core/settings-manager.d.ts.map +1 -0
- package/dist/core/settings-manager.js +912 -0
- package/dist/core/settings-manager.js.map +1 -0
- package/dist/core/skills.d.ts +60 -0
- package/dist/core/skills.d.ts.map +1 -0
- package/dist/core/skills.js +387 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/slash-commands.d.ts +21 -0
- package/dist/core/slash-commands.d.ts.map +1 -0
- package/dist/core/slash-commands.js +39 -0
- package/dist/core/slash-commands.js.map +1 -0
- package/dist/core/source-info.d.ts +18 -0
- package/dist/core/source-info.d.ts.map +1 -0
- package/dist/core/source-info.js +19 -0
- package/dist/core/source-info.js.map +1 -0
- package/dist/core/system-prompt.d.ts +28 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +130 -0
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/telemetry.d.ts +3 -0
- package/dist/core/telemetry.d.ts.map +1 -0
- package/dist/core/telemetry.js +10 -0
- package/dist/core/telemetry.js.map +1 -0
- package/dist/core/timings.d.ts +6 -0
- package/dist/core/timings.d.ts.map +1 -0
- package/dist/core/timings.js +42 -0
- package/dist/core/timings.js.map +1 -0
- package/dist/core/tools/bash.d.ts +70 -0
- package/dist/core/tools/bash.d.ts.map +1 -0
- package/dist/core/tools/bash.js +389 -0
- package/dist/core/tools/bash.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +106 -0
- package/dist/core/tools/edit-diff.d.ts.map +1 -0
- package/dist/core/tools/edit-diff.js +424 -0
- package/dist/core/tools/edit-diff.js.map +1 -0
- package/dist/core/tools/edit.d.ts +51 -0
- package/dist/core/tools/edit.d.ts.map +1 -0
- package/dist/core/tools/edit.js +284 -0
- package/dist/core/tools/edit.js.map +1 -0
- package/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
- package/dist/core/tools/file-mutation-queue.js +52 -0
- package/dist/core/tools/file-mutation-queue.js.map +1 -0
- package/dist/core/tools/find.d.ts +38 -0
- package/dist/core/tools/find.d.ts.map +1 -0
- package/dist/core/tools/find.js +298 -0
- package/dist/core/tools/find.js.map +1 -0
- package/dist/core/tools/grep.d.ts +37 -0
- package/dist/core/tools/grep.d.ts.map +1 -0
- package/dist/core/tools/grep.js +304 -0
- package/dist/core/tools/grep.js.map +1 -0
- package/dist/core/tools/index.d.ts +43 -0
- package/dist/core/tools/index.d.ts.map +1 -0
- package/dist/core/tools/index.js +129 -0
- package/dist/core/tools/index.js.map +1 -0
- package/dist/core/tools/ls.d.ts +37 -0
- package/dist/core/tools/ls.d.ts.map +1 -0
- package/dist/core/tools/ls.js +167 -0
- package/dist/core/tools/ls.js.map +1 -0
- package/dist/core/tools/output-accumulator.d.ts +52 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -0
- package/dist/core/tools/output-accumulator.js +185 -0
- package/dist/core/tools/output-accumulator.js.map +1 -0
- package/dist/core/tools/path-utils.d.ts +10 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -0
- package/dist/core/tools/path-utils.js +99 -0
- package/dist/core/tools/path-utils.js.map +1 -0
- package/dist/core/tools/read.d.ts +35 -0
- package/dist/core/tools/read.d.ts.map +1 -0
- package/dist/core/tools/read.js +284 -0
- package/dist/core/tools/read.js.map +1 -0
- package/dist/core/tools/render-utils.d.ts +24 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -0
- package/dist/core/tools/render-utils.js +65 -0
- package/dist/core/tools/render-utils.js.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.js +36 -0
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
- package/dist/core/tools/truncate.d.ts +70 -0
- package/dist/core/tools/truncate.d.ts.map +1 -0
- package/dist/core/tools/truncate.js +215 -0
- package/dist/core/tools/truncate.js.map +1 -0
- package/dist/core/tools/websearch.d.ts +29 -0
- package/dist/core/tools/websearch.d.ts.map +1 -0
- package/dist/core/tools/websearch.js +145 -0
- package/dist/core/tools/websearch.js.map +1 -0
- package/dist/core/tools/write.d.ts +26 -0
- package/dist/core/tools/write.d.ts.map +1 -0
- package/dist/core/tools/write.js +197 -0
- package/dist/core/tools/write.js.map +1 -0
- package/dist/core/trust-manager.d.ts +36 -0
- package/dist/core/trust-manager.d.ts.map +1 -0
- package/dist/core/trust-manager.js +202 -0
- package/dist/core/trust-manager.js.map +1 -0
- package/dist/core/usage-totals.d.ts +19 -0
- package/dist/core/usage-totals.d.ts.map +1 -0
- package/dist/core/usage-totals.js +52 -0
- package/dist/core/usage-totals.js.map +1 -0
- package/dist/extensions/gitnexus/augment.d.ts +4 -0
- package/dist/extensions/gitnexus/augment.d.ts.map +1 -0
- package/dist/extensions/gitnexus/augment.js +60 -0
- package/dist/extensions/gitnexus/augment.js.map +1 -0
- package/dist/extensions/gitnexus/changes.d.ts +3 -0
- package/dist/extensions/gitnexus/changes.d.ts.map +1 -0
- package/dist/extensions/gitnexus/changes.js +58 -0
- package/dist/extensions/gitnexus/changes.js.map +1 -0
- package/dist/extensions/gitnexus/client.d.ts +39 -0
- package/dist/extensions/gitnexus/client.d.ts.map +1 -0
- package/dist/extensions/gitnexus/client.js +173 -0
- package/dist/extensions/gitnexus/client.js.map +1 -0
- package/dist/extensions/gitnexus/config.d.ts +25 -0
- package/dist/extensions/gitnexus/config.d.ts.map +1 -0
- package/dist/extensions/gitnexus/config.js +42 -0
- package/dist/extensions/gitnexus/config.js.map +1 -0
- package/dist/extensions/gitnexus/device-auth.d.ts +60 -0
- package/dist/extensions/gitnexus/device-auth.d.ts.map +1 -0
- package/dist/extensions/gitnexus/device-auth.js +130 -0
- package/dist/extensions/gitnexus/device-auth.js.map +1 -0
- package/dist/extensions/gitnexus/gateway.d.ts +57 -0
- package/dist/extensions/gitnexus/gateway.d.ts.map +1 -0
- package/dist/extensions/gitnexus/gateway.js +139 -0
- package/dist/extensions/gitnexus/gateway.js.map +1 -0
- package/dist/extensions/gitnexus/index.d.ts +14 -0
- package/dist/extensions/gitnexus/index.d.ts.map +1 -0
- package/dist/extensions/gitnexus/index.js +189 -0
- package/dist/extensions/gitnexus/index.js.map +1 -0
- package/dist/extensions/gitnexus/observatory.d.ts +13 -0
- package/dist/extensions/gitnexus/observatory.d.ts.map +1 -0
- package/dist/extensions/gitnexus/observatory.js +189 -0
- package/dist/extensions/gitnexus/observatory.js.map +1 -0
- package/dist/extensions/gitnexus/prompt.d.ts +11 -0
- package/dist/extensions/gitnexus/prompt.d.ts.map +1 -0
- package/dist/extensions/gitnexus/prompt.js +50 -0
- package/dist/extensions/gitnexus/prompt.js.map +1 -0
- package/dist/extensions/gitnexus/render.d.ts +61 -0
- package/dist/extensions/gitnexus/render.d.ts.map +1 -0
- package/dist/extensions/gitnexus/render.js +391 -0
- package/dist/extensions/gitnexus/render.js.map +1 -0
- package/dist/extensions/gitnexus/resolve.d.ts +22 -0
- package/dist/extensions/gitnexus/resolve.d.ts.map +1 -0
- package/dist/extensions/gitnexus/resolve.js +54 -0
- package/dist/extensions/gitnexus/resolve.js.map +1 -0
- package/dist/extensions/gitnexus/skills/gitnexus-debugging/SKILL.md +89 -0
- package/dist/extensions/gitnexus/skills/gitnexus-debugging/mcp.json +8 -0
- package/dist/extensions/gitnexus/skills/gitnexus-exploring/SKILL.md +78 -0
- package/dist/extensions/gitnexus/skills/gitnexus-exploring/mcp.json +8 -0
- package/dist/extensions/gitnexus/skills/gitnexus-guide/SKILL.md +64 -0
- package/dist/extensions/gitnexus/skills/gitnexus-guide/mcp.json +8 -0
- package/dist/extensions/gitnexus/skills/gitnexus-impact-analysis/SKILL.md +97 -0
- package/dist/extensions/gitnexus/skills/gitnexus-impact-analysis/mcp.json +8 -0
- package/dist/extensions/gitnexus/skills/gitnexus-pr-review/SKILL.md +163 -0
- package/dist/extensions/gitnexus/skills/gitnexus-refactoring/SKILL.md +121 -0
- package/dist/extensions/gitnexus/skills/gitnexus-refactoring/mcp.json +8 -0
- package/dist/extensions/gitnexus/tools.d.ts +15 -0
- package/dist/extensions/gitnexus/tools.d.ts.map +1 -0
- package/dist/extensions/gitnexus/tools.js +187 -0
- package/dist/extensions/gitnexus/tools.js.map +1 -0
- package/dist/extensions/index.d.ts +3 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +10 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/llama/client.d.ts +61 -0
- package/dist/extensions/llama/client.d.ts.map +1 -0
- package/dist/extensions/llama/client.js +302 -0
- package/dist/extensions/llama/client.js.map +1 -0
- package/dist/extensions/llama/huggingface.d.ts +23 -0
- package/dist/extensions/llama/huggingface.d.ts.map +1 -0
- package/dist/extensions/llama/huggingface.js +141 -0
- package/dist/extensions/llama/huggingface.js.map +1 -0
- package/dist/extensions/llama/index.d.ts +3 -0
- package/dist/extensions/llama/index.d.ts.map +1 -0
- package/dist/extensions/llama/index.js +217 -0
- package/dist/extensions/llama/index.js.map +1 -0
- package/dist/extensions/llama/provider.d.ts +10 -0
- package/dist/extensions/llama/provider.d.ts.map +1 -0
- package/dist/extensions/llama/provider.js +121 -0
- package/dist/extensions/llama/provider.js.map +1 -0
- package/dist/extensions/llama/ui.d.ts +42 -0
- package/dist/extensions/llama/ui.d.ts.map +1 -0
- package/dist/extensions/llama/ui.js +416 -0
- package/dist/extensions/llama/ui.js.map +1 -0
- package/dist/extensions/mcp/client.d.ts +86 -0
- package/dist/extensions/mcp/client.d.ts.map +1 -0
- package/dist/extensions/mcp/client.js +275 -0
- package/dist/extensions/mcp/client.js.map +1 -0
- package/dist/extensions/mcp/config.d.ts +41 -0
- package/dist/extensions/mcp/config.d.ts.map +1 -0
- package/dist/extensions/mcp/config.js +85 -0
- package/dist/extensions/mcp/config.js.map +1 -0
- package/dist/extensions/mcp/index.d.ts +18 -0
- package/dist/extensions/mcp/index.d.ts.map +1 -0
- package/dist/extensions/mcp/index.js +95 -0
- package/dist/extensions/mcp/index.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69874 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +12 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +792 -0
- package/dist/main.js.map +1 -0
- package/dist/migrations.d.ts +33 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +281 -0
- package/dist/migrations.js.map +1 -0
- package/dist/modes/index.d.ts +10 -0
- package/dist/modes/index.d.ts.map +1 -0
- package/dist/modes/index.js +8 -0
- package/dist/modes/index.js.map +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +32 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/assistant-message.js +177 -0
- package/dist/modes/interactive/components/assistant-message.js.map +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +34 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/bash-execution.js +175 -0
- package/dist/modes/interactive/components/bash-execution.js.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.js +54 -0
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.js +44 -0
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/command-palette.d.ts +12 -0
- package/dist/modes/interactive/components/command-palette.d.ts.map +1 -0
- package/dist/modes/interactive/components/command-palette.js +67 -0
- package/dist/modes/interactive/components/command-palette.js.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/config-selector.d.ts +102 -0
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/config-selector.js +761 -0
- package/dist/modes/interactive/components/config-selector.js.map +1 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
- package/dist/modes/interactive/components/countdown-timer.js +33 -0
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts +23 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-editor.js +85 -0
- package/dist/modes/interactive/components/custom-editor.js.map +1 -0
- package/dist/modes/interactive/components/custom-entry.d.ts +19 -0
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-entry.js +52 -0
- package/dist/modes/interactive/components/custom-entry.js.map +1 -0
- package/dist/modes/interactive/components/custom-message.d.ts +22 -0
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-message.js +87 -0
- package/dist/modes/interactive/components/custom-message.js.map +1 -0
- package/dist/modes/interactive/components/dialog-frame.d.ts +37 -0
- package/dist/modes/interactive/components/dialog-frame.d.ts.map +1 -0
- package/dist/modes/interactive/components/dialog-frame.js +53 -0
- package/dist/modes/interactive/components/dialog-frame.js.map +1 -0
- package/dist/modes/interactive/components/diff.d.ts +12 -0
- package/dist/modes/interactive/components/diff.d.ts.map +1 -0
- package/dist/modes/interactive/components/diff.js +133 -0
- package/dist/modes/interactive/components/diff.js.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts +19 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.js +36 -0
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
- package/dist/modes/interactive/components/extension-editor.d.ts +21 -0
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-editor.js +98 -0
- package/dist/modes/interactive/components/extension-editor.js.map +1 -0
- package/dist/modes/interactive/components/extension-input.d.ts +23 -0
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-input.js +61 -0
- package/dist/modes/interactive/components/extension-input.js.map +1 -0
- package/dist/modes/interactive/components/extension-selector.d.ts +26 -0
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-selector.js +83 -0
- package/dist/modes/interactive/components/extension-selector.js.map +1 -0
- package/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -0
- package/dist/modes/interactive/components/first-time-setup.js +103 -0
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +30 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -0
- package/dist/modes/interactive/components/footer.js +108 -0
- package/dist/modes/interactive/components/footer.js.map +1 -0
- package/dist/modes/interactive/components/graph-rail.d.ts +44 -0
- package/dist/modes/interactive/components/graph-rail.d.ts.map +1 -0
- package/dist/modes/interactive/components/graph-rail.js +332 -0
- package/dist/modes/interactive/components/graph-rail.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +33 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -0
- package/dist/modes/interactive/components/index.js +34 -0
- package/dist/modes/interactive/components/index.js.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.js +36 -0
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
- package/dist/modes/interactive/components/landing-panel.d.ts +14 -0
- package/dist/modes/interactive/components/landing-panel.d.ts.map +1 -0
- package/dist/modes/interactive/components/landing-panel.js +141 -0
- package/dist/modes/interactive/components/landing-panel.js.map +1 -0
- package/dist/modes/interactive/components/login-dialog.d.ts +52 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
- package/dist/modes/interactive/components/login-dialog.js +188 -0
- package/dist/modes/interactive/components/login-dialog.js.map +1 -0
- package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
- package/dist/modes/interactive/components/markdown-transform.js +19 -0
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
- package/dist/modes/interactive/components/mermaid.d.ts +11 -0
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
- package/dist/modes/interactive/components/mermaid.js +80 -0
- package/dist/modes/interactive/components/mermaid.js.map +1 -0
- package/dist/modes/interactive/components/message-layout.d.ts +4 -0
- package/dist/modes/interactive/components/message-layout.d.ts.map +1 -0
- package/dist/modes/interactive/components/message-layout.js +4 -0
- package/dist/modes/interactive/components/message-layout.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +54 -0
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/model-selector.js +325 -0
- package/dist/modes/interactive/components/model-selector.js.map +1 -0
- package/dist/modes/interactive/components/nexus-logo.d.ts +25 -0
- package/dist/modes/interactive/components/nexus-logo.d.ts.map +1 -0
- package/dist/modes/interactive/components/nexus-logo.js +115 -0
- package/dist/modes/interactive/components/nexus-logo.js.map +1 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/oauth-selector.js +163 -0
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
- package/dist/modes/interactive/components/panel.d.ts +7 -0
- package/dist/modes/interactive/components/panel.d.ts.map +1 -0
- package/dist/modes/interactive/components/panel.js +18 -0
- package/dist/modes/interactive/components/panel.js.map +1 -0
- package/dist/modes/interactive/components/response-separator.d.ts +13 -0
- package/dist/modes/interactive/components/response-separator.d.ts.map +1 -0
- package/dist/modes/interactive/components/response-separator.js +23 -0
- package/dist/modes/interactive/components/response-separator.js.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +46 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.js +328 -0
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.js +155 -0
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
- package/dist/modes/interactive/components/session-selector.d.ts +99 -0
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector.js +887 -0
- package/dist/modes/interactive/components/session-selector.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +81 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-selector.js +613 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/show-images-selector.js +39 -0
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
- package/dist/modes/interactive/components/status-indicator.d.ts +37 -0
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -0
- package/dist/modes/interactive/components/status-indicator.js +116 -0
- package/dist/modes/interactive/components/status-indicator.js.map +1 -0
- package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/theme-selector.js +50 -0
- package/dist/modes/interactive/components/theme-selector.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.js +52 -0
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +70 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-execution.js +384 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -0
- package/dist/modes/interactive/components/tree-selector.d.ts +94 -0
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/tree-selector.js +1245 -0
- package/dist/modes/interactive/components/tree-selector.js.map +1 -0
- package/dist/modes/interactive/components/trust-selector.d.ts +23 -0
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/trust-selector.js +91 -0
- package/dist/modes/interactive/components/trust-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.js +114 -0
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message.d.ts +17 -0
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/user-message.js +51 -0
- package/dist/modes/interactive/components/user-message.js.map +1 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
- package/dist/modes/interactive/components/visual-truncate.js +33 -0
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
- package/dist/modes/interactive/external-editor.d.ts +12 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -0
- package/dist/modes/interactive/external-editor.js +37 -0
- package/dist/modes/interactive/external-editor.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +436 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-mode.js +5462 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -0
- package/dist/modes/interactive/model-search.d.ts +12 -0
- package/dist/modes/interactive/model-search.d.ts.map +1 -0
- package/dist/modes/interactive/model-search.js +15 -0
- package/dist/modes/interactive/model-search.js.map +1 -0
- package/dist/modes/interactive/theme/brand.d.ts +38 -0
- package/dist/modes/interactive/theme/brand.d.ts.map +1 -0
- package/dist/modes/interactive/theme/brand.js +108 -0
- package/dist/modes/interactive/theme/brand.js.map +1 -0
- package/dist/modes/interactive/theme/catppuccin-mocha.json +66 -0
- package/dist/modes/interactive/theme/dark.json +93 -0
- package/dist/modes/interactive/theme/dracula.json +66 -0
- package/dist/modes/interactive/theme/ember.json +85 -0
- package/dist/modes/interactive/theme/gruvbox.json +66 -0
- package/dist/modes/interactive/theme/light.json +91 -0
- package/dist/modes/interactive/theme/nord.json +66 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +32 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme-controller.js +111 -0
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -0
- package/dist/modes/interactive/theme/theme-schema.json +344 -0
- package/dist/modes/interactive/theme/theme.d.ts +129 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme.js +1101 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -0
- package/dist/modes/interactive/theme/tokyonight.json +66 -0
- package/dist/modes/json-event.d.ts +28 -0
- package/dist/modes/json-event.d.ts.map +1 -0
- package/dist/modes/json-event.js +12 -0
- package/dist/modes/json-event.js.map +1 -0
- package/dist/modes/print-mode.d.ts +28 -0
- package/dist/modes/print-mode.d.ts.map +1 -0
- package/dist/modes/print-mode.js +153 -0
- package/dist/modes/print-mode.js.map +1 -0
- package/dist/modes/rpc/jsonl.d.ts +17 -0
- package/dist/modes/rpc/jsonl.d.ts.map +1 -0
- package/dist/modes/rpc/jsonl.js +49 -0
- package/dist/modes/rpc/jsonl.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +247 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-client.js +488 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts +20 -0
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-mode.js +654 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -0
- package/dist/modes/rpc/rpc-types.d.ts +457 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-types.js +8 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -0
- package/dist/package-manager-cli.d.ts +8 -0
- package/dist/package-manager-cli.d.ts.map +1 -0
- package/dist/package-manager-cli.js +777 -0
- package/dist/package-manager-cli.js.map +1 -0
- package/dist/rpc-entry.d.ts +3 -0
- package/dist/rpc-entry.d.ts.map +1 -0
- package/dist/rpc-entry.js +69740 -0
- package/dist/rpc-entry.js.map +1 -0
- package/dist/utils/abort.d.ts +5 -0
- package/dist/utils/abort.d.ts.map +1 -0
- package/dist/utils/abort.js +48 -0
- package/dist/utils/abort.js.map +1 -0
- package/dist/utils/ansi.d.ts +2 -0
- package/dist/utils/ansi.d.ts.map +1 -0
- package/dist/utils/ansi.js +52 -0
- package/dist/utils/ansi.js.map +1 -0
- package/dist/utils/child-process.d.ts +18 -0
- package/dist/utils/child-process.d.ts.map +1 -0
- package/dist/utils/child-process.js +106 -0
- package/dist/utils/child-process.js.map +1 -0
- package/dist/utils/clipboard-image.d.ts +11 -0
- package/dist/utils/clipboard-image.d.ts.map +1 -0
- package/dist/utils/clipboard-image.js +245 -0
- package/dist/utils/clipboard-image.js.map +1 -0
- package/dist/utils/clipboard-native.d.ts +11 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -0
- package/dist/utils/clipboard-native.js +20 -0
- package/dist/utils/clipboard-native.js.map +1 -0
- package/dist/utils/clipboard.d.ts +4 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/dist/utils/clipboard.js +161 -0
- package/dist/utils/clipboard.js.map +1 -0
- package/dist/utils/deprecation.d.ts +4 -0
- package/dist/utils/deprecation.d.ts.map +1 -0
- package/dist/utils/deprecation.js +13 -0
- package/dist/utils/deprecation.js.map +1 -0
- package/dist/utils/exif-orientation.d.ts +5 -0
- package/dist/utils/exif-orientation.d.ts.map +1 -0
- package/dist/utils/exif-orientation.js +158 -0
- package/dist/utils/exif-orientation.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +8 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +26 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/fs-watch.d.ts +5 -0
- package/dist/utils/fs-watch.d.ts.map +1 -0
- package/dist/utils/fs-watch.js +25 -0
- package/dist/utils/fs-watch.js.map +1 -0
- package/dist/utils/git.d.ts +26 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +195 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/html.d.ts +7 -0
- package/dist/utils/html.d.ts.map +1 -0
- package/dist/utils/html.js +40 -0
- package/dist/utils/html.js.map +1 -0
- package/dist/utils/image-convert.d.ts +10 -0
- package/dist/utils/image-convert.d.ts.map +1 -0
- package/dist/utils/image-convert.js +45 -0
- package/dist/utils/image-convert.js.map +1 -0
- package/dist/utils/image-process.d.ts +18 -0
- package/dist/utils/image-process.d.ts.map +1 -0
- package/dist/utils/image-process.js +83 -0
- package/dist/utils/image-process.js.map +1 -0
- package/dist/utils/image-resize-core.d.ts +30 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -0
- package/dist/utils/image-resize-core.js +124 -0
- package/dist/utils/image-resize-core.js.map +1 -0
- package/dist/utils/image-resize-worker.d.ts +2 -0
- package/dist/utils/image-resize-worker.d.ts.map +1 -0
- package/dist/utils/image-resize-worker.js +31 -0
- package/dist/utils/image-resize-worker.js.map +1 -0
- package/dist/utils/image-resize.d.ts +16 -0
- package/dist/utils/image-resize.d.ts.map +1 -0
- package/dist/utils/image-resize.js +97 -0
- package/dist/utils/image-resize.js.map +1 -0
- package/dist/utils/json.d.ts +3 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +7 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/management-http.d.ts +23 -0
- package/dist/utils/management-http.d.ts.map +1 -0
- package/dist/utils/management-http.js +50 -0
- package/dist/utils/management-http.js.map +1 -0
- package/dist/utils/mime.d.ts +3 -0
- package/dist/utils/mime.d.ts.map +1 -0
- package/dist/utils/mime.js +110 -0
- package/dist/utils/mime.js.map +1 -0
- package/dist/utils/open-browser.d.ts +9 -0
- package/dist/utils/open-browser.d.ts.map +1 -0
- package/dist/utils/open-browser.js +22 -0
- package/dist/utils/open-browser.js.map +1 -0
- package/dist/utils/paths.d.ts +34 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +114 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/photon.d.ts +21 -0
- package/dist/utils/photon.d.ts.map +1 -0
- package/dist/utils/photon.js +121 -0
- package/dist/utils/photon.js.map +1 -0
- package/dist/utils/pi-user-agent.d.ts +2 -0
- package/dist/utils/pi-user-agent.d.ts.map +1 -0
- package/dist/utils/pi-user-agent.js +5 -0
- package/dist/utils/pi-user-agent.js.map +1 -0
- package/dist/utils/shell.d.ts +31 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +202 -0
- package/dist/utils/shell.js.map +1 -0
- package/dist/utils/sleep.d.ts +5 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/dist/utils/sleep.js +17 -0
- package/dist/utils/sleep.js.map +1 -0
- package/dist/utils/syntax-highlight.d.ts +12 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -0
- package/dist/utils/syntax-highlight.js +118 -0
- package/dist/utils/syntax-highlight.js.map +1 -0
- package/dist/utils/tool-result-images.d.ts +19 -0
- package/dist/utils/tool-result-images.d.ts.map +1 -0
- package/dist/utils/tool-result-images.js +45 -0
- package/dist/utils/tool-result-images.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +3 -0
- package/dist/utils/tools-manager.d.ts.map +1 -0
- package/dist/utils/tools-manager.js +326 -0
- package/dist/utils/tools-manager.js.map +1 -0
- package/dist/utils/version-check.d.ts +19 -0
- package/dist/utils/version-check.d.ts.map +1 -0
- package/dist/utils/version-check.js +98 -0
- package/dist/utils/version-check.js.map +1 -0
- package/dist/utils/windows-self-update.d.ts +3 -0
- package/dist/utils/windows-self-update.d.ts.map +1 -0
- package/dist/utils/windows-self-update.js +77 -0
- package/dist/utils/windows-self-update.js.map +1 -0
- package/docs/compaction.md +401 -0
- package/docs/containerization.md +111 -0
- package/docs/custom-provider.md +774 -0
- package/docs/development.md +71 -0
- package/docs/docs.json +156 -0
- package/docs/environment-variables.md +98 -0
- package/docs/extensions.md +2987 -0
- package/docs/images/doom-extension.png +0 -0
- package/docs/images/exy.png +0 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/images/tree-view.png +0 -0
- package/docs/index.md +84 -0
- package/docs/json.md +91 -0
- package/docs/keybindings.md +226 -0
- package/docs/llama-cpp.md +99 -0
- package/docs/models.md +565 -0
- package/docs/packages.md +228 -0
- package/docs/prompt-templates.md +96 -0
- package/docs/providers.md +310 -0
- package/docs/quickstart.md +167 -0
- package/docs/rpc.md +1578 -0
- package/docs/sdk.md +1205 -0
- package/docs/security.md +59 -0
- package/docs/session-format.md +438 -0
- package/docs/sessions.md +145 -0
- package/docs/settings.md +322 -0
- package/docs/shell-aliases.md +13 -0
- package/docs/skills.md +231 -0
- package/docs/terminal-setup.md +142 -0
- package/docs/termux.md +127 -0
- package/docs/themes.md +299 -0
- package/docs/tmux.md +63 -0
- package/docs/tui.md +942 -0
- package/docs/usage.md +305 -0
- package/docs/windows.md +17 -0
- package/examples/README.md +25 -0
- package/examples/extensions/README.md +213 -0
- package/examples/extensions/auto-commit-on-exit.ts +49 -0
- package/examples/extensions/bash-spawn-hook.ts +30 -0
- package/examples/extensions/bookmark.ts +50 -0
- package/examples/extensions/border-status-editor.ts +150 -0
- package/examples/extensions/built-in-tool-renderer.ts +249 -0
- package/examples/extensions/claude-rules.ts +86 -0
- package/examples/extensions/commands.ts +72 -0
- package/examples/extensions/confirm-destructive.ts +59 -0
- package/examples/extensions/custom-compaction.ts +117 -0
- package/examples/extensions/custom-footer.ts +64 -0
- package/examples/extensions/custom-header.ts +73 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +611 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
- package/examples/extensions/custom-provider-anthropic/package.json +19 -0
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +405 -0
- package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
- package/examples/extensions/dirty-repo-guard.ts +56 -0
- package/examples/extensions/doom-overlay/README.md +46 -0
- package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
- package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
- package/examples/extensions/doom-overlay/doom/build.sh +152 -0
- package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
- package/examples/extensions/doom-overlay/doom-component.ts +132 -0
- package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
- package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
- package/examples/extensions/doom-overlay/index.ts +74 -0
- package/examples/extensions/doom-overlay/wad-finder.ts +55 -0
- package/examples/extensions/dynamic-resources/SKILL.md +8 -0
- package/examples/extensions/dynamic-resources/dynamic.json +79 -0
- package/examples/extensions/dynamic-resources/dynamic.md +5 -0
- package/examples/extensions/dynamic-resources/index.ts +15 -0
- package/examples/extensions/dynamic-tools.ts +74 -0
- package/examples/extensions/entry-renderer.ts +41 -0
- package/examples/extensions/event-bus.ts +43 -0
- package/examples/extensions/file-trigger.ts +41 -0
- package/examples/extensions/git-checkpoint.ts +53 -0
- package/examples/extensions/git-merge-and-resolve.ts +115 -0
- package/examples/extensions/github-issue-autocomplete.ts +185 -0
- package/examples/extensions/gondolin/index.ts +531 -0
- package/examples/extensions/gondolin/package-lock.json +185 -0
- package/examples/extensions/gondolin/package.json +19 -0
- package/examples/extensions/handoff.ts +190 -0
- package/examples/extensions/hello.ts +26 -0
- package/examples/extensions/hidden-thinking-label.ts +53 -0
- package/examples/extensions/inline-bash.ts +94 -0
- package/examples/extensions/input-transform-streaming.ts +39 -0
- package/examples/extensions/input-transform.ts +43 -0
- package/examples/extensions/interactive-shell.ts +196 -0
- package/examples/extensions/kimi-deferred-tools.ts +61 -0
- package/examples/extensions/mac-system-theme.ts +47 -0
- package/examples/extensions/message-renderer.ts +59 -0
- package/examples/extensions/minimal-mode.ts +426 -0
- package/examples/extensions/modal-editor.ts +85 -0
- package/examples/extensions/model-status.ts +31 -0
- package/examples/extensions/notify.ts +55 -0
- package/examples/extensions/overlay-qa-tests.ts +1450 -0
- package/examples/extensions/overlay-test.ts +153 -0
- package/examples/extensions/permission-gate.ts +34 -0
- package/examples/extensions/pirate.ts +47 -0
- package/examples/extensions/plan-mode/README.md +66 -0
- package/examples/extensions/plan-mode/index.ts +390 -0
- package/examples/extensions/plan-mode/utils.ts +168 -0
- package/examples/extensions/preset.ts +436 -0
- package/examples/extensions/project-trust.ts +64 -0
- package/examples/extensions/prompt-customizer.ts +97 -0
- package/examples/extensions/protected-paths.ts +30 -0
- package/examples/extensions/provider-payload.ts +18 -0
- package/examples/extensions/qna.ts +118 -0
- package/examples/extensions/question.ts +286 -0
- package/examples/extensions/questionnaire.ts +448 -0
- package/examples/extensions/rainbow-editor.ts +88 -0
- package/examples/extensions/reload-runtime.ts +37 -0
- package/examples/extensions/rpc-demo.ts +118 -0
- package/examples/extensions/sandbox/index.ts +321 -0
- package/examples/extensions/sandbox/package-lock.json +92 -0
- package/examples/extensions/sandbox/package.json +19 -0
- package/examples/extensions/send-user-message.ts +97 -0
- package/examples/extensions/session-name.ts +27 -0
- package/examples/extensions/shutdown-command.ts +63 -0
- package/examples/extensions/snake.ts +343 -0
- package/examples/extensions/space-invaders.ts +560 -0
- package/examples/extensions/ssh.ts +220 -0
- package/examples/extensions/status-line.ts +32 -0
- package/examples/extensions/structured-output.ts +65 -0
- package/examples/extensions/subagent/README.md +175 -0
- package/examples/extensions/subagent/agents/planner.md +37 -0
- package/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/examples/extensions/subagent/agents/scout.md +50 -0
- package/examples/extensions/subagent/agents/worker.md +24 -0
- package/examples/extensions/subagent/agents.ts +126 -0
- package/examples/extensions/subagent/index.ts +1015 -0
- package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/examples/extensions/subagent/prompts/implement.md +10 -0
- package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/examples/extensions/summarize.ts +199 -0
- package/examples/extensions/system-prompt-header.ts +17 -0
- package/examples/extensions/tic-tac-toe.ts +1008 -0
- package/examples/extensions/timed-confirm.ts +70 -0
- package/examples/extensions/titlebar-spinner.ts +58 -0
- package/examples/extensions/todo.ts +297 -0
- package/examples/extensions/tool-override.ts +144 -0
- package/examples/extensions/tools.ts +146 -0
- package/examples/extensions/trigger-compact.ts +50 -0
- package/examples/extensions/truncated-tool.ts +195 -0
- package/examples/extensions/widget-placement.ts +9 -0
- package/examples/extensions/with-deps/index.ts +32 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +22 -0
- package/examples/extensions/working-indicator.ts +123 -0
- package/examples/extensions/working-message-test.ts +25 -0
- package/examples/rpc-extension-ui.ts +641 -0
- package/examples/sdk/01-minimal.ts +26 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +75 -0
- package/examples/sdk/04-skills.ts +55 -0
- package/examples/sdk/05-tools.ts +48 -0
- package/examples/sdk/06-extensions.ts +99 -0
- package/examples/sdk/07-context-files.ts +47 -0
- package/examples/sdk/08-prompt-templates.ts +51 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +34 -0
- package/examples/sdk/10-settings.ts +53 -0
- package/examples/sdk/11-sessions.ts +52 -0
- package/examples/sdk/12-full-control.ts +74 -0
- package/examples/sdk/13-session-runtime.ts +67 -0
- package/examples/sdk/README.md +140 -0
- package/npm-shrinkwrap.json +1817 -0
- package/package.json +145 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-totals.js","sourceRoot":"","sources":["../../src/core/usage-totals.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Usage } from \"@earendil-works/pi-ai/compat\";\nimport type { SessionEntry } from \"./session-manager.ts\";\n\nexport interface UsageTotals {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: number;\n}\n\nexport function createUsageTotals(): UsageTotals {\n\treturn {\n\t\tinput: 0,\n\t\toutput: 0,\n\t\tcacheRead: 0,\n\t\tcacheWrite: 0,\n\t\tcost: 0,\n\t};\n}\n\nexport function addUsageToTotals(totals: UsageTotals, usage: Usage): void {\n\ttotals.input += usage.input;\n\ttotals.output += usage.output;\n\ttotals.cacheRead += usage.cacheRead;\n\ttotals.cacheWrite += usage.cacheWrite;\n\ttotals.cost += usage.cost.total;\n}\n\nexport interface UsageCostBreakdownEntry {\n\tkey: string;\n\tcost: number;\n\ttokens: number;\n}\n\n/** Group attributable assistant usage by model and all other usage into a separate bucket. */\nexport function getUsageCostBreakdown(entries: SessionEntry[]): UsageCostBreakdownEntry[] {\n\tconst totalsByKey = new Map<string, UsageTotals>();\n\n\tfor (const entry of entries) {\n\t\tlet key: string | undefined;\n\t\tlet usage: Usage | undefined;\n\t\tif (entry.type === \"message\" && entry.message.role === \"assistant\") {\n\t\t\tkey = `${entry.message.provider}/${entry.message.responseModel ?? entry.message.model}`;\n\t\t\tusage = entry.message.usage;\n\t\t} else if (entry.type === \"message\" && entry.message.role === \"toolResult\" && entry.message.usage) {\n\t\t\tkey = \"Tools/summaries\";\n\t\t\tusage = entry.message.usage;\n\t\t} else if ((entry.type === \"branch_summary\" || entry.type === \"compaction\") && entry.usage) {\n\t\t\tkey = \"Tools/summaries\";\n\t\t\tusage = entry.usage;\n\t\t}\n\t\tif (!key || !usage) continue;\n\n\t\tlet totals = totalsByKey.get(key);\n\t\tif (!totals) {\n\t\t\ttotals = createUsageTotals();\n\t\t\ttotalsByKey.set(key, totals);\n\t\t}\n\t\taddUsageToTotals(totals, usage);\n\t}\n\n\treturn Array.from(totalsByKey, ([key, totals]) => ({\n\t\tkey,\n\t\tcost: totals.cost,\n\t\ttokens: totals.input + totals.output + totals.cacheRead + totals.cacheWrite,\n\t}))\n\t\t.filter((entry) => entry.cost > 0 || entry.tokens > 0)\n\t\t.sort((a, b) => b.cost - a.cost);\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "../../core/extensions/types.ts";
|
|
2
|
+
import { GitNexusClient } from "./client.ts";
|
|
3
|
+
export declare function registerAugmentedGrep(pi: ExtensionAPI, cwd: string, getClient: () => GitNexusClient | undefined, currentRepo: () => string | undefined): void;
|
|
4
|
+
//# sourceMappingURL=augment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"augment.d.ts","sourceRoot":"","sources":["../../../src/extensions/gitnexus/augment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAe7C,wBAAgB,qBAAqB,CACpC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,cAAc,GAAG,SAAS,EAC3C,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS,GACnC,IAAI,CAiDN","sourcesContent":["import type { ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { createGrepToolDefinition } from \"../../core/tools/index.ts\";\nimport { GitNexusClient } from \"./client.ts\";\n\n/**\n * native_augment: enrich grep results with graph context, mirroring the\n * Claude Code plugin's PreToolUse hook (gitnexus-claude-plugin/hooks) — except\n * the context comes from the hub, not a local .gitnexus DB.\n *\n * Conservative by design: pattern >= 3 chars, one augment per unique pattern\n * per session, ~3s budget, silent on any failure.\n */\n\nconst AUGMENT_TIMEOUT_MS = 3_000;\nconst AUGMENT_MAX_CHARS = 1_500;\nconst MIN_PATTERN_LENGTH = 3;\n\nexport function registerAugmentedGrep(\n\tpi: ExtensionAPI,\n\tcwd: string,\n\tgetClient: () => GitNexusClient | undefined,\n\tcurrentRepo: () => string | undefined,\n): void {\n\tconst seenPatterns = new Set<string>();\n\tconst grep = createGrepToolDefinition(cwd);\n\n\tpi.registerTool({\n\t\t...grep,\n\t\texecute: async (id, params, signal, onUpdate, ctx) => {\n\t\t\tconst result = await grep.execute(id, params, signal, onUpdate, ctx);\n\t\t\ttry {\n\t\t\t\tconst client = getClient();\n\t\t\t\tconst repo = currentRepo();\n\t\t\t\tconst pattern = String((params as { pattern?: unknown })?.pattern ?? \"\").trim();\n\t\t\t\tif (!client || !repo || pattern.length < MIN_PATTERN_LENGTH || seenPatterns.has(pattern)) return result;\n\t\t\t\tseenPatterns.add(pattern);\n\n\t\t\t\tconst abort = new AbortController();\n\t\t\t\tconst timer = setTimeout(() => abort.abort(), AUGMENT_TIMEOUT_MS);\n\t\t\t\tlet graphText: string;\n\t\t\t\ttry {\n\t\t\t\t\tconst hubResult = await client.callTool(\n\t\t\t\t\t\t\"query\",\n\t\t\t\t\t\t{ query: pattern, repo, limit: 2, max_symbols: 5 },\n\t\t\t\t\t\tabort.signal,\n\t\t\t\t\t);\n\t\t\t\t\tgraphText = GitNexusClient.text(hubResult);\n\t\t\t\t} finally {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t}\n\t\t\t\tif (!graphText.trim()) return result;\n\n\t\t\t\tconst trimmed =\n\t\t\t\t\tgraphText.length > AUGMENT_MAX_CHARS\n\t\t\t\t\t\t? `${graphText.slice(0, AUGMENT_MAX_CHARS)}\\n…(truncated)`\n\t\t\t\t\t\t: graphText;\n\t\t\t\treturn {\n\t\t\t\t\t...result,\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t...result.content,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `\\n── GitNexus graph context for \"${pattern}\" (${repo}) ──\\n${trimmed}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t} catch {\n\t\t\t\treturn result; // augmentation must never break grep\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createGrepToolDefinition } from "../../core/tools/index.js";
|
|
2
|
+
import { GitNexusClient } from "./client.js";
|
|
3
|
+
/**
|
|
4
|
+
* native_augment: enrich grep results with graph context, mirroring the
|
|
5
|
+
* Claude Code plugin's PreToolUse hook (gitnexus-claude-plugin/hooks) — except
|
|
6
|
+
* the context comes from the hub, not a local .gitnexus DB.
|
|
7
|
+
*
|
|
8
|
+
* Conservative by design: pattern >= 3 chars, one augment per unique pattern
|
|
9
|
+
* per session, ~3s budget, silent on any failure.
|
|
10
|
+
*/
|
|
11
|
+
const AUGMENT_TIMEOUT_MS = 3_000;
|
|
12
|
+
const AUGMENT_MAX_CHARS = 1_500;
|
|
13
|
+
const MIN_PATTERN_LENGTH = 3;
|
|
14
|
+
export function registerAugmentedGrep(pi, cwd, getClient, currentRepo) {
|
|
15
|
+
const seenPatterns = new Set();
|
|
16
|
+
const grep = createGrepToolDefinition(cwd);
|
|
17
|
+
pi.registerTool({
|
|
18
|
+
...grep,
|
|
19
|
+
execute: async (id, params, signal, onUpdate, ctx) => {
|
|
20
|
+
const result = await grep.execute(id, params, signal, onUpdate, ctx);
|
|
21
|
+
try {
|
|
22
|
+
const client = getClient();
|
|
23
|
+
const repo = currentRepo();
|
|
24
|
+
const pattern = String(params?.pattern ?? "").trim();
|
|
25
|
+
if (!client || !repo || pattern.length < MIN_PATTERN_LENGTH || seenPatterns.has(pattern))
|
|
26
|
+
return result;
|
|
27
|
+
seenPatterns.add(pattern);
|
|
28
|
+
const abort = new AbortController();
|
|
29
|
+
const timer = setTimeout(() => abort.abort(), AUGMENT_TIMEOUT_MS);
|
|
30
|
+
let graphText;
|
|
31
|
+
try {
|
|
32
|
+
const hubResult = await client.callTool("query", { query: pattern, repo, limit: 2, max_symbols: 5 }, abort.signal);
|
|
33
|
+
graphText = GitNexusClient.text(hubResult);
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
clearTimeout(timer);
|
|
37
|
+
}
|
|
38
|
+
if (!graphText.trim())
|
|
39
|
+
return result;
|
|
40
|
+
const trimmed = graphText.length > AUGMENT_MAX_CHARS
|
|
41
|
+
? `${graphText.slice(0, AUGMENT_MAX_CHARS)}\n…(truncated)`
|
|
42
|
+
: graphText;
|
|
43
|
+
return {
|
|
44
|
+
...result,
|
|
45
|
+
content: [
|
|
46
|
+
...result.content,
|
|
47
|
+
{
|
|
48
|
+
type: "text",
|
|
49
|
+
text: `\n── GitNexus graph context for "${pattern}" (${repo}) ──\n${trimmed}`,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return result; // augmentation must never break grep
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=augment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"augment.js","sourceRoot":"","sources":["../../../src/extensions/gitnexus/augment.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;;GAOG;AAEH,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACjC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAChC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B,MAAM,UAAU,qBAAqB,CACpC,EAAgB,EAChB,GAAW,EACX,SAA2C,EAC3C,WAAqC,EAC9B;IACP,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,MAAM,IAAI,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;IAE3C,EAAE,CAAC,YAAY,CAAC;QACf,GAAG,IAAI;QACP,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;YACrE,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;gBAC3B,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;gBAC3B,MAAM,OAAO,GAAG,MAAM,CAAE,MAAgC,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBAChF,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,GAAG,kBAAkB,IAAI,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;oBAAE,OAAO,MAAM,CAAC;gBACxG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAE1B,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;gBACpC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,kBAAkB,CAAC,CAAC;gBAClE,IAAI,SAAiB,CAAC;gBACtB,IAAI,CAAC;oBACJ,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,QAAQ,CACtC,OAAO,EACP,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,EAClD,KAAK,CAAC,MAAM,CACZ,CAAC;oBACF,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC5C,CAAC;wBAAS,CAAC;oBACV,YAAY,CAAC,KAAK,CAAC,CAAC;gBACrB,CAAC;gBACD,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;oBAAE,OAAO,MAAM,CAAC;gBAErC,MAAM,OAAO,GACZ,SAAS,CAAC,MAAM,GAAG,iBAAiB;oBACnC,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,kBAAgB;oBAC1D,CAAC,CAAC,SAAS,CAAC;gBACd,OAAO;oBACN,GAAG,MAAM;oBACT,OAAO,EAAE;wBACR,GAAG,MAAM,CAAC,OAAO;wBACjB;4BACC,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,wCAAoC,OAAO,MAAM,IAAI,aAAS,OAAO,EAAE;yBAC7E;qBACD;iBACD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,MAAM,CAAC,CAAC,qCAAqC;YACrD,CAAC;QAAA,CACD;KACD,CAAC,CAAC;AAAA,CACH","sourcesContent":["import type { ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { createGrepToolDefinition } from \"../../core/tools/index.ts\";\nimport { GitNexusClient } from \"./client.ts\";\n\n/**\n * native_augment: enrich grep results with graph context, mirroring the\n * Claude Code plugin's PreToolUse hook (gitnexus-claude-plugin/hooks) — except\n * the context comes from the hub, not a local .gitnexus DB.\n *\n * Conservative by design: pattern >= 3 chars, one augment per unique pattern\n * per session, ~3s budget, silent on any failure.\n */\n\nconst AUGMENT_TIMEOUT_MS = 3_000;\nconst AUGMENT_MAX_CHARS = 1_500;\nconst MIN_PATTERN_LENGTH = 3;\n\nexport function registerAugmentedGrep(\n\tpi: ExtensionAPI,\n\tcwd: string,\n\tgetClient: () => GitNexusClient | undefined,\n\tcurrentRepo: () => string | undefined,\n): void {\n\tconst seenPatterns = new Set<string>();\n\tconst grep = createGrepToolDefinition(cwd);\n\n\tpi.registerTool({\n\t\t...grep,\n\t\texecute: async (id, params, signal, onUpdate, ctx) => {\n\t\t\tconst result = await grep.execute(id, params, signal, onUpdate, ctx);\n\t\t\ttry {\n\t\t\t\tconst client = getClient();\n\t\t\t\tconst repo = currentRepo();\n\t\t\t\tconst pattern = String((params as { pattern?: unknown })?.pattern ?? \"\").trim();\n\t\t\t\tif (!client || !repo || pattern.length < MIN_PATTERN_LENGTH || seenPatterns.has(pattern)) return result;\n\t\t\t\tseenPatterns.add(pattern);\n\n\t\t\t\tconst abort = new AbortController();\n\t\t\t\tconst timer = setTimeout(() => abort.abort(), AUGMENT_TIMEOUT_MS);\n\t\t\t\tlet graphText: string;\n\t\t\t\ttry {\n\t\t\t\t\tconst hubResult = await client.callTool(\n\t\t\t\t\t\t\"query\",\n\t\t\t\t\t\t{ query: pattern, repo, limit: 2, max_symbols: 5 },\n\t\t\t\t\t\tabort.signal,\n\t\t\t\t\t);\n\t\t\t\t\tgraphText = GitNexusClient.text(hubResult);\n\t\t\t\t} finally {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t}\n\t\t\t\tif (!graphText.trim()) return result;\n\n\t\t\t\tconst trimmed =\n\t\t\t\t\tgraphText.length > AUGMENT_MAX_CHARS\n\t\t\t\t\t\t? `${graphText.slice(0, AUGMENT_MAX_CHARS)}\\n…(truncated)`\n\t\t\t\t\t\t: graphText;\n\t\t\t\treturn {\n\t\t\t\t\t...result,\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t...result.content,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `\\n── GitNexus graph context for \"${pattern}\" (${repo}) ──\\n${trimmed}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t} catch {\n\t\t\t\treturn result; // augmentation must never break grep\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../../../src/extensions/gitnexus/changes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAoBnE,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAmC1E","sourcesContent":["import type { ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { graphRailStore } from \"../../core/graph-rail-store.ts\";\nimport { createEditToolDefinition, createWriteToolDefinition } from \"../../core/tools/index.ts\";\n\n/**\n * Wrap the edit/write tools to record per-file diffstats for the side rail.\n * Pure observation — results pass through untouched.\n */\n\nfunction countDiff(diff: string | undefined): { added: number; removed: number } {\n\tif (!diff) return { added: 0, removed: 0 };\n\tlet added = 0;\n\tlet removed = 0;\n\tfor (const line of diff.split(\"\\n\")) {\n\t\tif (line.startsWith(\"+\") && !line.startsWith(\"+++\")) added++;\n\t\telse if (line.startsWith(\"-\") && !line.startsWith(\"---\")) removed++;\n\t}\n\treturn { added, removed };\n}\n\nexport function registerChangeTracking(pi: ExtensionAPI, cwd: string): void {\n\tconst edit = createEditToolDefinition(cwd);\n\tconst write = createWriteToolDefinition(cwd);\n\n\tpi.registerTool({\n\t\t...edit,\n\t\texecute: async (id, params, signal, onUpdate, ctx) => {\n\t\t\tconst result = await edit.execute(id, params, signal, onUpdate, ctx);\n\t\t\ttry {\n\t\t\t\tconst path = String((params as { path?: unknown })?.path ?? \"\");\n\t\t\t\tconst diff = (result.details as { diff?: string } | undefined)?.diff;\n\t\t\t\tconst { added, removed } = countDiff(diff);\n\t\t\t\tif (path && (added > 0 || removed > 0)) graphRailStore.recordChange(path, added, removed);\n\t\t\t} catch {\n\t\t\t\t// observation only\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t});\n\n\tpi.registerTool({\n\t\t...write,\n\t\texecute: async (id, params, signal, onUpdate, ctx) => {\n\t\t\tconst result = await write.execute(id, params, signal, onUpdate, ctx);\n\t\t\ttry {\n\t\t\t\tconst p = params as { path?: unknown; content?: unknown };\n\t\t\t\tconst path = String(p?.path ?? \"\");\n\t\t\t\tconst lineCount = String(p?.content ?? \"\").split(\"\\n\").length;\n\t\t\t\tif (path) graphRailStore.recordChange(path, lineCount, 0);\n\t\t\t} catch {\n\t\t\t\t// observation only\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t});\n}\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { graphRailStore } from "../../core/graph-rail-store.js";
|
|
2
|
+
import { createEditToolDefinition, createWriteToolDefinition } from "../../core/tools/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Wrap the edit/write tools to record per-file diffstats for the side rail.
|
|
5
|
+
* Pure observation — results pass through untouched.
|
|
6
|
+
*/
|
|
7
|
+
function countDiff(diff) {
|
|
8
|
+
if (!diff)
|
|
9
|
+
return { added: 0, removed: 0 };
|
|
10
|
+
let added = 0;
|
|
11
|
+
let removed = 0;
|
|
12
|
+
for (const line of diff.split("\n")) {
|
|
13
|
+
if (line.startsWith("+") && !line.startsWith("+++"))
|
|
14
|
+
added++;
|
|
15
|
+
else if (line.startsWith("-") && !line.startsWith("---"))
|
|
16
|
+
removed++;
|
|
17
|
+
}
|
|
18
|
+
return { added, removed };
|
|
19
|
+
}
|
|
20
|
+
export function registerChangeTracking(pi, cwd) {
|
|
21
|
+
const edit = createEditToolDefinition(cwd);
|
|
22
|
+
const write = createWriteToolDefinition(cwd);
|
|
23
|
+
pi.registerTool({
|
|
24
|
+
...edit,
|
|
25
|
+
execute: async (id, params, signal, onUpdate, ctx) => {
|
|
26
|
+
const result = await edit.execute(id, params, signal, onUpdate, ctx);
|
|
27
|
+
try {
|
|
28
|
+
const path = String(params?.path ?? "");
|
|
29
|
+
const diff = result.details?.diff;
|
|
30
|
+
const { added, removed } = countDiff(diff);
|
|
31
|
+
if (path && (added > 0 || removed > 0))
|
|
32
|
+
graphRailStore.recordChange(path, added, removed);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// observation only
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
pi.registerTool({
|
|
41
|
+
...write,
|
|
42
|
+
execute: async (id, params, signal, onUpdate, ctx) => {
|
|
43
|
+
const result = await write.execute(id, params, signal, onUpdate, ctx);
|
|
44
|
+
try {
|
|
45
|
+
const p = params;
|
|
46
|
+
const path = String(p?.path ?? "");
|
|
47
|
+
const lineCount = String(p?.content ?? "").split("\n").length;
|
|
48
|
+
if (path)
|
|
49
|
+
graphRailStore.recordChange(path, lineCount, 0);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// observation only
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=changes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changes.js","sourceRoot":"","sources":["../../../src/extensions/gitnexus/changes.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { graphRailStore } from \"../../core/graph-rail-store.ts\";\nimport { createEditToolDefinition, createWriteToolDefinition } from \"../../core/tools/index.ts\";\n\n/**\n * Wrap the edit/write tools to record per-file diffstats for the side rail.\n * Pure observation — results pass through untouched.\n */\n\nfunction countDiff(diff: string | undefined): { added: number; removed: number } {\n\tif (!diff) return { added: 0, removed: 0 };\n\tlet added = 0;\n\tlet removed = 0;\n\tfor (const line of diff.split(\"\\n\")) {\n\t\tif (line.startsWith(\"+\") && !line.startsWith(\"+++\")) added++;\n\t\telse if (line.startsWith(\"-\") && !line.startsWith(\"---\")) removed++;\n\t}\n\treturn { added, removed };\n}\n\nexport function registerChangeTracking(pi: ExtensionAPI, cwd: string): void {\n\tconst edit = createEditToolDefinition(cwd);\n\tconst write = createWriteToolDefinition(cwd);\n\n\tpi.registerTool({\n\t\t...edit,\n\t\texecute: async (id, params, signal, onUpdate, ctx) => {\n\t\t\tconst result = await edit.execute(id, params, signal, onUpdate, ctx);\n\t\t\ttry {\n\t\t\t\tconst path = String((params as { path?: unknown })?.path ?? \"\");\n\t\t\t\tconst diff = (result.details as { diff?: string } | undefined)?.diff;\n\t\t\t\tconst { added, removed } = countDiff(diff);\n\t\t\t\tif (path && (added > 0 || removed > 0)) graphRailStore.recordChange(path, added, removed);\n\t\t\t} catch {\n\t\t\t\t// observation only\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t});\n\n\tpi.registerTool({\n\t\t...write,\n\t\texecute: async (id, params, signal, onUpdate, ctx) => {\n\t\t\tconst result = await write.execute(id, params, signal, onUpdate, ctx);\n\t\t\ttry {\n\t\t\t\tconst p = params as { path?: unknown; content?: unknown };\n\t\t\t\tconst path = String(p?.path ?? \"\");\n\t\t\t\tconst lineCount = String(p?.content ?? \"\").split(\"\\n\").length;\n\t\t\t\tif (path) graphRailStore.recordChange(path, lineCount, 0);\n\t\t\t} catch {\n\t\t\t\t// observation only\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t});\n}\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Streamable-HTTP MCP client for the GitNexus hub — and only the hub.
|
|
3
|
+
*
|
|
4
|
+
* This is intentionally NOT a general MCP client: it implements exactly the
|
|
5
|
+
* subset nexus-cli needs against a single known server — initialize,
|
|
6
|
+
* notifications/initialized, tools/call — over the Streamable HTTP transport
|
|
7
|
+
* (JSON-RPC over POST; responses arrive as application/json or as a
|
|
8
|
+
* text/event-stream carrying JSON-RPC messages).
|
|
9
|
+
*/
|
|
10
|
+
import type { GitNexusConfig } from "./config.ts";
|
|
11
|
+
export interface McpToolResult {
|
|
12
|
+
content?: Array<{
|
|
13
|
+
type: string;
|
|
14
|
+
text?: string;
|
|
15
|
+
}>;
|
|
16
|
+
isError?: boolean;
|
|
17
|
+
structuredContent?: unknown;
|
|
18
|
+
}
|
|
19
|
+
export declare class GitNexusClientError extends Error {
|
|
20
|
+
readonly kind: "auth" | "network" | "protocol" | "tool";
|
|
21
|
+
constructor(message: string, kind: "auth" | "network" | "protocol" | "tool");
|
|
22
|
+
}
|
|
23
|
+
export declare class GitNexusClient {
|
|
24
|
+
private sessionId;
|
|
25
|
+
private nextId;
|
|
26
|
+
private initializing;
|
|
27
|
+
private readonly config;
|
|
28
|
+
constructor(config: GitNexusConfig);
|
|
29
|
+
/** Call a hub tool by name. Initializes the MCP session lazily on first use. */
|
|
30
|
+
callTool(name: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<McpToolResult>;
|
|
31
|
+
/** Extract the primary text payload from an MCP tool result. */
|
|
32
|
+
static text(result: McpToolResult): string;
|
|
33
|
+
private ensureInitialized;
|
|
34
|
+
private initialize;
|
|
35
|
+
private notify;
|
|
36
|
+
private request;
|
|
37
|
+
private post;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/extensions/gitnexus/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAmBlD,MAAM,WAAW,aAAa;IAC7B,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IAExD,YAAY,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,EAI1E;CACD;AAKD,qBAAa,cAAc;IAC1B,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IAExC,YAAY,MAAM,EAAE,cAAc,EAEjC;IAED,gFAAgF;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAIxG;IAED,gEAAgE;IAChE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAUzC;IAED,OAAO,CAAC,iBAAiB;YAQX,UAAU;YAaV,MAAM;YAIN,OAAO;YAUP,IAAI;CA8DlB","sourcesContent":["/**\n * Minimal Streamable-HTTP MCP client for the GitNexus hub — and only the hub.\n *\n * This is intentionally NOT a general MCP client: it implements exactly the\n * subset nexus-cli needs against a single known server — initialize,\n * notifications/initialized, tools/call — over the Streamable HTTP transport\n * (JSON-RPC over POST; responses arrive as application/json or as a\n * text/event-stream carrying JSON-RPC messages).\n */\n\nimport { appendFileSync } from \"node:fs\";\nimport type { GitNexusConfig } from \"./config.ts\";\n\n/** File-based trace (NEXUS_TRACE=1): TUI captures stderr, so console won't do. */\nfunction clientTrace(message: string): void {\n\tif (!process.env.NEXUS_TRACE) return;\n\ttry {\n\t\tappendFileSync(\"/tmp/nexus-observatory-trace.log\", `${new Date().toISOString()} [client] ${message}\\n`);\n\t} catch {\n\t\t// best-effort\n\t}\n}\n\ninterface JsonRpcResponse {\n\tjsonrpc: \"2.0\";\n\tid?: number | string | null;\n\tresult?: unknown;\n\terror?: { code: number; message: string; data?: unknown };\n}\n\nexport interface McpToolResult {\n\tcontent?: Array<{ type: string; text?: string }>;\n\tisError?: boolean;\n\tstructuredContent?: unknown;\n}\n\nexport class GitNexusClientError extends Error {\n\treadonly kind: \"auth\" | \"network\" | \"protocol\" | \"tool\";\n\n\tconstructor(message: string, kind: \"auth\" | \"network\" | \"protocol\" | \"tool\") {\n\t\tsuper(message);\n\t\tthis.name = \"GitNexusClientError\";\n\t\tthis.kind = kind;\n\t}\n}\n\nconst PROTOCOL_VERSION = \"2025-06-18\";\nconst REQUEST_TIMEOUT_MS = 60_000;\n\nexport class GitNexusClient {\n\tprivate sessionId: string | undefined;\n\tprivate nextId = 1;\n\tprivate initializing: Promise<void> | undefined;\n\tprivate readonly config: GitNexusConfig;\n\n\tconstructor(config: GitNexusConfig) {\n\t\tthis.config = config;\n\t}\n\n\t/** Call a hub tool by name. Initializes the MCP session lazily on first use. */\n\tasync callTool(name: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<McpToolResult> {\n\t\tawait this.ensureInitialized(signal);\n\t\tconst result = await this.request(\"tools/call\", { name, arguments: args }, signal);\n\t\treturn (result ?? {}) as McpToolResult;\n\t}\n\n\t/** Extract the primary text payload from an MCP tool result. */\n\tstatic text(result: McpToolResult): string {\n\t\tconst parts = result.content ?? [];\n\t\tconst text = parts\n\t\t\t.filter((p) => p.type === \"text\" && typeof p.text === \"string\")\n\t\t\t.map((p) => p.text)\n\t\t\t.join(\"\\n\");\n\t\tif (result.isError) {\n\t\t\tthrow new GitNexusClientError(text || \"hub tool returned an error\", \"tool\");\n\t\t}\n\t\treturn text;\n\t}\n\n\tprivate ensureInitialized(signal?: AbortSignal): Promise<void> {\n\t\tthis.initializing ??= this.initialize(signal).catch((error) => {\n\t\t\tthis.initializing = undefined;\n\t\t\tthrow error;\n\t\t});\n\t\treturn this.initializing;\n\t}\n\n\tprivate async initialize(signal?: AbortSignal): Promise<void> {\n\t\tawait this.request(\n\t\t\t\"initialize\",\n\t\t\t{\n\t\t\t\tprotocolVersion: PROTOCOL_VERSION,\n\t\t\t\tcapabilities: {},\n\t\t\t\tclientInfo: { name: \"nexus-cli\", version: \"0.1.0\" },\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\t\tawait this.notify(\"notifications/initialized\");\n\t}\n\n\tprivate async notify(method: string): Promise<void> {\n\t\tawait this.post({ jsonrpc: \"2.0\", method }, undefined);\n\t}\n\n\tprivate async request(method: string, params: unknown, signal?: AbortSignal): Promise<unknown> {\n\t\tconst id = this.nextId++;\n\t\tconst response = await this.post({ jsonrpc: \"2.0\", id, method, params }, signal);\n\t\tif (!response) throw new GitNexusClientError(`empty response for ${method}`, \"protocol\");\n\t\tif (response.error) {\n\t\t\tthrow new GitNexusClientError(`hub ${method} failed: ${response.error.message}`, \"protocol\");\n\t\t}\n\t\treturn response.result;\n\t}\n\n\tprivate async post(body: unknown, signal?: AbortSignal): Promise<JsonRpcResponse | undefined> {\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n\t\tconst onOuterAbort = () => controller.abort();\n\t\tsignal?.addEventListener(\"abort\", onOuterAbort, { once: true });\n\t\ttry {\n\t\t\tconst method = (body as { method?: string }).method ?? \"?\";\n\t\t\tclientTrace(`${method}: fetch dispatch`);\n\t\t\tlet response: Response;\n\t\t\ttry {\n\t\t\t\tresponse = await fetch(this.config.hubUrl, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t\t\taccept: \"application/json, text/event-stream\",\n\t\t\t\t\t\tauthorization: `Bearer ${this.config.token}`,\n\t\t\t\t\t\t...(this.config.deviceFingerprint ? { \"x-device-fingerprint\": this.config.deviceFingerprint } : {}),\n\t\t\t\t\t\t...(this.config.deviceName ? { \"x-device-name\": this.config.deviceName } : {}),\n\t\t\t\t\t\t...(this.sessionId ? { \"mcp-session-id\": this.sessionId } : {}),\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(body),\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new GitNexusClientError(`cannot reach GitNexus hub: ${reason}`, \"network\");\n\t\t\t}\n\n\t\t\tclientTrace(`${method}: status ${response.status} content-type ${response.headers.get(\"content-type\")}`);\n\t\t\tconst newSessionId = response.headers.get(\"mcp-session-id\");\n\t\t\tif (newSessionId) this.sessionId = newSessionId;\n\n\t\t\tif (response.status === 401 || response.status === 403) {\n\t\t\t\tawait response.body?.cancel().catch(() => {});\n\t\t\t\tthrow new GitNexusClientError(\"GitNexus hub rejected the token (401/403). Run /login.\", \"auth\");\n\t\t\t}\n\t\t\tif (response.status === 202) {\n\t\t\t\t// Drain the body — an unconsumed response pins its socket, and under a\n\t\t\t\t// connection-capped dispatcher that deadlocks every later hub call.\n\t\t\t\tawait response.body?.cancel().catch(() => {});\n\t\t\t\treturn undefined; // accepted notification\n\t\t\t}\n\t\t\tif (!response.ok) {\n\t\t\t\tawait response.body?.cancel().catch(() => {});\n\t\t\t\tthrow new GitNexusClientError(`GitNexus hub HTTP ${response.status}`, \"protocol\");\n\t\t\t}\n\n\t\t\tconst contentType = response.headers.get(\"content-type\") ?? \"\";\n\t\t\tif (contentType.includes(\"text/event-stream\")) {\n\t\t\t\tconst sse = await response.text();\n\t\t\t\tclientTrace(`${method}: sse body ${sse.length} bytes`);\n\t\t\t\treturn parseSseForResponse(sse);\n\t\t\t}\n\t\t\tconst text = await response.text();\n\t\t\tclientTrace(`${method}: json body ${text.length} bytes`);\n\t\t\tif (!text) return undefined;\n\t\t\treturn JSON.parse(text) as JsonRpcResponse;\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t\tsignal?.removeEventListener(\"abort\", onOuterAbort);\n\t\t}\n\t}\n}\n\n/** Pull the (single) JSON-RPC response message out of an SSE body. */\nfunction parseSseForResponse(sse: string): JsonRpcResponse | undefined {\n\tlet last: JsonRpcResponse | undefined;\n\tfor (const rawEvent of sse.split(\"\\n\\n\")) {\n\t\tconst data = rawEvent\n\t\t\t.split(\"\\n\")\n\t\t\t.filter((line) => line.startsWith(\"data:\"))\n\t\t\t.map((line) => line.slice(5).trim())\n\t\t\t.join(\"\\n\");\n\t\tif (!data) continue;\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(data) as JsonRpcResponse;\n\t\t\t// Responses carry an id; server-initiated notifications do not.\n\t\t\tif (parsed.id !== undefined && parsed.id !== null) last = parsed;\n\t\t} catch {\n\t\t\t// Ignore non-JSON keepalives.\n\t\t}\n\t}\n\treturn last;\n}\n"]}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Streamable-HTTP MCP client for the GitNexus hub — and only the hub.
|
|
3
|
+
*
|
|
4
|
+
* This is intentionally NOT a general MCP client: it implements exactly the
|
|
5
|
+
* subset nexus-cli needs against a single known server — initialize,
|
|
6
|
+
* notifications/initialized, tools/call — over the Streamable HTTP transport
|
|
7
|
+
* (JSON-RPC over POST; responses arrive as application/json or as a
|
|
8
|
+
* text/event-stream carrying JSON-RPC messages).
|
|
9
|
+
*/
|
|
10
|
+
import { appendFileSync } from "node:fs";
|
|
11
|
+
/** File-based trace (NEXUS_TRACE=1): TUI captures stderr, so console won't do. */
|
|
12
|
+
function clientTrace(message) {
|
|
13
|
+
if (!process.env.NEXUS_TRACE)
|
|
14
|
+
return;
|
|
15
|
+
try {
|
|
16
|
+
appendFileSync("/tmp/nexus-observatory-trace.log", `${new Date().toISOString()} [client] ${message}\n`);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// best-effort
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export class GitNexusClientError extends Error {
|
|
23
|
+
kind;
|
|
24
|
+
constructor(message, kind) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = "GitNexusClientError";
|
|
27
|
+
this.kind = kind;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const PROTOCOL_VERSION = "2025-06-18";
|
|
31
|
+
const REQUEST_TIMEOUT_MS = 60_000;
|
|
32
|
+
export class GitNexusClient {
|
|
33
|
+
sessionId;
|
|
34
|
+
nextId = 1;
|
|
35
|
+
initializing;
|
|
36
|
+
config;
|
|
37
|
+
constructor(config) {
|
|
38
|
+
this.config = config;
|
|
39
|
+
}
|
|
40
|
+
/** Call a hub tool by name. Initializes the MCP session lazily on first use. */
|
|
41
|
+
async callTool(name, args, signal) {
|
|
42
|
+
await this.ensureInitialized(signal);
|
|
43
|
+
const result = await this.request("tools/call", { name, arguments: args }, signal);
|
|
44
|
+
return (result ?? {});
|
|
45
|
+
}
|
|
46
|
+
/** Extract the primary text payload from an MCP tool result. */
|
|
47
|
+
static text(result) {
|
|
48
|
+
const parts = result.content ?? [];
|
|
49
|
+
const text = parts
|
|
50
|
+
.filter((p) => p.type === "text" && typeof p.text === "string")
|
|
51
|
+
.map((p) => p.text)
|
|
52
|
+
.join("\n");
|
|
53
|
+
if (result.isError) {
|
|
54
|
+
throw new GitNexusClientError(text || "hub tool returned an error", "tool");
|
|
55
|
+
}
|
|
56
|
+
return text;
|
|
57
|
+
}
|
|
58
|
+
ensureInitialized(signal) {
|
|
59
|
+
this.initializing ??= this.initialize(signal).catch((error) => {
|
|
60
|
+
this.initializing = undefined;
|
|
61
|
+
throw error;
|
|
62
|
+
});
|
|
63
|
+
return this.initializing;
|
|
64
|
+
}
|
|
65
|
+
async initialize(signal) {
|
|
66
|
+
await this.request("initialize", {
|
|
67
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
68
|
+
capabilities: {},
|
|
69
|
+
clientInfo: { name: "nexus-cli", version: "0.1.0" },
|
|
70
|
+
}, signal);
|
|
71
|
+
await this.notify("notifications/initialized");
|
|
72
|
+
}
|
|
73
|
+
async notify(method) {
|
|
74
|
+
await this.post({ jsonrpc: "2.0", method }, undefined);
|
|
75
|
+
}
|
|
76
|
+
async request(method, params, signal) {
|
|
77
|
+
const id = this.nextId++;
|
|
78
|
+
const response = await this.post({ jsonrpc: "2.0", id, method, params }, signal);
|
|
79
|
+
if (!response)
|
|
80
|
+
throw new GitNexusClientError(`empty response for ${method}`, "protocol");
|
|
81
|
+
if (response.error) {
|
|
82
|
+
throw new GitNexusClientError(`hub ${method} failed: ${response.error.message}`, "protocol");
|
|
83
|
+
}
|
|
84
|
+
return response.result;
|
|
85
|
+
}
|
|
86
|
+
async post(body, signal) {
|
|
87
|
+
const controller = new AbortController();
|
|
88
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
89
|
+
const onOuterAbort = () => controller.abort();
|
|
90
|
+
signal?.addEventListener("abort", onOuterAbort, { once: true });
|
|
91
|
+
try {
|
|
92
|
+
const method = body.method ?? "?";
|
|
93
|
+
clientTrace(`${method}: fetch dispatch`);
|
|
94
|
+
let response;
|
|
95
|
+
try {
|
|
96
|
+
response = await fetch(this.config.hubUrl, {
|
|
97
|
+
method: "POST",
|
|
98
|
+
headers: {
|
|
99
|
+
"content-type": "application/json",
|
|
100
|
+
accept: "application/json, text/event-stream",
|
|
101
|
+
authorization: `Bearer ${this.config.token}`,
|
|
102
|
+
...(this.config.deviceFingerprint ? { "x-device-fingerprint": this.config.deviceFingerprint } : {}),
|
|
103
|
+
...(this.config.deviceName ? { "x-device-name": this.config.deviceName } : {}),
|
|
104
|
+
...(this.sessionId ? { "mcp-session-id": this.sessionId } : {}),
|
|
105
|
+
},
|
|
106
|
+
body: JSON.stringify(body),
|
|
107
|
+
signal: controller.signal,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
112
|
+
throw new GitNexusClientError(`cannot reach GitNexus hub: ${reason}`, "network");
|
|
113
|
+
}
|
|
114
|
+
clientTrace(`${method}: status ${response.status} content-type ${response.headers.get("content-type")}`);
|
|
115
|
+
const newSessionId = response.headers.get("mcp-session-id");
|
|
116
|
+
if (newSessionId)
|
|
117
|
+
this.sessionId = newSessionId;
|
|
118
|
+
if (response.status === 401 || response.status === 403) {
|
|
119
|
+
await response.body?.cancel().catch(() => { });
|
|
120
|
+
throw new GitNexusClientError("GitNexus hub rejected the token (401/403). Run /login.", "auth");
|
|
121
|
+
}
|
|
122
|
+
if (response.status === 202) {
|
|
123
|
+
// Drain the body — an unconsumed response pins its socket, and under a
|
|
124
|
+
// connection-capped dispatcher that deadlocks every later hub call.
|
|
125
|
+
await response.body?.cancel().catch(() => { });
|
|
126
|
+
return undefined; // accepted notification
|
|
127
|
+
}
|
|
128
|
+
if (!response.ok) {
|
|
129
|
+
await response.body?.cancel().catch(() => { });
|
|
130
|
+
throw new GitNexusClientError(`GitNexus hub HTTP ${response.status}`, "protocol");
|
|
131
|
+
}
|
|
132
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
133
|
+
if (contentType.includes("text/event-stream")) {
|
|
134
|
+
const sse = await response.text();
|
|
135
|
+
clientTrace(`${method}: sse body ${sse.length} bytes`);
|
|
136
|
+
return parseSseForResponse(sse);
|
|
137
|
+
}
|
|
138
|
+
const text = await response.text();
|
|
139
|
+
clientTrace(`${method}: json body ${text.length} bytes`);
|
|
140
|
+
if (!text)
|
|
141
|
+
return undefined;
|
|
142
|
+
return JSON.parse(text);
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
clearTimeout(timeout);
|
|
146
|
+
signal?.removeEventListener("abort", onOuterAbort);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/** Pull the (single) JSON-RPC response message out of an SSE body. */
|
|
151
|
+
function parseSseForResponse(sse) {
|
|
152
|
+
let last;
|
|
153
|
+
for (const rawEvent of sse.split("\n\n")) {
|
|
154
|
+
const data = rawEvent
|
|
155
|
+
.split("\n")
|
|
156
|
+
.filter((line) => line.startsWith("data:"))
|
|
157
|
+
.map((line) => line.slice(5).trim())
|
|
158
|
+
.join("\n");
|
|
159
|
+
if (!data)
|
|
160
|
+
continue;
|
|
161
|
+
try {
|
|
162
|
+
const parsed = JSON.parse(data);
|
|
163
|
+
// Responses carry an id; server-initiated notifications do not.
|
|
164
|
+
if (parsed.id !== undefined && parsed.id !== null)
|
|
165
|
+
last = parsed;
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// Ignore non-JSON keepalives.
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return last;
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/extensions/gitnexus/client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Minimal Streamable-HTTP MCP client for the GitNexus hub — and only the hub.\n *\n * This is intentionally NOT a general MCP client: it implements exactly the\n * subset nexus-cli needs against a single known server — initialize,\n * notifications/initialized, tools/call — over the Streamable HTTP transport\n * (JSON-RPC over POST; responses arrive as application/json or as a\n * text/event-stream carrying JSON-RPC messages).\n */\n\nimport { appendFileSync } from \"node:fs\";\nimport type { GitNexusConfig } from \"./config.ts\";\n\n/** File-based trace (NEXUS_TRACE=1): TUI captures stderr, so console won't do. */\nfunction clientTrace(message: string): void {\n\tif (!process.env.NEXUS_TRACE) return;\n\ttry {\n\t\tappendFileSync(\"/tmp/nexus-observatory-trace.log\", `${new Date().toISOString()} [client] ${message}\\n`);\n\t} catch {\n\t\t// best-effort\n\t}\n}\n\ninterface JsonRpcResponse {\n\tjsonrpc: \"2.0\";\n\tid?: number | string | null;\n\tresult?: unknown;\n\terror?: { code: number; message: string; data?: unknown };\n}\n\nexport interface McpToolResult {\n\tcontent?: Array<{ type: string; text?: string }>;\n\tisError?: boolean;\n\tstructuredContent?: unknown;\n}\n\nexport class GitNexusClientError extends Error {\n\treadonly kind: \"auth\" | \"network\" | \"protocol\" | \"tool\";\n\n\tconstructor(message: string, kind: \"auth\" | \"network\" | \"protocol\" | \"tool\") {\n\t\tsuper(message);\n\t\tthis.name = \"GitNexusClientError\";\n\t\tthis.kind = kind;\n\t}\n}\n\nconst PROTOCOL_VERSION = \"2025-06-18\";\nconst REQUEST_TIMEOUT_MS = 60_000;\n\nexport class GitNexusClient {\n\tprivate sessionId: string | undefined;\n\tprivate nextId = 1;\n\tprivate initializing: Promise<void> | undefined;\n\tprivate readonly config: GitNexusConfig;\n\n\tconstructor(config: GitNexusConfig) {\n\t\tthis.config = config;\n\t}\n\n\t/** Call a hub tool by name. Initializes the MCP session lazily on first use. */\n\tasync callTool(name: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<McpToolResult> {\n\t\tawait this.ensureInitialized(signal);\n\t\tconst result = await this.request(\"tools/call\", { name, arguments: args }, signal);\n\t\treturn (result ?? {}) as McpToolResult;\n\t}\n\n\t/** Extract the primary text payload from an MCP tool result. */\n\tstatic text(result: McpToolResult): string {\n\t\tconst parts = result.content ?? [];\n\t\tconst text = parts\n\t\t\t.filter((p) => p.type === \"text\" && typeof p.text === \"string\")\n\t\t\t.map((p) => p.text)\n\t\t\t.join(\"\\n\");\n\t\tif (result.isError) {\n\t\t\tthrow new GitNexusClientError(text || \"hub tool returned an error\", \"tool\");\n\t\t}\n\t\treturn text;\n\t}\n\n\tprivate ensureInitialized(signal?: AbortSignal): Promise<void> {\n\t\tthis.initializing ??= this.initialize(signal).catch((error) => {\n\t\t\tthis.initializing = undefined;\n\t\t\tthrow error;\n\t\t});\n\t\treturn this.initializing;\n\t}\n\n\tprivate async initialize(signal?: AbortSignal): Promise<void> {\n\t\tawait this.request(\n\t\t\t\"initialize\",\n\t\t\t{\n\t\t\t\tprotocolVersion: PROTOCOL_VERSION,\n\t\t\t\tcapabilities: {},\n\t\t\t\tclientInfo: { name: \"nexus-cli\", version: \"0.1.0\" },\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\t\tawait this.notify(\"notifications/initialized\");\n\t}\n\n\tprivate async notify(method: string): Promise<void> {\n\t\tawait this.post({ jsonrpc: \"2.0\", method }, undefined);\n\t}\n\n\tprivate async request(method: string, params: unknown, signal?: AbortSignal): Promise<unknown> {\n\t\tconst id = this.nextId++;\n\t\tconst response = await this.post({ jsonrpc: \"2.0\", id, method, params }, signal);\n\t\tif (!response) throw new GitNexusClientError(`empty response for ${method}`, \"protocol\");\n\t\tif (response.error) {\n\t\t\tthrow new GitNexusClientError(`hub ${method} failed: ${response.error.message}`, \"protocol\");\n\t\t}\n\t\treturn response.result;\n\t}\n\n\tprivate async post(body: unknown, signal?: AbortSignal): Promise<JsonRpcResponse | undefined> {\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n\t\tconst onOuterAbort = () => controller.abort();\n\t\tsignal?.addEventListener(\"abort\", onOuterAbort, { once: true });\n\t\ttry {\n\t\t\tconst method = (body as { method?: string }).method ?? \"?\";\n\t\t\tclientTrace(`${method}: fetch dispatch`);\n\t\t\tlet response: Response;\n\t\t\ttry {\n\t\t\t\tresponse = await fetch(this.config.hubUrl, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t\t\taccept: \"application/json, text/event-stream\",\n\t\t\t\t\t\tauthorization: `Bearer ${this.config.token}`,\n\t\t\t\t\t\t...(this.config.deviceFingerprint ? { \"x-device-fingerprint\": this.config.deviceFingerprint } : {}),\n\t\t\t\t\t\t...(this.config.deviceName ? { \"x-device-name\": this.config.deviceName } : {}),\n\t\t\t\t\t\t...(this.sessionId ? { \"mcp-session-id\": this.sessionId } : {}),\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(body),\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new GitNexusClientError(`cannot reach GitNexus hub: ${reason}`, \"network\");\n\t\t\t}\n\n\t\t\tclientTrace(`${method}: status ${response.status} content-type ${response.headers.get(\"content-type\")}`);\n\t\t\tconst newSessionId = response.headers.get(\"mcp-session-id\");\n\t\t\tif (newSessionId) this.sessionId = newSessionId;\n\n\t\t\tif (response.status === 401 || response.status === 403) {\n\t\t\t\tawait response.body?.cancel().catch(() => {});\n\t\t\t\tthrow new GitNexusClientError(\"GitNexus hub rejected the token (401/403). Run /login.\", \"auth\");\n\t\t\t}\n\t\t\tif (response.status === 202) {\n\t\t\t\t// Drain the body — an unconsumed response pins its socket, and under a\n\t\t\t\t// connection-capped dispatcher that deadlocks every later hub call.\n\t\t\t\tawait response.body?.cancel().catch(() => {});\n\t\t\t\treturn undefined; // accepted notification\n\t\t\t}\n\t\t\tif (!response.ok) {\n\t\t\t\tawait response.body?.cancel().catch(() => {});\n\t\t\t\tthrow new GitNexusClientError(`GitNexus hub HTTP ${response.status}`, \"protocol\");\n\t\t\t}\n\n\t\t\tconst contentType = response.headers.get(\"content-type\") ?? \"\";\n\t\t\tif (contentType.includes(\"text/event-stream\")) {\n\t\t\t\tconst sse = await response.text();\n\t\t\t\tclientTrace(`${method}: sse body ${sse.length} bytes`);\n\t\t\t\treturn parseSseForResponse(sse);\n\t\t\t}\n\t\t\tconst text = await response.text();\n\t\t\tclientTrace(`${method}: json body ${text.length} bytes`);\n\t\t\tif (!text) return undefined;\n\t\t\treturn JSON.parse(text) as JsonRpcResponse;\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t\tsignal?.removeEventListener(\"abort\", onOuterAbort);\n\t\t}\n\t}\n}\n\n/** Pull the (single) JSON-RPC response message out of an SSE body. */\nfunction parseSseForResponse(sse: string): JsonRpcResponse | undefined {\n\tlet last: JsonRpcResponse | undefined;\n\tfor (const rawEvent of sse.split(\"\\n\\n\")) {\n\t\tconst data = rawEvent\n\t\t\t.split(\"\\n\")\n\t\t\t.filter((line) => line.startsWith(\"data:\"))\n\t\t\t.map((line) => line.slice(5).trim())\n\t\t\t.join(\"\\n\");\n\t\tif (!data) continue;\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(data) as JsonRpcResponse;\n\t\t\t// Responses carry an id; server-initiated notifications do not.\n\t\t\tif (parsed.id !== undefined && parsed.id !== null) last = parsed;\n\t\t} catch {\n\t\t\t// Ignore non-JSON keepalives.\n\t\t}\n\t}\n\treturn last;\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitNexus hub connection settings.
|
|
3
|
+
*
|
|
4
|
+
* Resolution order (first hit wins):
|
|
5
|
+
* 1. Environment: GITNEXUS_HUB_URL / GITNEXUS_TOKEN
|
|
6
|
+
* 2. Config file: ~/.config/nexus/auth.json ({ hubUrl, token })
|
|
7
|
+
*
|
|
8
|
+
* The hub endpoint is the Streamable-HTTP MCP endpoint (".../mcp"). Bearer
|
|
9
|
+
* tokens are hub API tokens; an empty token allowlist on the hub means the
|
|
10
|
+
* token can see every repo of its user identity.
|
|
11
|
+
*/
|
|
12
|
+
export interface GitNexusConfig {
|
|
13
|
+
hubUrl: string;
|
|
14
|
+
token: string;
|
|
15
|
+
/** Hub tokens can be device-bound; these headers must then match the binding. */
|
|
16
|
+
deviceFingerprint?: string | undefined;
|
|
17
|
+
deviceName?: string | undefined;
|
|
18
|
+
}
|
|
19
|
+
export declare const DEFAULT_HUB_URL = "https://gitnexus-enterprise-production.up.railway.app/mcp";
|
|
20
|
+
/** Resolve hub settings. Returns undefined when no token is configured anywhere. */
|
|
21
|
+
export declare function resolveGitNexusConfig(): GitNexusConfig | undefined;
|
|
22
|
+
/** Persist hub settings from `/login`. */
|
|
23
|
+
export declare function saveGitNexusConfig(config: GitNexusConfig): string;
|
|
24
|
+
export declare function gitNexusConfigPath(): string;
|
|
25
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/extensions/gitnexus/config.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,eAAO,MAAM,eAAe,8DAA8D,CAAC;AAoB3F,oFAAoF;AACpF,wBAAgB,qBAAqB,IAAI,cAAc,GAAG,SAAS,CAQlE;AAED,0CAA0C;AAC1C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAIjE;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\n/**\n * GitNexus hub connection settings.\n *\n * Resolution order (first hit wins):\n * 1. Environment: GITNEXUS_HUB_URL / GITNEXUS_TOKEN\n * 2. Config file: ~/.config/nexus/auth.json ({ hubUrl, token })\n *\n * The hub endpoint is the Streamable-HTTP MCP endpoint (\".../mcp\"). Bearer\n * tokens are hub API tokens; an empty token allowlist on the hub means the\n * token can see every repo of its user identity.\n */\n\nexport interface GitNexusConfig {\n\thubUrl: string;\n\ttoken: string;\n\t/** Hub tokens can be device-bound; these headers must then match the binding. */\n\tdeviceFingerprint?: string | undefined;\n\tdeviceName?: string | undefined;\n}\n\nexport const DEFAULT_HUB_URL = \"https://gitnexus-enterprise-production.up.railway.app/mcp\";\n\nfunction configDir(): string {\n\treturn join(homedir(), \".config\", \"nexus\");\n}\n\nfunction configPath(): string {\n\treturn join(configDir(), \"auth.json\");\n}\n\nfunction readConfigFile(): Partial<GitNexusConfig> {\n\ttry {\n\t\tconst raw = readFileSync(configPath(), \"utf8\");\n\t\tconst parsed = JSON.parse(raw) as Partial<GitNexusConfig>;\n\t\treturn typeof parsed === \"object\" && parsed !== null ? parsed : {};\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/** Resolve hub settings. Returns undefined when no token is configured anywhere. */\nexport function resolveGitNexusConfig(): GitNexusConfig | undefined {\n\tconst file = readConfigFile();\n\tconst token = process.env.GITNEXUS_TOKEN ?? file.token;\n\tif (!token) return undefined;\n\tconst hubUrl = process.env.GITNEXUS_HUB_URL ?? file.hubUrl ?? DEFAULT_HUB_URL;\n\tconst deviceFingerprint = process.env.GITNEXUS_DEVICE_FP ?? file.deviceFingerprint;\n\tconst deviceName = process.env.GITNEXUS_DEVICE_NAME ?? file.deviceName;\n\treturn { hubUrl, token, deviceFingerprint, deviceName };\n}\n\n/** Persist hub settings from `/login`. */\nexport function saveGitNexusConfig(config: GitNexusConfig): string {\n\tif (!existsSync(configDir())) mkdirSync(configDir(), { recursive: true, mode: 0o700 });\n\twriteFileSync(configPath(), `${JSON.stringify(config, null, \"\\t\")}\\n`, { mode: 0o600 });\n\treturn configPath();\n}\n\nexport function gitNexusConfigPath(): string {\n\treturn configPath();\n}\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
export const DEFAULT_HUB_URL = "https://gitnexus-enterprise-production.up.railway.app/mcp";
|
|
5
|
+
function configDir() {
|
|
6
|
+
return join(homedir(), ".config", "nexus");
|
|
7
|
+
}
|
|
8
|
+
function configPath() {
|
|
9
|
+
return join(configDir(), "auth.json");
|
|
10
|
+
}
|
|
11
|
+
function readConfigFile() {
|
|
12
|
+
try {
|
|
13
|
+
const raw = readFileSync(configPath(), "utf8");
|
|
14
|
+
const parsed = JSON.parse(raw);
|
|
15
|
+
return typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Resolve hub settings. Returns undefined when no token is configured anywhere. */
|
|
22
|
+
export function resolveGitNexusConfig() {
|
|
23
|
+
const file = readConfigFile();
|
|
24
|
+
const token = process.env.GITNEXUS_TOKEN ?? file.token;
|
|
25
|
+
if (!token)
|
|
26
|
+
return undefined;
|
|
27
|
+
const hubUrl = process.env.GITNEXUS_HUB_URL ?? file.hubUrl ?? DEFAULT_HUB_URL;
|
|
28
|
+
const deviceFingerprint = process.env.GITNEXUS_DEVICE_FP ?? file.deviceFingerprint;
|
|
29
|
+
const deviceName = process.env.GITNEXUS_DEVICE_NAME ?? file.deviceName;
|
|
30
|
+
return { hubUrl, token, deviceFingerprint, deviceName };
|
|
31
|
+
}
|
|
32
|
+
/** Persist hub settings from `/login`. */
|
|
33
|
+
export function saveGitNexusConfig(config) {
|
|
34
|
+
if (!existsSync(configDir()))
|
|
35
|
+
mkdirSync(configDir(), { recursive: true, mode: 0o700 });
|
|
36
|
+
writeFileSync(configPath(), `${JSON.stringify(config, null, "\t")}\n`, { mode: 0o600 });
|
|
37
|
+
return configPath();
|
|
38
|
+
}
|
|
39
|
+
export function gitNexusConfigPath() {
|
|
40
|
+
return configPath();
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/extensions/gitnexus/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAsBjC,MAAM,CAAC,MAAM,eAAe,GAAG,2DAA2D,CAAC;AAE3F,SAAS,SAAS,GAAW;IAC5B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAAA,CAC3C;AAED,SAAS,UAAU,GAAW;IAC7B,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,WAAW,CAAC,CAAC;AAAA,CACtC;AAED,SAAS,cAAc,GAA4B;IAClD,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;QAC1D,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;AAAA,CACD;AAED,oFAAoF;AACpF,MAAM,UAAU,qBAAqB,GAA+B;IACnE,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC;IACvD,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC;IAC9E,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,IAAI,CAAC,iBAAiB,CAAC;IACnF,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,IAAI,CAAC,UAAU,CAAC;IACvE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,CAAC;AAAA,CACxD;AAED,0CAA0C;AAC1C,MAAM,UAAU,kBAAkB,CAAC,MAAsB,EAAU;IAClE,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;QAAE,SAAS,CAAC,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACvF,aAAa,CAAC,UAAU,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxF,OAAO,UAAU,EAAE,CAAC;AAAA,CACpB;AAED,MAAM,UAAU,kBAAkB,GAAW;IAC5C,OAAO,UAAU,EAAE,CAAC;AAAA,CACpB","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\n/**\n * GitNexus hub connection settings.\n *\n * Resolution order (first hit wins):\n * 1. Environment: GITNEXUS_HUB_URL / GITNEXUS_TOKEN\n * 2. Config file: ~/.config/nexus/auth.json ({ hubUrl, token })\n *\n * The hub endpoint is the Streamable-HTTP MCP endpoint (\".../mcp\"). Bearer\n * tokens are hub API tokens; an empty token allowlist on the hub means the\n * token can see every repo of its user identity.\n */\n\nexport interface GitNexusConfig {\n\thubUrl: string;\n\ttoken: string;\n\t/** Hub tokens can be device-bound; these headers must then match the binding. */\n\tdeviceFingerprint?: string | undefined;\n\tdeviceName?: string | undefined;\n}\n\nexport const DEFAULT_HUB_URL = \"https://gitnexus-enterprise-production.up.railway.app/mcp\";\n\nfunction configDir(): string {\n\treturn join(homedir(), \".config\", \"nexus\");\n}\n\nfunction configPath(): string {\n\treturn join(configDir(), \"auth.json\");\n}\n\nfunction readConfigFile(): Partial<GitNexusConfig> {\n\ttry {\n\t\tconst raw = readFileSync(configPath(), \"utf8\");\n\t\tconst parsed = JSON.parse(raw) as Partial<GitNexusConfig>;\n\t\treturn typeof parsed === \"object\" && parsed !== null ? parsed : {};\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/** Resolve hub settings. Returns undefined when no token is configured anywhere. */\nexport function resolveGitNexusConfig(): GitNexusConfig | undefined {\n\tconst file = readConfigFile();\n\tconst token = process.env.GITNEXUS_TOKEN ?? file.token;\n\tif (!token) return undefined;\n\tconst hubUrl = process.env.GITNEXUS_HUB_URL ?? file.hubUrl ?? DEFAULT_HUB_URL;\n\tconst deviceFingerprint = process.env.GITNEXUS_DEVICE_FP ?? file.deviceFingerprint;\n\tconst deviceName = process.env.GITNEXUS_DEVICE_NAME ?? file.deviceName;\n\treturn { hubUrl, token, deviceFingerprint, deviceName };\n}\n\n/** Persist hub settings from `/login`. */\nexport function saveGitNexusConfig(config: GitNexusConfig): string {\n\tif (!existsSync(configDir())) mkdirSync(configDir(), { recursive: true, mode: 0o700 });\n\twriteFileSync(configPath(), `${JSON.stringify(config, null, \"\\t\")}\\n`, { mode: 0o600 });\n\treturn configPath();\n}\n\nexport function gitNexusConfigPath(): string {\n\treturn configPath();\n}\n"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Device authorization client for hub login.
|
|
3
|
+
*
|
|
4
|
+
* The CLI cannot receive a browser redirect, so it starts a request, shows the
|
|
5
|
+
* user a short code, and polls until they approve it in the web app. The hub
|
|
6
|
+
* mints the token on the first successful poll, so it exists in plaintext only
|
|
7
|
+
* in that one response and in the local auth file.
|
|
8
|
+
*
|
|
9
|
+
* Protocol shape follows RFC 8628, and the hub returns its error codes
|
|
10
|
+
* verbatim so callers branch on a stable string rather than prose.
|
|
11
|
+
*/
|
|
12
|
+
export interface DeviceAuthStart {
|
|
13
|
+
deviceCode: string;
|
|
14
|
+
userCode: string;
|
|
15
|
+
verificationUrl: string;
|
|
16
|
+
verificationUrlComplete?: string;
|
|
17
|
+
/** Seconds until the request expires. */
|
|
18
|
+
expiresIn: number;
|
|
19
|
+
/** Seconds the CLI must wait between polls. */
|
|
20
|
+
interval: number;
|
|
21
|
+
}
|
|
22
|
+
export interface DeviceAuthResult {
|
|
23
|
+
token: string;
|
|
24
|
+
hubUrl: string;
|
|
25
|
+
tokenId?: string;
|
|
26
|
+
}
|
|
27
|
+
export type DeviceAuthFailure =
|
|
28
|
+
/** The user rejected the code in the browser. */
|
|
29
|
+
"access_denied"
|
|
30
|
+
/** The request expired, was already used, or never existed. */
|
|
31
|
+
| "expired_token"
|
|
32
|
+
/** The CLI gave up waiting. */
|
|
33
|
+
| "timeout";
|
|
34
|
+
export declare class DeviceAuthError extends Error {
|
|
35
|
+
readonly reason: DeviceAuthFailure | "network" | "protocol";
|
|
36
|
+
constructor(message: string, reason: DeviceAuthError["reason"]);
|
|
37
|
+
}
|
|
38
|
+
/** Base URL of the hub's HTTP API, derived from the configured MCP endpoint. */
|
|
39
|
+
export declare function hubApiBase(hubUrl: string): string;
|
|
40
|
+
/** Human-readable device label, so tokens are identifiable in the hub UI. */
|
|
41
|
+
export declare function defaultDeviceName(): string;
|
|
42
|
+
/** Stable machine identity required by Hub device-token authentication. */
|
|
43
|
+
export declare function deviceFingerprint(): string;
|
|
44
|
+
/** Ask the hub to begin a device login. */
|
|
45
|
+
export declare function startDeviceAuth(hubUrl: string, options?: {
|
|
46
|
+
deviceName?: string;
|
|
47
|
+
deviceFingerprint?: string;
|
|
48
|
+
signal?: AbortSignal;
|
|
49
|
+
}): Promise<DeviceAuthStart>;
|
|
50
|
+
/**
|
|
51
|
+
* Poll until the user approves, the request dies, or the deadline passes.
|
|
52
|
+
*
|
|
53
|
+
* `sleep` is injectable so tests do not wait in real time.
|
|
54
|
+
*/
|
|
55
|
+
export declare function pollDeviceAuth(hubUrl: string, start: DeviceAuthStart, options?: {
|
|
56
|
+
signal?: AbortSignal;
|
|
57
|
+
sleep?: (ms: number) => Promise<void>;
|
|
58
|
+
now?: () => number;
|
|
59
|
+
}): Promise<DeviceAuthResult>;
|
|
60
|
+
//# sourceMappingURL=device-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-auth.d.ts","sourceRoot":"","sources":["../../../src/extensions/gitnexus/device-auth.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,eAAe;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,iBAAiB;AAC5B,iDAAiD;AAC/C,eAAe;AACjB,+DAA+D;GAC7D,eAAe;AACjB,+BAA+B;GAC7B,SAAS,CAAC;AAEb,qBAAa,eAAgB,SAAQ,KAAK;IACzC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,GAAG,UAAU,CAAC;IAE5D,YAAY,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,EAI7D;CACD;AAED,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,IAAI,MAAM,CAQ1C;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,IAAI,MAAM,CAS1C;AAkCD,2CAA2C;AAC3C,wBAAsB,eAAe,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GACrF,OAAO,CAAC,eAAe,CAAC,CA4B1B;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CACnC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,eAAe,EACtB,OAAO,GAAE;IACR,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACd,GACJ,OAAO,CAAC,gBAAgB,CAAC,CA+C3B","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { arch, hostname, platform, userInfo } from \"node:os\";\nimport { APP_NAME, VERSION } from \"../../config.ts\";\n\n/**\n * Device authorization client for hub login.\n *\n * The CLI cannot receive a browser redirect, so it starts a request, shows the\n * user a short code, and polls until they approve it in the web app. The hub\n * mints the token on the first successful poll, so it exists in plaintext only\n * in that one response and in the local auth file.\n *\n * Protocol shape follows RFC 8628, and the hub returns its error codes\n * verbatim so callers branch on a stable string rather than prose.\n */\n\nexport interface DeviceAuthStart {\n\tdeviceCode: string;\n\tuserCode: string;\n\tverificationUrl: string;\n\tverificationUrlComplete?: string;\n\t/** Seconds until the request expires. */\n\texpiresIn: number;\n\t/** Seconds the CLI must wait between polls. */\n\tinterval: number;\n}\n\nexport interface DeviceAuthResult {\n\ttoken: string;\n\thubUrl: string;\n\ttokenId?: string;\n}\n\nexport type DeviceAuthFailure =\n\t/** The user rejected the code in the browser. */\n\t| \"access_denied\"\n\t/** The request expired, was already used, or never existed. */\n\t| \"expired_token\"\n\t/** The CLI gave up waiting. */\n\t| \"timeout\";\n\nexport class DeviceAuthError extends Error {\n\treadonly reason: DeviceAuthFailure | \"network\" | \"protocol\";\n\n\tconstructor(message: string, reason: DeviceAuthError[\"reason\"]) {\n\t\tsuper(message);\n\t\tthis.name = \"DeviceAuthError\";\n\t\tthis.reason = reason;\n\t}\n}\n\n/** Base URL of the hub's HTTP API, derived from the configured MCP endpoint. */\nexport function hubApiBase(hubUrl: string): string {\n\treturn hubUrl.replace(/\\/mcp\\/?$/, \"\").replace(/\\/+$/, \"\");\n}\n\n/** Human-readable device label, so tokens are identifiable in the hub UI. */\nexport function defaultDeviceName(): string {\n\ttry {\n\t\tconst host = hostname();\n\t\tconst user = userInfo().username;\n\t\treturn user ? `${user}@${host}` : host;\n\t} catch {\n\t\treturn \"unknown-device\";\n\t}\n}\n\n/** Stable machine identity required by Hub device-token authentication. */\nexport function deviceFingerprint(): string {\n\tlet username = \"unknown-user\";\n\ttry {\n\t\tusername = userInfo().username || username;\n\t} catch {\n\t\t// Keep deterministic fallback.\n\t}\n\tconst identity = `${hostname()}:${username}:${platform()}:${arch()}`;\n\treturn createHash(\"sha256\").update(identity).digest(\"hex\").slice(0, 16);\n}\n\nasync function postJson(\n\turl: string,\n\tbody: unknown,\n\tsignal: AbortSignal | undefined,\n): Promise<{ status: number; data: any }> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"content-type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(body),\n\t\t\tsignal,\n\t\t});\n\t} catch (error) {\n\t\tif (signal?.aborted) throw new DeviceAuthError(\"Login cancelled\", \"timeout\");\n\t\tthrow new DeviceAuthError(`Cannot reach the hub at ${url}: ${errorText(error)}`, \"network\");\n\t}\n\n\tconst text = await response.text();\n\tlet data: any;\n\ttry {\n\t\tdata = text ? JSON.parse(text) : {};\n\t} catch {\n\t\tthrow new DeviceAuthError(`Hub returned a non-JSON response (HTTP ${response.status})`, \"protocol\");\n\t}\n\treturn { status: response.status, data };\n}\n\nfunction errorText(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\n/** Ask the hub to begin a device login. */\nexport async function startDeviceAuth(\n\thubUrl: string,\n\toptions: { deviceName?: string; deviceFingerprint?: string; signal?: AbortSignal } = {},\n): Promise<DeviceAuthStart> {\n\tconst { status, data } = await postJson(\n\t\t`${hubApiBase(hubUrl)}/auth/device/start`,\n\t\t{\n\t\t\tagentName: APP_NAME,\n\t\t\tagentVersion: VERSION,\n\t\t\tdeviceName: options.deviceName ?? defaultDeviceName(),\n\t\t\tdeviceFingerprint: options.deviceFingerprint ?? deviceFingerprint(),\n\t\t},\n\t\toptions.signal,\n\t);\n\n\tif (status !== 200 || typeof data?.deviceCode !== \"string\" || typeof data?.userCode !== \"string\") {\n\t\tthrow new DeviceAuthError(\n\t\t\tdata?.error ? String(data.error) : `Hub rejected the login request (HTTP ${status})`,\n\t\t\t\"protocol\",\n\t\t);\n\t}\n\n\treturn {\n\t\tdeviceCode: data.deviceCode,\n\t\tuserCode: data.userCode,\n\t\tverificationUrl: String(data.verificationUrl ?? `${hubApiBase(hubUrl)}/device`),\n\t\tverificationUrlComplete:\n\t\t\ttypeof data.verificationUrlComplete === \"string\" ? data.verificationUrlComplete : undefined,\n\t\texpiresIn: typeof data.expiresIn === \"number\" ? data.expiresIn : 600,\n\t\tinterval: typeof data.interval === \"number\" && data.interval > 0 ? data.interval : 5,\n\t};\n}\n\n/**\n * Poll until the user approves, the request dies, or the deadline passes.\n *\n * `sleep` is injectable so tests do not wait in real time.\n */\nexport async function pollDeviceAuth(\n\thubUrl: string,\n\tstart: DeviceAuthStart,\n\toptions: {\n\t\tsignal?: AbortSignal;\n\t\tsleep?: (ms: number) => Promise<void>;\n\t\tnow?: () => number;\n\t} = {},\n): Promise<DeviceAuthResult> {\n\tconst sleep = options.sleep ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms)));\n\tconst now = options.now ?? (() => Date.now());\n\tconst deadline = now() + start.expiresIn * 1000;\n\tlet intervalMs = start.interval * 1000;\n\n\twhile (true) {\n\t\tif (options.signal?.aborted) throw new DeviceAuthError(\"Login cancelled\", \"timeout\");\n\t\tawait sleep(intervalMs);\n\t\t// Re-check after sleeping: a request that expired while we waited should\n\t\t// not cost the hub another round trip.\n\t\tif (now() >= deadline) break;\n\n\t\tconst { status, data } = await postJson(\n\t\t\t`${hubApiBase(hubUrl)}/auth/device/poll`,\n\t\t\t{ deviceCode: start.deviceCode },\n\t\t\toptions.signal,\n\t\t);\n\n\t\tif (status === 200 && typeof data?.token === \"string\") {\n\t\t\treturn {\n\t\t\t\ttoken: data.token,\n\t\t\t\thubUrl: typeof data.hubUrl === \"string\" ? data.hubUrl : hubUrl,\n\t\t\t\ttokenId: typeof data.tokenId === \"string\" ? data.tokenId : undefined,\n\t\t\t};\n\t\t}\n\n\t\tswitch (data?.error) {\n\t\t\tcase \"authorization_pending\":\n\t\t\t\tbreak;\n\t\t\tcase \"slow_down\":\n\t\t\t\t// Back off to whatever the hub now advertises, or a second more.\n\t\t\t\tintervalMs = typeof data.interval === \"number\" ? data.interval * 1000 : intervalMs + 1000;\n\t\t\t\tbreak;\n\t\t\tcase \"access_denied\":\n\t\t\t\tthrow new DeviceAuthError(\"Login was denied in the browser\", \"access_denied\");\n\t\t\tcase \"expired_token\":\n\t\t\t\tthrow new DeviceAuthError(\"The login code expired or was already used\", \"expired_token\");\n\t\t\tdefault:\n\t\t\t\tthrow new DeviceAuthError(\n\t\t\t\t\tdata?.error ? String(data.error) : `Unexpected hub response (HTTP ${status})`,\n\t\t\t\t\t\"protocol\",\n\t\t\t\t);\n\t\t}\n\t}\n\n\tthrow new DeviceAuthError(\"Timed out waiting for approval\", \"timeout\");\n}\n"]}
|