@duckmind/dm-linux-x64 0.65.8 → 0.66.2
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/dm +2 -2
- package/extensions/.dm-extensions.json +14 -548
- package/extensions/dm-lens/clients/dispatch/runners/utils/runner-helpers.js +1 -1
- package/extensions/dm-mcp-adapter/mcp-keyring-helper.cjs +1 -1
- package/extensions/dm-ponytail/hooks/ponytail-activate.js +1 -1
- package/extensions/dm-ponytail/hooks/ponytail-instructions.js +1 -1
- package/extensions/dm-subagents/src/extension/tool-activation.js +7 -2
- package/extensions/dm-subagents/src/runs/background/runner-aliases.js +2 -2
- package/extensions/dm-subagents/src/runs/foreground/prompt-audit.js +4 -1
- package/extensions/dm-subagents/src/runs/shared/child-session.js +8 -6
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +5 -1
- package/extensions/dm-subagents/src/watchdog/permission-arbiter.js +9 -1
- package/extensions/dm-subagents/src/watchdog/review.js +4 -1
- package/extensions/dm-web-access/tool-activation.js +0 -1
- package/package.json +1 -1
- package/extensions/dm-lens/dist/clients/actionable-warnings-logger.js +0 -24
- package/extensions/dm-lens/dist/clients/actionable-warnings.js +0 -1014
- package/extensions/dm-lens/dist/clients/advisory-provenance.js +0 -385
- package/extensions/dm-lens/dist/clients/agent-behavior-client.js +0 -94
- package/extensions/dm-lens/dist/clients/agent-nudge.js +0 -151
- package/extensions/dm-lens/dist/clients/analysed-root.js +0 -1
- package/extensions/dm-lens/dist/clients/ast-grep-client.js +0 -576
- package/extensions/dm-lens/dist/clients/ast-grep-rule-manager.js +0 -114
- package/extensions/dm-lens/dist/clients/ast-grep-tool-logger.js +0 -85
- package/extensions/dm-lens/dist/clients/ast-grep-types.js +0 -1
- package/extensions/dm-lens/dist/clients/ast-grep-yaml-synth.js +0 -109
- package/extensions/dm-lens/dist/clients/atomic-write-staging.js +0 -66
- package/extensions/dm-lens/dist/clients/atomic-write.js +0 -37
- package/extensions/dm-lens/dist/clients/availability-probe-flight.js +0 -11
- package/extensions/dm-lens/dist/clients/bash-file-access.js +0 -830
- package/extensions/dm-lens/dist/clients/biome-client.js +0 -221
- package/extensions/dm-lens/dist/clients/blocker-freshness.js +0 -385
- package/extensions/dm-lens/dist/clients/blocker-past-eof.js +0 -49
- package/extensions/dm-lens/dist/clients/bootstrap.js +0 -246
- package/extensions/dm-lens/dist/clients/bounded-cache.js +0 -105
- package/extensions/dm-lens/dist/clients/bounded-pid-file-lock.js +0 -173
- package/extensions/dm-lens/dist/clients/bounded-telemetry.js +0 -104
- package/extensions/dm-lens/dist/clients/build-identity.js +0 -45
- package/extensions/dm-lens/dist/clients/bundled-resource-health.js +0 -41
- package/extensions/dm-lens/dist/clients/bus-events-logger.js +0 -48
- package/extensions/dm-lens/dist/clients/bus-publish.js +0 -117
- package/extensions/dm-lens/dist/clients/cache/rule-cache.js +0 -103
- package/extensions/dm-lens/dist/clients/cache-manager.js +0 -340
- package/extensions/dm-lens/dist/clients/cache-observability.js +0 -847
- package/extensions/dm-lens/dist/clients/call-graph.js +0 -628
- package/extensions/dm-lens/dist/clients/cargo-manifest.js +0 -151
- package/extensions/dm-lens/dist/clients/cascade-budget.js +0 -52
- package/extensions/dm-lens/dist/clients/cascade-format.js +0 -160
- package/extensions/dm-lens/dist/clients/cascade-logger.js +0 -22
- package/extensions/dm-lens/dist/clients/cascade-types.js +0 -1
- package/extensions/dm-lens/dist/clients/child-unref.js +0 -59
- package/extensions/dm-lens/dist/clients/code-quality-warnings.js +0 -192
- package/extensions/dm-lens/dist/clients/codebase-model.js +0 -110
- package/extensions/dm-lens/dist/clients/collateral-test-role.js +0 -8
- package/extensions/dm-lens/dist/clients/complexity-client.js +0 -398
- package/extensions/dm-lens/dist/clients/config-core/deny.js +0 -117
- package/extensions/dm-lens/dist/clients/config-core/index.js +0 -2
- package/extensions/dm-lens/dist/clients/config-core/merge.js +0 -228
- package/extensions/dm-lens/dist/clients/config-core/normalize.js +0 -217
- package/extensions/dm-lens/dist/clients/config-core/process-spec.js +0 -147
- package/extensions/dm-lens/dist/clients/config-core/provenance.js +0 -54
- package/extensions/dm-lens/dist/clients/config-core/records.js +0 -79
- package/extensions/dm-lens/dist/clients/config-core/resolve.js +0 -48
- package/extensions/dm-lens/dist/clients/config-core/safe-object.js +0 -22
- package/extensions/dm-lens/dist/clients/config-core/schema.js +0 -90
- package/extensions/dm-lens/dist/clients/config-diagnostic-codes.js +0 -90
- package/extensions/dm-lens/dist/clients/config-locations.js +0 -175
- package/extensions/dm-lens/dist/clients/config-resolve.js +0 -359
- package/extensions/dm-lens/dist/clients/config-schema.js +0 -128
- package/extensions/dm-lens/dist/clients/config-warn.js +0 -146
- package/extensions/dm-lens/dist/clients/console-guard-install.js +0 -4
- package/extensions/dm-lens/dist/clients/cooperative-budget.js +0 -36
- package/extensions/dm-lens/dist/clients/dead-code-client.js +0 -342
- package/extensions/dm-lens/dist/clients/dead-code-logger.js +0 -18
- package/extensions/dm-lens/dist/clients/deadline-utils.js +0 -117
- package/extensions/dm-lens/dist/clients/debug-handles.js +0 -121
- package/extensions/dm-lens/dist/clients/debug-heap.js +0 -80
- package/extensions/dm-lens/dist/clients/deferred-lsp-work.js +0 -33
- package/extensions/dm-lens/dist/clients/degradation-ledger.js +0 -272
- package/extensions/dm-lens/dist/clients/demoted-finding-render.js +0 -61
- package/extensions/dm-lens/dist/clients/dependency-checker.js +0 -525
- package/extensions/dm-lens/dist/clients/deps/ast-grep-napi.js +0 -17
- package/extensions/dm-lens/dist/clients/deps/dm-host-deps.js +0 -10
- package/extensions/dm-lens/dist/clients/deps/dm-tui-compat.js +0 -58
- package/extensions/dm-lens/dist/clients/deps/js-yaml.js +0 -7
- package/extensions/dm-lens/dist/clients/deps/minimatch.js +0 -6
- package/extensions/dm-lens/dist/clients/deps/pidusage.js +0 -5
- package/extensions/dm-lens/dist/clients/deps/typebox.js +0 -5
- package/extensions/dm-lens/dist/clients/deps/vscode-jsonrpc.js +0 -8
- package/extensions/dm-lens/dist/clients/deps/web-tree-sitter.js +0 -11
- package/extensions/dm-lens/dist/clients/diagnostic-dispositions.js +0 -318
- package/extensions/dm-lens/dist/clients/diagnostic-line-freshness.js +0 -144
- package/extensions/dm-lens/dist/clients/diagnostic-logger.js +0 -60
- package/extensions/dm-lens/dist/clients/diagnostic-tracker.js +0 -89
- package/extensions/dm-lens/dist/clients/diagnostics-publish.js +0 -134
- package/extensions/dm-lens/dist/clients/dispatch/ast-grep-catalog.js +0 -16
- package/extensions/dm-lens/dist/clients/dispatch/auxiliary-lsp.js +0 -158
- package/extensions/dm-lens/dist/clients/dispatch/collect-later-tier.js +0 -25
- package/extensions/dm-lens/dist/clients/dispatch/diagnostic-taxonomy.js +0 -58
- package/extensions/dm-lens/dist/clients/dispatch/dispatcher.js +0 -953
- package/extensions/dm-lens/dist/clients/dispatch/fact-provider-types.js +0 -1
- package/extensions/dm-lens/dist/clients/dispatch/fact-rule-runner.js +0 -17
- package/extensions/dm-lens/dist/clients/dispatch/fact-runner.js +0 -18
- package/extensions/dm-lens/dist/clients/dispatch/fact-scheduler.js +0 -52
- package/extensions/dm-lens/dist/clients/dispatch/fact-store.js +0 -199
- package/extensions/dm-lens/dist/clients/dispatch/facts/comment-facts.js +0 -20
- package/extensions/dm-lens/dist/clients/dispatch/facts/file-content.js +0 -18
- package/extensions/dm-lens/dist/clients/dispatch/facts/function-facts.js +0 -281
- package/extensions/dm-lens/dist/clients/dispatch/facts/import-facts.js +0 -169
- package/extensions/dm-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -19
- package/extensions/dm-lens/dist/clients/dispatch/facts/try-catch-facts.js +0 -95
- package/extensions/dm-lens/dist/clients/dispatch/finding-policy.js +0 -159
- package/extensions/dm-lens/dist/clients/dispatch/indent-detect.js +0 -227
- package/extensions/dm-lens/dist/clients/dispatch/inline-suppressions.js +0 -52
- package/extensions/dm-lens/dist/clients/dispatch/integration.js +0 -1463
- package/extensions/dm-lens/dist/clients/dispatch/lazy.js +0 -8
- package/extensions/dm-lens/dist/clients/dispatch/pending-runner-findings.js +0 -75
- package/extensions/dm-lens/dist/clients/dispatch/plan.js +0 -278
- package/extensions/dm-lens/dist/clients/dispatch/priorities.js +0 -14
- package/extensions/dm-lens/dist/clients/dispatch/rule-id-normalize.js +0 -42
- package/extensions/dm-lens/dist/clients/dispatch/rule-ignores.js +0 -21
- package/extensions/dm-lens/dist/clients/dispatch/rule-policy.js +0 -73
- package/extensions/dm-lens/dist/clients/dispatch/rules/async-noise.js +0 -31
- package/extensions/dm-lens/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
- package/extensions/dm-lens/dist/clients/dispatch/rules/cors-wildcard.js +0 -35
- package/extensions/dm-lens/dist/clients/dispatch/rules/error-obscuring.js +0 -29
- package/extensions/dm-lens/dist/clients/dispatch/rules/error-swallowing.js +0 -29
- package/extensions/dm-lens/dist/clients/dispatch/rules/framework-call-noise.js +0 -31
- package/extensions/dm-lens/dist/clients/dispatch/rules/high-complexity.js +0 -56
- package/extensions/dm-lens/dist/clients/dispatch/rules/high-fan-out.js +0 -45
- package/extensions/dm-lens/dist/clients/dispatch/rules/high-import-coupling.js +0 -31
- package/extensions/dm-lens/dist/clients/dispatch/rules/missing-error-propagation.js +0 -45
- package/extensions/dm-lens/dist/clients/dispatch/rules/no-commented-credentials.js +0 -46
- package/extensions/dm-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -38
- package/extensions/dm-lens/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
- package/extensions/dm-lens/dist/clients/dispatch/rules/unsafe-boundary.js +0 -101
- package/extensions/dm-lens/dist/clients/dispatch/runner-context.js +0 -46
- package/extensions/dm-lens/dist/clients/dispatch/runners/actionlint.js +0 -98
- package/extensions/dm-lens/dist/clients/dispatch/runners/ast-grep-napi.js +0 -690
- package/extensions/dm-lens/dist/clients/dispatch/runners/biome-check.js +0 -202
- package/extensions/dm-lens/dist/clients/dispatch/runners/cpp-check.js +0 -190
- package/extensions/dm-lens/dist/clients/dispatch/runners/credo.js +0 -66
- package/extensions/dm-lens/dist/clients/dispatch/runners/cue-vet.js +0 -167
- package/extensions/dm-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -151
- package/extensions/dm-lens/dist/clients/dispatch/runners/detekt.js +0 -157
- package/extensions/dm-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -157
- package/extensions/dm-lens/dist/clients/dispatch/runners/elixir-check.js +0 -153
- package/extensions/dm-lens/dist/clients/dispatch/runners/eslint.js +0 -99
- package/extensions/dm-lens/dist/clients/dispatch/runners/fact-rules.js +0 -20
- package/extensions/dm-lens/dist/clients/dispatch/runners/fish-indent.js +0 -65
- package/extensions/dm-lens/dist/clients/dispatch/runners/gleam-check.js +0 -107
- package/extensions/dm-lens/dist/clients/dispatch/runners/go-vet.js +0 -51
- package/extensions/dm-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -89
- package/extensions/dm-lens/dist/clients/dispatch/runners/hadolint.js +0 -83
- package/extensions/dm-lens/dist/clients/dispatch/runners/helm-lint.js +0 -144
- package/extensions/dm-lens/dist/clients/dispatch/runners/helm-render.js +0 -593
- package/extensions/dm-lens/dist/clients/dispatch/runners/htmlhint.js +0 -103
- package/extensions/dm-lens/dist/clients/dispatch/runners/index.js +0 -100
- package/extensions/dm-lens/dist/clients/dispatch/runners/javac.js +0 -82
- package/extensions/dm-lens/dist/clients/dispatch/runners/ktlint.js +0 -93
- package/extensions/dm-lens/dist/clients/dispatch/runners/lsp.js +0 -206
- package/extensions/dm-lens/dist/clients/dispatch/runners/markdownlint.js +0 -129
- package/extensions/dm-lens/dist/clients/dispatch/runners/mypy.js +0 -70
- package/extensions/dm-lens/dist/clients/dispatch/runners/oxlint.js +0 -305
- package/extensions/dm-lens/dist/clients/dispatch/runners/php-lint.js +0 -70
- package/extensions/dm-lens/dist/clients/dispatch/runners/phpstan.js +0 -90
- package/extensions/dm-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -56
- package/extensions/dm-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -307
- package/extensions/dm-lens/dist/clients/dispatch/runners/pyright.js +0 -118
- package/extensions/dm-lens/dist/clients/dispatch/runners/rubocop.js +0 -79
- package/extensions/dm-lens/dist/clients/dispatch/runners/ruff.js +0 -69
- package/extensions/dm-lens/dist/clients/dispatch/runners/rust-clippy.js +0 -147
- package/extensions/dm-lens/dist/clients/dispatch/runners/shellcheck.js +0 -111
- package/extensions/dm-lens/dist/clients/dispatch/runners/shfmt.js +0 -81
- package/extensions/dm-lens/dist/clients/dispatch/runners/spellcheck.js +0 -74
- package/extensions/dm-lens/dist/clients/dispatch/runners/spotbugs.js +0 -208
- package/extensions/dm-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -136
- package/extensions/dm-lens/dist/clients/dispatch/runners/stylelint.js +0 -118
- package/extensions/dm-lens/dist/clients/dispatch/runners/swiftlint.js +0 -143
- package/extensions/dm-lens/dist/clients/dispatch/runners/taplo.js +0 -97
- package/extensions/dm-lens/dist/clients/dispatch/runners/terragrunt.js +0 -110
- package/extensions/dm-lens/dist/clients/dispatch/runners/tflint.js +0 -104
- package/extensions/dm-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -516
- package/extensions/dm-lens/dist/clients/dispatch/runners/trivy-config.js +0 -155
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/availability-policy.js +0 -285
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -61
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -61
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -130
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1067
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -40
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/tool-failure.js +0 -117
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -88
- package/extensions/dm-lens/dist/clients/dispatch/runners/utils.js +0 -8
- package/extensions/dm-lens/dist/clients/dispatch/runners/vale.js +0 -106
- package/extensions/dm-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -163
- package/extensions/dm-lens/dist/clients/dispatch/runners/yamllint.js +0 -83
- package/extensions/dm-lens/dist/clients/dispatch/runners/zig-check.js +0 -72
- package/extensions/dm-lens/dist/clients/dispatch/suppress-writer.js +0 -57
- package/extensions/dm-lens/dist/clients/dispatch/tool-profile.js +0 -30
- package/extensions/dm-lens/dist/clients/dispatch/types.js +0 -7
- package/extensions/dm-lens/dist/clients/dispatch/utils/format-utils.js +0 -45
- package/extensions/dm-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -31
- package/extensions/dm-lens/dist/clients/disposition-logger.js +0 -19
- package/extensions/dm-lens/dist/clients/disposition-publish.js +0 -88
- package/extensions/dm-lens/dist/clients/durable-store.js +0 -77
- package/extensions/dm-lens/dist/clients/effective-config.js +0 -160
- package/extensions/dm-lens/dist/clients/env-utils.js +0 -26
- package/extensions/dm-lens/dist/clients/error-class.js +0 -3
- package/extensions/dm-lens/dist/clients/eval-timestamp.js +0 -2
- package/extensions/dm-lens/dist/clients/event-loop-hold.js +0 -119
- package/extensions/dm-lens/dist/clients/event-loop-monitor.js +0 -84
- package/extensions/dm-lens/dist/clients/extension-log.js +0 -230
- package/extensions/dm-lens/dist/clients/extension-mode.js +0 -20
- package/extensions/dm-lens/dist/clients/feature-hints.js +0 -88
- package/extensions/dm-lens/dist/clients/file-kinds.js +0 -304
- package/extensions/dm-lens/dist/clients/file-role.js +0 -50
- package/extensions/dm-lens/dist/clients/file-time.js +0 -112
- package/extensions/dm-lens/dist/clients/file-utils.js +0 -630
- package/extensions/dm-lens/dist/clients/finding-delivery-gate.js +0 -129
- package/extensions/dm-lens/dist/clients/finding-identity.js +0 -23
- package/extensions/dm-lens/dist/clients/fix-worklog.js +0 -75
- package/extensions/dm-lens/dist/clients/format-events-publish.js +0 -230
- package/extensions/dm-lens/dist/clients/format-service.js +0 -154
- package/extensions/dm-lens/dist/clients/formatters-lazy.js +0 -8
- package/extensions/dm-lens/dist/clients/formatters.js +0 -1351
- package/extensions/dm-lens/dist/clients/freshness-cadence.js +0 -1
- package/extensions/dm-lens/dist/clients/freshness.js +0 -8
- package/extensions/dm-lens/dist/clients/generated-artifacts.js +0 -209
- package/extensions/dm-lens/dist/clients/generation-guard.js +0 -105
- package/extensions/dm-lens/dist/clients/git-guard.js +0 -770
- package/extensions/dm-lens/dist/clients/git-tracked-ignore.js +0 -120
- package/extensions/dm-lens/dist/clients/gitleaks-client.js +0 -282
- package/extensions/dm-lens/dist/clients/go-client.js +0 -47
- package/extensions/dm-lens/dist/clients/govulncheck-client.js +0 -411
- package/extensions/dm-lens/dist/clients/gradle-ktfmt-style.js +0 -177
- package/extensions/dm-lens/dist/clients/grammar-source.js +0 -224
- package/extensions/dm-lens/dist/clients/gzip-stage-write.js +0 -85
- package/extensions/dm-lens/dist/clients/hashline-anchor.js +0 -222
- package/extensions/dm-lens/dist/clients/hook-budgets.js +0 -16
- package/extensions/dm-lens/dist/clients/host-edit-normalize.js +0 -87
- package/extensions/dm-lens/dist/clients/host-ports.js +0 -35
- package/extensions/dm-lens/dist/clients/indent-retarget.js +0 -102
- package/extensions/dm-lens/dist/clients/inline-blocker-dispositions.js +0 -103
- package/extensions/dm-lens/dist/clients/install-diagnostics.js +0 -123
- package/extensions/dm-lens/dist/clients/installer/index.js +0 -3770
- package/extensions/dm-lens/dist/clients/installer/managed-tool-refresh-session.js +0 -17
- package/extensions/dm-lens/dist/clients/installer/managed-tool-refresh.js +0 -522
- package/extensions/dm-lens/dist/clients/instance-reaper-state.js +0 -3
- package/extensions/dm-lens/dist/clients/instance-reaper.js +0 -577
- package/extensions/dm-lens/dist/clients/instance-registry-lock.js +0 -131
- package/extensions/dm-lens/dist/clients/instance-registry.js +0 -452
- package/extensions/dm-lens/dist/clients/jscpd-client.js +0 -252
- package/extensions/dm-lens/dist/clients/json-cache-read.js +0 -25
- package/extensions/dm-lens/dist/clients/knip-client.js +0 -472
- package/extensions/dm-lens/dist/clients/language-policy.js +0 -242
- package/extensions/dm-lens/dist/clients/language-profile.js +0 -261
- package/extensions/dm-lens/dist/clients/language-registry.js +0 -424
- package/extensions/dm-lens/dist/clients/latency-logger.js +0 -192
- package/extensions/dm-lens/dist/clients/lazy-import.js +0 -14
- package/extensions/dm-lens/dist/clients/ledger-bounds.js +0 -21
- package/extensions/dm-lens/dist/clients/lens-config.js +0 -237
- package/extensions/dm-lens/dist/clients/lens-engine.js +0 -181
- package/extensions/dm-lens/dist/clients/lens-events.js +0 -105
- package/extensions/dm-lens/dist/clients/lens-flag-registry.js +0 -302
- package/extensions/dm-lens/dist/clients/lens-map.js +0 -980
- package/extensions/dm-lens/dist/clients/live-bus-emitter.js +0 -53
- package/extensions/dm-lens/dist/clients/log-cleanup.js +0 -138
- package/extensions/dm-lens/dist/clients/lsp/aggregation.js +0 -88
- package/extensions/dm-lens/dist/clients/lsp/cascade-tier.js +0 -203
- package/extensions/dm-lens/dist/clients/lsp/client.js +0 -2709
- package/extensions/dm-lens/dist/clients/lsp/config.js +0 -252
- package/extensions/dm-lens/dist/clients/lsp/content-limits.js +0 -21
- package/extensions/dm-lens/dist/clients/lsp/diagnostic-binding.js +0 -79
- package/extensions/dm-lens/dist/clients/lsp/document-drift.js +0 -312
- package/extensions/dm-lens/dist/clients/lsp/edits.js +0 -930
- package/extensions/dm-lens/dist/clients/lsp/index.js +0 -4448
- package/extensions/dm-lens/dist/clients/lsp/inferred-project.js +0 -121
- package/extensions/dm-lens/dist/clients/lsp/jvm-runtime.js +0 -194
- package/extensions/dm-lens/dist/clients/lsp/language.js +0 -23
- package/extensions/dm-lens/dist/clients/lsp/launch.js +0 -468
- package/extensions/dm-lens/dist/clients/lsp/lombok.js +0 -146
- package/extensions/dm-lens/dist/clients/lsp/path-utils.js +0 -1
- package/extensions/dm-lens/dist/clients/lsp/pending-aux-coverage.js +0 -90
- package/extensions/dm-lens/dist/clients/lsp/position-encoding.js +0 -28
- package/extensions/dm-lens/dist/clients/lsp/ruby-drive-dirs.js +0 -42
- package/extensions/dm-lens/dist/clients/lsp/server.js +0 -2422
- package/extensions/dm-lens/dist/clients/lsp/session-roots.js +0 -52
- package/extensions/dm-lens/dist/clients/lsp/spawn-history.js +0 -15
- package/extensions/dm-lens/dist/clients/lsp/sync-kind.js +0 -30
- package/extensions/dm-lens/dist/clients/lsp/tsserver-sync.js +0 -156
- package/extensions/dm-lens/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
- package/extensions/dm-lens/dist/clients/lsp/wait-policy/classification.js +0 -36
- package/extensions/dm-lens/dist/clients/lsp/wait-policy/index.js +0 -3
- package/extensions/dm-lens/dist/clients/lsp/wait-policy/strategies.js +0 -175
- package/extensions/dm-lens/dist/clients/lsp/watch-queue.js +0 -40
- package/extensions/dm-lens/dist/clients/lsp/workspace-diagnostics-cache.js +0 -267
- package/extensions/dm-lens/dist/clients/lsp/workspace-diagnostics-session.js +0 -7
- package/extensions/dm-lens/dist/clients/lsp/workspace-sweep-hold.js +0 -93
- package/extensions/dm-lens/dist/clients/lsp-budget.js +0 -83
- package/extensions/dm-lens/dist/clients/lsp-document-symbols.js +0 -93
- package/extensions/dm-lens/dist/clients/lsp-lazy.js +0 -8
- package/extensions/dm-lens/dist/clients/lsp-mutation.js +0 -273
- package/extensions/dm-lens/dist/clients/lsp-status.js +0 -37
- package/extensions/dm-lens/dist/clients/map-with-concurrency.js +0 -20
- package/extensions/dm-lens/dist/clients/mcp/analyze.js +0 -251
- package/extensions/dm-lens/dist/clients/mcp/host-shim.js +0 -14
- package/extensions/dm-lens/dist/clients/mcp/ipc.js +0 -302
- package/extensions/dm-lens/dist/clients/mcp/review.js +0 -137
- package/extensions/dm-lens/dist/clients/mcp/session.js +0 -305
- package/extensions/dm-lens/dist/clients/memory-sampler.js +0 -107
- package/extensions/dm-lens/dist/clients/message-end-attribution.js +0 -18
- package/extensions/dm-lens/dist/clients/metrics-client.js +0 -80
- package/extensions/dm-lens/dist/clients/metrics-history.js +0 -255
- package/extensions/dm-lens/dist/clients/middle-man-analysis.js +0 -161
- package/extensions/dm-lens/dist/clients/model-provider.js +0 -31
- package/extensions/dm-lens/dist/clients/module-report-lsp.js +0 -140
- package/extensions/dm-lens/dist/clients/module-report.js +0 -1642
- package/extensions/dm-lens/dist/clients/mutating-tool.js +0 -377
- package/extensions/dm-lens/dist/clients/mutation-attribution.js +0 -168
- package/extensions/dm-lens/dist/clients/mutation-bridge.js +0 -102
- package/extensions/dm-lens/dist/clients/ndjson-logger.js +0 -471
- package/extensions/dm-lens/dist/clients/observed-mutation-sources.js +0 -43
- package/extensions/dm-lens/dist/clients/observed-mutation.js +0 -709
- package/extensions/dm-lens/dist/clients/oldtext-autopatch.js +0 -100
- package/extensions/dm-lens/dist/clients/opaque-mutation-scan.js +0 -313
- package/extensions/dm-lens/dist/clients/opengrep-client.js +0 -216
- package/extensions/dm-lens/dist/clients/opengrep-config.js +0 -52
- package/extensions/dm-lens/dist/clients/package-manager.js +0 -303
- package/extensions/dm-lens/dist/clients/package-root.js +0 -25
- package/extensions/dm-lens/dist/clients/partial-edit-apply.js +0 -337
- package/extensions/dm-lens/dist/clients/path-attribution-telemetry.js +0 -31
- package/extensions/dm-lens/dist/clients/path-keyed-map.js +0 -57
- package/extensions/dm-lens/dist/clients/path-utils.js +0 -476
- package/extensions/dm-lens/dist/clients/performance-report.js +0 -291
- package/extensions/dm-lens/dist/clients/persist-debounce.js +0 -37
- package/extensions/dm-lens/dist/clients/persistent-reverify.js +0 -165
- package/extensions/dm-lens/dist/clients/php-cs-fixer-config.js +0 -15
- package/extensions/dm-lens/dist/clients/pipeline.js +0 -1091
- package/extensions/dm-lens/dist/clients/post-autofix-notice.js +0 -19
- package/extensions/dm-lens/dist/clients/print-mode.js +0 -3
- package/extensions/dm-lens/dist/clients/probe-home-state.js +0 -62
- package/extensions/dm-lens/dist/clients/process-bridge.js +0 -20
- package/extensions/dm-lens/dist/clients/process-singletons.js +0 -69
- package/extensions/dm-lens/dist/clients/process-snapshot.js +0 -22
- package/extensions/dm-lens/dist/clients/project-changes.js +0 -112
- package/extensions/dm-lens/dist/clients/project-conventions.js +0 -152
- package/extensions/dm-lens/dist/clients/project-diagnostics/cache.js +0 -91
- package/extensions/dm-lens/dist/clients/project-diagnostics/extractors.js +0 -53
- package/extensions/dm-lens/dist/clients/project-diagnostics/fresh-fetch.js +0 -408
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -64
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -38
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -21
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -23
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -28
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -45
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -34
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -32
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -79
- package/extensions/dm-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -41
- package/extensions/dm-lens/dist/clients/project-diagnostics/scanner.js +0 -349
- package/extensions/dm-lens/dist/clients/project-diagnostics/types.js +0 -1
- package/extensions/dm-lens/dist/clients/project-lens-config.js +0 -437
- package/extensions/dm-lens/dist/clients/project-report.js +0 -527
- package/extensions/dm-lens/dist/clients/project-scale.js +0 -60
- package/extensions/dm-lens/dist/clients/project-scan-policy.js +0 -4
- package/extensions/dm-lens/dist/clients/project-snapshot-fingerprint.js +0 -39
- package/extensions/dm-lens/dist/clients/project-snapshot-persist-worker.js +0 -14
- package/extensions/dm-lens/dist/clients/project-snapshot.js +0 -1178
- package/extensions/dm-lens/dist/clients/project-trust.js +0 -104
- package/extensions/dm-lens/dist/clients/python-environment.js +0 -120
- package/extensions/dm-lens/dist/clients/python-provenance.js +0 -551
- package/extensions/dm-lens/dist/clients/quiet-window-config.js +0 -16
- package/extensions/dm-lens/dist/clients/quiet-window.js +0 -126
- package/extensions/dm-lens/dist/clients/read-bridge.js +0 -46
- package/extensions/dm-lens/dist/clients/read-expansion.js +0 -218
- package/extensions/dm-lens/dist/clients/read-guard-logger.js +0 -178
- package/extensions/dm-lens/dist/clients/read-guard-tool-lines.js +0 -1042
- package/extensions/dm-lens/dist/clients/read-guard.js +0 -1096
- package/extensions/dm-lens/dist/clients/recent-touches.js +0 -126
- package/extensions/dm-lens/dist/clients/redact/secrets.js +0 -386
- package/extensions/dm-lens/dist/clients/resource-sampler.js +0 -344
- package/extensions/dm-lens/dist/clients/reverse-deps.js +0 -227
- package/extensions/dm-lens/dist/clients/review-graph/builder.js +0 -3635
- package/extensions/dm-lens/dist/clients/review-graph/format.js +0 -30
- package/extensions/dm-lens/dist/clients/review-graph/git-identity.js +0 -115
- package/extensions/dm-lens/dist/clients/review-graph/import-resolvers.js +0 -325
- package/extensions/dm-lens/dist/clients/review-graph/persist-worker.js +0 -8
- package/extensions/dm-lens/dist/clients/review-graph/query.js +0 -195
- package/extensions/dm-lens/dist/clients/review-graph/revision-drift.js +0 -3
- package/extensions/dm-lens/dist/clients/review-graph/service.js +0 -60
- package/extensions/dm-lens/dist/clients/review-graph/shared-extraction-ir.js +0 -54
- package/extensions/dm-lens/dist/clients/review-graph/symbol-id.js +0 -29
- package/extensions/dm-lens/dist/clients/review-graph/tsconfig-paths.js +0 -253
- package/extensions/dm-lens/dist/clients/review-graph/types.js +0 -1
- package/extensions/dm-lens/dist/clients/review-graph/workspace-modules.js +0 -374
- package/extensions/dm-lens/dist/clients/review-graph-logger.js +0 -51
- package/extensions/dm-lens/dist/clients/ruff-client.js +0 -109
- package/extensions/dm-lens/dist/clients/rules-scanner.js +0 -113
- package/extensions/dm-lens/dist/clients/run-duration.js +0 -9
- package/extensions/dm-lens/dist/clients/runtime-agent-end.js +0 -608
- package/extensions/dm-lens/dist/clients/runtime-config.js +0 -39
- package/extensions/dm-lens/dist/clients/runtime-context.js +0 -155
- package/extensions/dm-lens/dist/clients/runtime-coordinator.js +0 -817
- package/extensions/dm-lens/dist/clients/runtime-session.js +0 -1625
- package/extensions/dm-lens/dist/clients/runtime-tool-call.js +0 -868
- package/extensions/dm-lens/dist/clients/runtime-tool-result.js +0 -1317
- package/extensions/dm-lens/dist/clients/runtime-turn.js +0 -2333
- package/extensions/dm-lens/dist/clients/rust-client.js +0 -48
- package/extensions/dm-lens/dist/clients/safe-spawn.js +0 -1267
- package/extensions/dm-lens/dist/clients/sanitize.js +0 -174
- package/extensions/dm-lens/dist/clients/scan-utils.js +0 -7
- package/extensions/dm-lens/dist/clients/scratch-tree-policy.js +0 -57
- package/extensions/dm-lens/dist/clients/search-read-registration.js +0 -59
- package/extensions/dm-lens/dist/clients/secret-findings.js +0 -69
- package/extensions/dm-lens/dist/clients/security-scan-client.js +0 -208
- package/extensions/dm-lens/dist/clients/session-event-guard.js +0 -111
- package/extensions/dm-lens/dist/clients/session-lifecycle.js +0 -173
- package/extensions/dm-lens/dist/clients/session-start-observability.js +0 -47
- package/extensions/dm-lens/dist/clients/session-state-store.js +0 -63
- package/extensions/dm-lens/dist/clients/session-summary.js +0 -8
- package/extensions/dm-lens/dist/clients/sessionstart-logger.js +0 -22
- package/extensions/dm-lens/dist/clients/sg-runner.js +0 -627
- package/extensions/dm-lens/dist/clients/sgconfig.js +0 -280
- package/extensions/dm-lens/dist/clients/shared-checkout-guard.js +0 -177
- package/extensions/dm-lens/dist/clients/single-flight.js +0 -52
- package/extensions/dm-lens/dist/clients/situational-tool-telemetry.js +0 -85
- package/extensions/dm-lens/dist/clients/skills-resolver.js +0 -38
- package/extensions/dm-lens/dist/clients/slow-fs.js +0 -77
- package/extensions/dm-lens/dist/clients/smells-rollup.js +0 -118
- package/extensions/dm-lens/dist/clients/source-filter.js +0 -320
- package/extensions/dm-lens/dist/clients/source-walker.js +0 -96
- package/extensions/dm-lens/dist/clients/spawn-output-cap.js +0 -35
- package/extensions/dm-lens/dist/clients/spawn-timeout-cooldown.js +0 -51
- package/extensions/dm-lens/dist/clients/stale-marker.js +0 -1
- package/extensions/dm-lens/dist/clients/startup-scan.js +0 -222
- package/extensions/dm-lens/dist/clients/startup-timing.js +0 -67
- package/extensions/dm-lens/dist/clients/string-utils.js +0 -6
- package/extensions/dm-lens/dist/clients/subagent-mode.js +0 -40
- package/extensions/dm-lens/dist/clients/symbol-containment.js +0 -16
- package/extensions/dm-lens/dist/clients/symbol-types.js +0 -1
- package/extensions/dm-lens/dist/clients/test-runner-client.js +0 -1504
- package/extensions/dm-lens/dist/clients/test-runner-delivery.js +0 -260
- package/extensions/dm-lens/dist/clients/todo-scanner.js +0 -164
- package/extensions/dm-lens/dist/clients/tool-agreement.js +0 -377
- package/extensions/dm-lens/dist/clients/tool-config.js +0 -218
- package/extensions/dm-lens/dist/clients/tool-cwd.js +0 -235
- package/extensions/dm-lens/dist/clients/tool-definition.js +0 -22
- package/extensions/dm-lens/dist/clients/tool-event.js +0 -18
- package/extensions/dm-lens/dist/clients/tool-policy.js +0 -2393
- package/extensions/dm-lens/dist/clients/tool-probe.js +0 -5
- package/extensions/dm-lens/dist/clients/tool-render.js +0 -79
- package/extensions/dm-lens/dist/clients/tool-set-policy.js +0 -70
- package/extensions/dm-lens/dist/clients/tree-sitter-cache.js +0 -206
- package/extensions/dm-lens/dist/clients/tree-sitter-client.js +0 -2787
- package/extensions/dm-lens/dist/clients/tree-sitter-logger.js +0 -77
- package/extensions/dm-lens/dist/clients/tree-sitter-navigator.js +0 -198
- package/extensions/dm-lens/dist/clients/tree-sitter-query-loader.js +0 -318
- package/extensions/dm-lens/dist/clients/tree-sitter-shared.js +0 -87
- package/extensions/dm-lens/dist/clients/tree-sitter-symbol-extractor.js +0 -957
- package/extensions/dm-lens/dist/clients/trivy-client.js +0 -305
- package/extensions/dm-lens/dist/clients/tui-fit.js +0 -26
- package/extensions/dm-lens/dist/clients/turn-context.js +0 -48
- package/extensions/dm-lens/dist/clients/turn-end/lane.js +0 -1
- package/extensions/dm-lens/dist/clients/turn-end/lanes/govulncheck.js +0 -54
- package/extensions/dm-lens/dist/clients/turn-end/lanes/secrets.js +0 -131
- package/extensions/dm-lens/dist/clients/turn-summary-render.js +0 -56
- package/extensions/dm-lens/dist/clients/turn-summary.js +0 -84
- package/extensions/dm-lens/dist/clients/typos-config.js +0 -9
- package/extensions/dm-lens/dist/clients/user-notify.js +0 -15
- package/extensions/dm-lens/dist/clients/vanished-instance-marker.js +0 -18
- package/extensions/dm-lens/dist/clients/warm-attach.js +0 -210
- package/extensions/dm-lens/dist/clients/widget-state.js +0 -963
- package/extensions/dm-lens/dist/clients/word-index-logger.js +0 -21
- package/extensions/dm-lens/dist/clients/word-index-store.js +0 -222
- package/extensions/dm-lens/dist/clients/word-index.js +0 -1426
- package/extensions/dm-lens/dist/clients/workspace-topology.js +0 -261
- package/extensions/dm-lens/dist/clients/write-ordering-guard.js +0 -24
- package/extensions/dm-lens/dist/clients/zizmor-config.js +0 -160
- package/extensions/dm-lens/dist/i18n.js +0 -67
- package/extensions/dm-lens/dist/index.js +0 -1782
- package/extensions/dm-lens/dist/mcp/analyze-cli.js +0 -178
- package/extensions/dm-lens/dist/mcp/build-staleness.js +0 -55
- package/extensions/dm-lens/dist/mcp/cli.js +0 -78
- package/extensions/dm-lens/dist/mcp/server.js +0 -1208
- package/extensions/dm-lens/dist/mcp/worker.js +0 -33
- package/extensions/dm-lens/dist/scripts/lib/process-scan.mjs +0 -256
- package/extensions/dm-lens/dist/scripts/lib/skills-predicate.mjs +0 -53
- package/extensions/dm-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -45
- package/extensions/dm-lens/dist/tools/activate-tools.js +0 -61
- package/extensions/dm-lens/dist/tools/ast-grep-outline.js +0 -127
- package/extensions/dm-lens/dist/tools/ast-grep-replace.js +0 -226
- package/extensions/dm-lens/dist/tools/ast-grep-search.js +0 -687
- package/extensions/dm-lens/dist/tools/effective-config.js +0 -59
- package/extensions/dm-lens/dist/tools/lens-diagnostic-mark.js +0 -240
- package/extensions/dm-lens/dist/tools/lens-diagnostics.js +0 -1484
- package/extensions/dm-lens/dist/tools/lsp-diagnostics.js +0 -1088
- package/extensions/dm-lens/dist/tools/lsp-navigation.js +0 -1194
- package/extensions/dm-lens/dist/tools/lsp-structured-output.js +0 -277
- package/extensions/dm-lens/dist/tools/module-report.js +0 -332
- package/extensions/dm-lens/dist/tools/project-report.js +0 -72
- package/extensions/dm-lens/dist/tools/render-compact.js +0 -272
- package/extensions/dm-lens/dist/tools/scan-progress.js +0 -31
- package/extensions/dm-lens/dist/tools/shared.js +0 -26
- package/extensions/dm-lens/dist/tools/symbol-search.js +0 -133
- package/extensions/dm-mcp-adapter/dist/abort.js +0 -35
- package/extensions/dm-mcp-adapter/dist/agent-dir.js +0 -45
- package/extensions/dm-mcp-adapter/dist/agent-plugin-loader.js +0 -392
- package/extensions/dm-mcp-adapter/dist/agent-plugin-provenance.js +0 -26
- package/extensions/dm-mcp-adapter/dist/bearer-command-resolver.js +0 -182
- package/extensions/dm-mcp-adapter/dist/claude-plugin-loader.js +0 -350
- package/extensions/dm-mcp-adapter/dist/config.js +0 -1310
- package/extensions/dm-mcp-adapter/dist/consent-manager.js +0 -84
- package/extensions/dm-mcp-adapter/dist/elicitation-handler.js +0 -308
- package/extensions/dm-mcp-adapter/dist/errors.js +0 -225
- package/extensions/dm-mcp-adapter/dist/http-ca.js +0 -71
- package/extensions/dm-mcp-adapter/dist/jev-client.js +0 -359
- package/extensions/dm-mcp-adapter/dist/jev-contracts.js +0 -1
- package/extensions/dm-mcp-adapter/dist/jev-key-store.js +0 -176
- package/extensions/dm-mcp-adapter/dist/json-schema-validator.js +0 -70
- package/extensions/dm-mcp-adapter/dist/lifecycle.js +0 -387
- package/extensions/dm-mcp-adapter/dist/logger.js +0 -115
- package/extensions/dm-mcp-adapter/dist/mcp-auth-fetch.js +0 -86
- package/extensions/dm-mcp-adapter/dist/mcp-auth-flow.js +0 -949
- package/extensions/dm-mcp-adapter/dist/mcp-auth.js +0 -997
- package/extensions/dm-mcp-adapter/dist/mcp-bearer-store.js +0 -182
- package/extensions/dm-mcp-adapter/dist/mcp-callback-server.js +0 -381
- package/extensions/dm-mcp-adapter/dist/mcp-oauth-provider.js +0 -524
- package/extensions/dm-mcp-adapter/dist/mcp-probe.js +0 -151
- package/extensions/dm-mcp-adapter/dist/mcp-tasks.js +0 -300
- package/extensions/dm-mcp-adapter/dist/mcp-trace.js +0 -215
- package/extensions/dm-mcp-adapter/dist/metadata-cache.js +0 -267
- package/extensions/dm-mcp-adapter/dist/npx-resolver.js +0 -465
- package/extensions/dm-mcp-adapter/dist/package-mcp-loader.js +0 -135
- package/extensions/dm-mcp-adapter/dist/request-headers-command.js +0 -294
- package/extensions/dm-mcp-adapter/dist/resource-tools.js +0 -7
- package/extensions/dm-mcp-adapter/dist/runtime-owner.js +0 -94
- package/extensions/dm-mcp-adapter/dist/sampling-handler.js +0 -213
- package/extensions/dm-mcp-adapter/dist/secure-keyring.js +0 -191
- package/extensions/dm-mcp-adapter/dist/server-manager.js +0 -1514
- package/extensions/dm-mcp-adapter/dist/session-approvals.js +0 -127
- package/extensions/dm-mcp-adapter/dist/session-recovery.js +0 -82
- package/extensions/dm-mcp-adapter/dist/state.js +0 -1
- package/extensions/dm-mcp-adapter/dist/types.js +0 -286
- package/extensions/dm-mcp-adapter/dist/ui-app-bridge-helpers.js +0 -36
- package/extensions/dm-mcp-adapter/dist/ui-resource-handler.js +0 -204
- package/extensions/dm-mcp-adapter/dist/ui-stream-types.js +0 -58
- package/extensions/dm-mcp-adapter/dist/ui-tool-visibility.js +0 -26
- package/extensions/dm-mcp-adapter/dist/unix-socket-transport.js +0 -83
- package/extensions/dm-mcp-adapter/dist/utils.js +0 -382
|
@@ -1,997 +0,0 @@
|
|
|
1
|
-
import { spawnSync } from "child_process";
|
|
2
|
-
import { createCipheriv, createDecipheriv, createHash, randomBytes } from "crypto";
|
|
3
|
-
import { createRequire } from "module";
|
|
4
|
-
import { chmodSync, closeSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeFileSync } from "fs";
|
|
5
|
-
import { dirname, join } from "path";
|
|
6
|
-
import { fileURLToPath } from "url";
|
|
7
|
-
import { getAgentPath } from "./agent-dir.js";
|
|
8
|
-
import { resolveConfiguredOAuthDir } from "./config.js";
|
|
9
|
-
const require = createRequire(import.meta.url);
|
|
10
|
-
const AUTH_SECRET_SERVICE = "dm-mcp-adapter.oauth";
|
|
11
|
-
const TEST_AUTH_STORE_ENV = "DM_MCP_ADAPTER_TEST_AUTH_STORE";
|
|
12
|
-
const AUTH_SECRET_CHUNK_SIZE = 1000;
|
|
13
|
-
const AUTH_SECRET_VALUE_LIMIT = 1280;
|
|
14
|
-
const KEYRING_RECOVERY_DISABLED_ENV = "DM_MCP_ADAPTER_DISABLE_KEYRING_RECOVERY";
|
|
15
|
-
const KEYRING_RECOVERY_KEYCTL_ENV = "DM_MCP_ADAPTER_KEYRING_RECOVERY_KEYCTL";
|
|
16
|
-
const KEYRING_RECOVERY_NODE_ENV = "DM_MCP_ADAPTER_KEYRING_RECOVERY_NODE";
|
|
17
|
-
const KEYRING_RECOVERY_HELPER_ENV = "DM_MCP_ADAPTER_KEYRING_RECOVERY_HELPER";
|
|
18
|
-
const TEST_LINUX_KEYRING_RECOVERY_ENV = "DM_MCP_ADAPTER_TEST_LINUX_KEYRING_RECOVERY";
|
|
19
|
-
const AUTH_CACHE_DISABLED_ENV = "DM_MCP_ADAPTER_DISABLE_AUTH_CACHE";
|
|
20
|
-
const KEYRING_RECOVERY_TIMEOUT_MS = 1e4;
|
|
21
|
-
const AUTH_CHUNK_MANIFEST_KEY = "__piMcpAdapterOAuthChunked";
|
|
22
|
-
const OAUTH_FILE_KEY_ENV = "DM_MCP_ADAPTER_OAUTH_FILE_KEY";
|
|
23
|
-
const ENCRYPTED_FILE_AAD_CONTEXT = "dm-mcp-adapter.oauth.encrypted-file.v1";
|
|
24
|
-
const oauthLifecycleRecords = new Map;
|
|
25
|
-
function getOAuthLifecycleRecord(serverName) {
|
|
26
|
-
let record = oauthLifecycleRecords.get(serverName);
|
|
27
|
-
if (!record) {
|
|
28
|
-
record = { generation: {}, revocations: 0 };
|
|
29
|
-
oauthLifecycleRecords.set(serverName, record);
|
|
30
|
-
}
|
|
31
|
-
return record;
|
|
32
|
-
}
|
|
33
|
-
export function captureOAuthAuthority(serverName, assertNow = true) {
|
|
34
|
-
const record = getOAuthLifecycleRecord(serverName);
|
|
35
|
-
const generation = record.generation;
|
|
36
|
-
const capturedDuringRevocation = record.revocations > 0;
|
|
37
|
-
const assertAuthority = () => {
|
|
38
|
-
if (capturedDuringRevocation || record.generation !== generation || record.revocations > 0) {
|
|
39
|
-
throw new Error("OAuth flow is no longer active");
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
if (assertNow)
|
|
43
|
-
assertAuthority();
|
|
44
|
-
return assertAuthority;
|
|
45
|
-
}
|
|
46
|
-
export function beginOAuthRevocation(serverName) {
|
|
47
|
-
const record = getOAuthLifecycleRecord(serverName);
|
|
48
|
-
record.generation = {};
|
|
49
|
-
record.revocations += 1;
|
|
50
|
-
let released = false;
|
|
51
|
-
return () => {
|
|
52
|
-
if (released)
|
|
53
|
-
return;
|
|
54
|
-
released = true;
|
|
55
|
-
record.revocations -= 1;
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export class OAuthCredentialStoreError extends Error {
|
|
60
|
-
operation;
|
|
61
|
-
backend;
|
|
62
|
-
code = "OAUTH_CREDENTIAL_STORE_UNAVAILABLE";
|
|
63
|
-
constructor(message, operation, cause, backend) {
|
|
64
|
-
super(message, { cause });
|
|
65
|
-
this.operation = operation;
|
|
66
|
-
this.backend = backend;
|
|
67
|
-
this.name = "OAuthCredentialStoreError";
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
function causeChainContains(error, pattern) {
|
|
71
|
-
const seen = new Set;
|
|
72
|
-
let current = error;
|
|
73
|
-
while (typeof current === "object" && current !== null || typeof current === "function") {
|
|
74
|
-
if (seen.has(current))
|
|
75
|
-
break;
|
|
76
|
-
seen.add(current);
|
|
77
|
-
const candidate = current;
|
|
78
|
-
if ([candidate.name, candidate.message, candidate.code].some((value) => typeof value === "string" && pattern.test(value))) {
|
|
79
|
-
return true;
|
|
80
|
-
}
|
|
81
|
-
current = candidate.cause;
|
|
82
|
-
}
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
export function formatOAuthCredentialStoreUnavailable(error) {
|
|
86
|
-
if (error.backend === "encrypted-file") {
|
|
87
|
-
if (causeChainContains(error, /DM_MCP_ADAPTER_OAUTH_FILE_KEY/)) {
|
|
88
|
-
return "Encrypted OAuth credential file store unavailable. Set DM_MCP_ADAPTER_OAUTH_FILE_KEY to canonical base64 for exactly 32 random bytes and retry.";
|
|
89
|
-
}
|
|
90
|
-
return "Encrypted OAuth credential file store unavailable. Check the encrypted credential file and key, then reauthenticate.";
|
|
91
|
-
}
|
|
92
|
-
if (process.platform === "linux" && causeChainContains(error, /key\s*(?:has been\s*)?revoked|keyrevoked/i)) {
|
|
93
|
-
return "OAuth credential store unavailable: the Linux session keyring may be revoked. Start DM from a fresh login/keyring session and retry.";
|
|
94
|
-
}
|
|
95
|
-
if (causeChainContains(error, /ERROR_NO_SUCH_LOGON_SESSION|\b1312\b/i)) {
|
|
96
|
-
return 'OAuth credential store unavailable: Windows Credential Manager is unavailable from this network logon. To opt in to encrypted file storage for OpenSSH/headless use, set settings.oauthCredentialStore to "encrypted-file" and provide DM_MCP_ADAPTER_OAUTH_FILE_KEY.';
|
|
97
|
-
}
|
|
98
|
-
return "OAuth credential store unavailable. Configure or unlock the OS credential store and retry.";
|
|
99
|
-
}
|
|
100
|
-
function authSecretStoreLabel(store) {
|
|
101
|
-
return store.kind === "encrypted-file" ? "encrypted OAuth credential file store" : "OS secure credential store";
|
|
102
|
-
}
|
|
103
|
-
let KeyringEntryClass;
|
|
104
|
-
const keyringEntries = new Map;
|
|
105
|
-
const memoryAuthEntries = new Map;
|
|
106
|
-
let testAuthSecretStoreReadCount = 0;
|
|
107
|
-
const authEntryCache = new Map;
|
|
108
|
-
function isAuthEntryCacheEnabled() {
|
|
109
|
-
return process.env[AUTH_CACHE_DISABLED_ENV] !== "1";
|
|
110
|
-
}
|
|
111
|
-
function cloneAuthEntry(entry) {
|
|
112
|
-
return entry === undefined ? undefined : structuredClone(entry);
|
|
113
|
-
}
|
|
114
|
-
const memoryAuthSecretStore = {
|
|
115
|
-
read(account) {
|
|
116
|
-
testAuthSecretStoreReadCount++;
|
|
117
|
-
return memoryAuthEntries.get(account);
|
|
118
|
-
},
|
|
119
|
-
write(account, payload) {
|
|
120
|
-
memoryAuthEntries.set(account, payload);
|
|
121
|
-
},
|
|
122
|
-
remove(account) {
|
|
123
|
-
memoryAuthEntries.delete(account);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
const keyringAuthSecretStore = {
|
|
127
|
-
read(account) {
|
|
128
|
-
const cached = keyringEntries.get(account);
|
|
129
|
-
if (cached) {
|
|
130
|
-
try {
|
|
131
|
-
return cached.getPassword() ?? undefined;
|
|
132
|
-
} catch {}
|
|
133
|
-
keyringEntries.delete(account);
|
|
134
|
-
}
|
|
135
|
-
const fresh = getKeyringEntry(account);
|
|
136
|
-
const value = fresh.getPassword();
|
|
137
|
-
keyringEntries.set(account, fresh);
|
|
138
|
-
return value ?? undefined;
|
|
139
|
-
},
|
|
140
|
-
write(account, payload) {
|
|
141
|
-
keyringEntries.delete(account);
|
|
142
|
-
const fresh = getKeyringEntry(account);
|
|
143
|
-
fresh.setPassword(payload);
|
|
144
|
-
keyringEntries.set(account, fresh);
|
|
145
|
-
},
|
|
146
|
-
remove(account) {
|
|
147
|
-
keyringEntries.delete(account);
|
|
148
|
-
getKeyringEntry(account).deleteCredential();
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
const sizeLimitedAuthSecretStore = {
|
|
152
|
-
read(account) {
|
|
153
|
-
testAuthSecretStoreReadCount++;
|
|
154
|
-
return memoryAuthEntries.get(account);
|
|
155
|
-
},
|
|
156
|
-
write(account, payload) {
|
|
157
|
-
if (payload.length > AUTH_SECRET_VALUE_LIMIT) {
|
|
158
|
-
throw new Error(`Value of 'password encoded as UTF-16' is longer than the platform limit of ${AUTH_SECRET_VALUE_LIMIT * 2} chars`);
|
|
159
|
-
}
|
|
160
|
-
memoryAuthEntries.set(account, payload);
|
|
161
|
-
},
|
|
162
|
-
remove(account) {
|
|
163
|
-
memoryAuthEntries.delete(account);
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
const writeFailingAuthSecretStore = {
|
|
167
|
-
...memoryAuthSecretStore,
|
|
168
|
-
write() {
|
|
169
|
-
throw new Error("simulated secure credential store write failure");
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
const unavailableAuthSecretStore = {
|
|
173
|
-
read() {
|
|
174
|
-
testAuthSecretStoreReadCount++;
|
|
175
|
-
throw new Error("simulated secure credential store unavailable");
|
|
176
|
-
},
|
|
177
|
-
write() {
|
|
178
|
-
throw new Error("simulated secure credential store unavailable");
|
|
179
|
-
},
|
|
180
|
-
remove() {
|
|
181
|
-
throw new Error("simulated secure credential store unavailable");
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
function createKeyRevokedTestError() {
|
|
185
|
-
return new Error("Couldn't access platform storage: KeyRevoked", { cause: new Error("KeyRevoked") });
|
|
186
|
-
}
|
|
187
|
-
const keyRevokedAuthSecretStore = {
|
|
188
|
-
read() {
|
|
189
|
-
testAuthSecretStoreReadCount++;
|
|
190
|
-
throw createKeyRevokedTestError();
|
|
191
|
-
},
|
|
192
|
-
write() {
|
|
193
|
-
throw createKeyRevokedTestError();
|
|
194
|
-
},
|
|
195
|
-
remove() {
|
|
196
|
-
throw createKeyRevokedTestError();
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
export function resetTestAuthSecretStore() {
|
|
200
|
-
memoryAuthEntries.clear();
|
|
201
|
-
authEntryCache.clear();
|
|
202
|
-
keyringEntries.clear();
|
|
203
|
-
testAuthSecretStoreReadCount = 0;
|
|
204
|
-
}
|
|
205
|
-
export function setTestKeyringEntryClass(entryClass) {
|
|
206
|
-
keyringEntries.clear();
|
|
207
|
-
KeyringEntryClass = entryClass;
|
|
208
|
-
}
|
|
209
|
-
export function resetAuthEntryCache() {
|
|
210
|
-
authEntryCache.clear();
|
|
211
|
-
}
|
|
212
|
-
export function getTestAuthSecretStoreReadCount() {
|
|
213
|
-
return testAuthSecretStoreReadCount;
|
|
214
|
-
}
|
|
215
|
-
export function getTestAuthSecretStoreEntries() {
|
|
216
|
-
return [...memoryAuthEntries.entries()];
|
|
217
|
-
}
|
|
218
|
-
export function removeTestAuthSecretStoreEntry(account) {
|
|
219
|
-
memoryAuthEntries.delete(account);
|
|
220
|
-
}
|
|
221
|
-
export function setTestAuthSecretStoreEntry(account, payload) {
|
|
222
|
-
memoryAuthEntries.set(account, payload);
|
|
223
|
-
}
|
|
224
|
-
function decodeCanonicalBase64(value, expectedBytes) {
|
|
225
|
-
if (typeof value !== "string" || value.length === 0 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value)) {
|
|
226
|
-
throw new Error("value is not canonical base64");
|
|
227
|
-
}
|
|
228
|
-
const decoded = Buffer.from(value, "base64");
|
|
229
|
-
if (decoded.toString("base64") !== value || expectedBytes !== undefined && decoded.length !== expectedBytes) {
|
|
230
|
-
throw new Error(expectedBytes === undefined ? "value is not canonical base64" : `value must decode to exactly ${expectedBytes} bytes`);
|
|
231
|
-
}
|
|
232
|
-
return decoded;
|
|
233
|
-
}
|
|
234
|
-
function getEncryptedFileKey() {
|
|
235
|
-
const encoded = process.env[OAUTH_FILE_KEY_ENV];
|
|
236
|
-
if (!encoded)
|
|
237
|
-
throw new Error(`${OAUTH_FILE_KEY_ENV} is required for the encrypted OAuth credential file store`);
|
|
238
|
-
try {
|
|
239
|
-
return decodeCanonicalBase64(encoded, 32);
|
|
240
|
-
} catch (error) {
|
|
241
|
-
throw new Error(`${OAUTH_FILE_KEY_ENV} must be canonical base64 for exactly 32 random bytes`, { cause: error });
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
function encryptedEntryPath(root, account) {
|
|
245
|
-
return join(root, account, "credentials.json");
|
|
246
|
-
}
|
|
247
|
-
function validatePrivateRegularFile(path) {
|
|
248
|
-
let stat;
|
|
249
|
-
try {
|
|
250
|
-
stat = lstatSync(path);
|
|
251
|
-
} catch (error) {
|
|
252
|
-
if (error.code === "ENOENT")
|
|
253
|
-
return false;
|
|
254
|
-
throw error;
|
|
255
|
-
}
|
|
256
|
-
if (!stat.isFile() || stat.isSymbolicLink())
|
|
257
|
-
throw new Error(`Refusing non-regular OAuth credential file at ${path}`);
|
|
258
|
-
if (process.platform !== "win32" && (stat.mode & 63) !== 0) {
|
|
259
|
-
throw new Error(`OAuth credential file has group or other permissions at ${path}`);
|
|
260
|
-
}
|
|
261
|
-
return true;
|
|
262
|
-
}
|
|
263
|
-
function ensurePrivateDirectory(path) {
|
|
264
|
-
mkdirSync(path, { recursive: true, mode: 448 });
|
|
265
|
-
const stat = lstatSync(path);
|
|
266
|
-
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
267
|
-
throw new Error(`Refusing non-directory OAuth credential path at ${path}`);
|
|
268
|
-
if (process.platform !== "win32")
|
|
269
|
-
chmodSync(path, 448);
|
|
270
|
-
}
|
|
271
|
-
function createEncryptedFileAuthSecretStore() {
|
|
272
|
-
const root = getAgentPath("mcp-oauth-encrypted");
|
|
273
|
-
return {
|
|
274
|
-
kind: "encrypted-file",
|
|
275
|
-
read(account) {
|
|
276
|
-
const key = getEncryptedFileKey();
|
|
277
|
-
const path = encryptedEntryPath(root, account);
|
|
278
|
-
if (!validatePrivateRegularFile(path))
|
|
279
|
-
return;
|
|
280
|
-
const envelope = parseJsonPayload(account, readFileSync(path, "utf8"), path);
|
|
281
|
-
if (!envelope || envelope.version !== 1 || envelope.algorithm !== "aes-256-gcm") {
|
|
282
|
-
throw new Error(`Unsupported encrypted OAuth credential envelope at ${path}`);
|
|
283
|
-
}
|
|
284
|
-
const iv = decodeCanonicalBase64(envelope.iv, 12);
|
|
285
|
-
const ciphertext = decodeCanonicalBase64(envelope.ciphertext);
|
|
286
|
-
const tag = decodeCanonicalBase64(envelope.tag, 16);
|
|
287
|
-
const decipher = createDecipheriv("aes-256-gcm", key, iv);
|
|
288
|
-
decipher.setAAD(Buffer.from(`${ENCRYPTED_FILE_AAD_CONTEXT}\x00${account}`, "utf8"));
|
|
289
|
-
decipher.setAuthTag(tag);
|
|
290
|
-
return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
291
|
-
},
|
|
292
|
-
write(account, payload) {
|
|
293
|
-
const key = getEncryptedFileKey();
|
|
294
|
-
const iv = randomBytes(12);
|
|
295
|
-
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
296
|
-
cipher.setAAD(Buffer.from(`${ENCRYPTED_FILE_AAD_CONTEXT}\x00${account}`, "utf8"));
|
|
297
|
-
const ciphertext = Buffer.concat([cipher.update(payload, "utf8"), cipher.final()]);
|
|
298
|
-
const envelope = JSON.stringify({
|
|
299
|
-
version: 1,
|
|
300
|
-
algorithm: "aes-256-gcm",
|
|
301
|
-
iv: iv.toString("base64"),
|
|
302
|
-
ciphertext: ciphertext.toString("base64"),
|
|
303
|
-
tag: cipher.getAuthTag().toString("base64")
|
|
304
|
-
});
|
|
305
|
-
const dir = join(root, account);
|
|
306
|
-
ensurePrivateDirectory(root);
|
|
307
|
-
ensurePrivateDirectory(dir);
|
|
308
|
-
const destination = encryptedEntryPath(root, account);
|
|
309
|
-
validatePrivateRegularFile(destination);
|
|
310
|
-
const temporary = join(dir, `.credentials-${randomBytes(12).toString("hex")}.tmp`);
|
|
311
|
-
let fd;
|
|
312
|
-
try {
|
|
313
|
-
fd = openSync(temporary, "wx", 384);
|
|
314
|
-
writeFileSync(fd, envelope, "utf8");
|
|
315
|
-
fsyncSync(fd);
|
|
316
|
-
closeSync(fd);
|
|
317
|
-
fd = undefined;
|
|
318
|
-
renameSync(temporary, destination);
|
|
319
|
-
} catch (error) {
|
|
320
|
-
if (fd !== undefined) {
|
|
321
|
-
try {
|
|
322
|
-
closeSync(fd);
|
|
323
|
-
} catch {}
|
|
324
|
-
}
|
|
325
|
-
try {
|
|
326
|
-
rmSync(temporary, { force: true });
|
|
327
|
-
} catch {}
|
|
328
|
-
throw error;
|
|
329
|
-
}
|
|
330
|
-
},
|
|
331
|
-
remove(account) {
|
|
332
|
-
getEncryptedFileKey();
|
|
333
|
-
const path = encryptedEntryPath(root, account);
|
|
334
|
-
if (!validatePrivateRegularFile(path))
|
|
335
|
-
return;
|
|
336
|
-
rmSync(path);
|
|
337
|
-
try {
|
|
338
|
-
rmSync(dirname(path));
|
|
339
|
-
} catch {}
|
|
340
|
-
}
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
function getAuthSecretStore(options = {}) {
|
|
344
|
-
if (options.credentialStore === "encrypted-file")
|
|
345
|
-
return createEncryptedFileAuthSecretStore();
|
|
346
|
-
if (process.env[TEST_AUTH_STORE_ENV] === "memory")
|
|
347
|
-
return memoryAuthSecretStore;
|
|
348
|
-
if (process.env[TEST_AUTH_STORE_ENV] === "sizelimited")
|
|
349
|
-
return sizeLimitedAuthSecretStore;
|
|
350
|
-
if (process.env[TEST_AUTH_STORE_ENV] === "writefailing")
|
|
351
|
-
return writeFailingAuthSecretStore;
|
|
352
|
-
if (process.env[TEST_AUTH_STORE_ENV] === "unavailable")
|
|
353
|
-
return unavailableAuthSecretStore;
|
|
354
|
-
if (process.env[TEST_AUTH_STORE_ENV] === "keyrevoked")
|
|
355
|
-
return keyRevokedAuthSecretStore;
|
|
356
|
-
return keyringAuthSecretStore;
|
|
357
|
-
}
|
|
358
|
-
function getKeyringEntry(account) {
|
|
359
|
-
try {
|
|
360
|
-
KeyringEntryClass ??= loadKeyringEntryClass();
|
|
361
|
-
return new KeyringEntryClass(AUTH_SECRET_SERVICE, account);
|
|
362
|
-
} catch (error) {
|
|
363
|
-
throw new Error("OAuth secure credential storage is unavailable. Configure the OS credential store and retry authentication.", { cause: error });
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
function loadKeyringEntryClass(keyringRequire = require, platform = process.platform, arch = process.arch) {
|
|
367
|
-
try {
|
|
368
|
-
return keyringRequire("@napi-rs/keyring").Entry;
|
|
369
|
-
} catch (loaderError) {
|
|
370
|
-
try {
|
|
371
|
-
return loadKeyringNativeBindingFallback(keyringRequire, platform, arch).Entry;
|
|
372
|
-
} catch (fallbackError) {
|
|
373
|
-
throw new Error(`Failed to load @napi-rs/keyring; absolute-path native binding fallback also failed: ${formatErrorMessage(fallbackError)}`, {
|
|
374
|
-
cause: loaderError
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
function loadKeyringNativeBindingFallback(keyringRequire, platform, arch) {
|
|
380
|
-
const targets = getKeyringNativeBindingTargets(platform, arch);
|
|
381
|
-
if (targets.length === 0) {
|
|
382
|
-
throw new Error(`Unsupported @napi-rs/keyring native binding target: ${platform}-${arch}`);
|
|
383
|
-
}
|
|
384
|
-
let lastError;
|
|
385
|
-
for (const target of targets) {
|
|
386
|
-
try {
|
|
387
|
-
const packageJsonPath = keyringRequire.resolve(`${target.packageName}/package.json`);
|
|
388
|
-
return keyringRequire(join(dirname(packageJsonPath), target.bindingFile));
|
|
389
|
-
} catch (error) {
|
|
390
|
-
lastError = error;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
394
|
-
}
|
|
395
|
-
function getKeyringNativeBindingTargets(platform, arch) {
|
|
396
|
-
return getKeyringNativeBindingSuffixes(platform, arch).map((suffix) => ({
|
|
397
|
-
packageName: `@napi-rs/keyring-${suffix}`,
|
|
398
|
-
bindingFile: `keyring.${suffix}.node`
|
|
399
|
-
}));
|
|
400
|
-
}
|
|
401
|
-
function getKeyringNativeBindingSuffixes(platform, arch) {
|
|
402
|
-
if (platform === "darwin") {
|
|
403
|
-
if (arch === "arm64")
|
|
404
|
-
return ["darwin-arm64"];
|
|
405
|
-
if (arch === "x64")
|
|
406
|
-
return ["darwin-x64"];
|
|
407
|
-
}
|
|
408
|
-
if (platform === "win32") {
|
|
409
|
-
if (arch === "arm64")
|
|
410
|
-
return ["win32-arm64-msvc"];
|
|
411
|
-
if (arch === "x64")
|
|
412
|
-
return ["win32-x64-msvc"];
|
|
413
|
-
if (arch === "ia32")
|
|
414
|
-
return ["win32-ia32-msvc"];
|
|
415
|
-
}
|
|
416
|
-
if (platform === "linux") {
|
|
417
|
-
if (arch === "arm64")
|
|
418
|
-
return ["linux-arm64-gnu", "linux-arm64-musl"];
|
|
419
|
-
if (arch === "arm")
|
|
420
|
-
return ["linux-arm-gnueabihf"];
|
|
421
|
-
if (arch === "riscv64")
|
|
422
|
-
return ["linux-riscv64-gnu"];
|
|
423
|
-
if (arch === "x64")
|
|
424
|
-
return ["linux-x64-gnu", "linux-x64-musl"];
|
|
425
|
-
}
|
|
426
|
-
if (platform === "freebsd" && arch === "x64")
|
|
427
|
-
return ["freebsd-x64"];
|
|
428
|
-
return [];
|
|
429
|
-
}
|
|
430
|
-
function formatErrorMessage(error) {
|
|
431
|
-
return error instanceof Error ? error.message : String(error);
|
|
432
|
-
}
|
|
433
|
-
function isLinuxKeyringRecoveryEnabled() {
|
|
434
|
-
if (process.env[KEYRING_RECOVERY_DISABLED_ENV] === "1")
|
|
435
|
-
return false;
|
|
436
|
-
return process.platform === "linux" || process.env[TEST_LINUX_KEYRING_RECOVERY_ENV] === "1";
|
|
437
|
-
}
|
|
438
|
-
function shouldAttemptLinuxKeyringRecovery(error) {
|
|
439
|
-
return isLinuxKeyringRecoveryEnabled() && causeChainContains(error, /key\s*(?:has been\s*)?revoked|keyrevoked/i);
|
|
440
|
-
}
|
|
441
|
-
function runLinuxKeyringRecoveryOperation(operation, account, payload) {
|
|
442
|
-
const keyctl = process.env[KEYRING_RECOVERY_KEYCTL_ENV]?.trim() || "keyctl";
|
|
443
|
-
const node = process.env[KEYRING_RECOVERY_NODE_ENV]?.trim() || "node";
|
|
444
|
-
const helper = process.env[KEYRING_RECOVERY_HELPER_ENV]?.trim() || fileURLToPath(new URL("./mcp-keyring-helper.cjs", import.meta.url));
|
|
445
|
-
const request = JSON.stringify({ operation, service: AUTH_SECRET_SERVICE, account, payload });
|
|
446
|
-
const result = spawnSync(keyctl, ["session", "-", node, helper], {
|
|
447
|
-
input: `${request}
|
|
448
|
-
`,
|
|
449
|
-
encoding: "utf8",
|
|
450
|
-
maxBuffer: 1024 * 1024,
|
|
451
|
-
timeout: KEYRING_RECOVERY_TIMEOUT_MS,
|
|
452
|
-
windowsHide: true
|
|
453
|
-
});
|
|
454
|
-
if (result.error) {
|
|
455
|
-
throw new Error(`Linux keyring recovery helper could not start: ${result.error.message}`, { cause: result.error });
|
|
456
|
-
}
|
|
457
|
-
if (result.status !== 0) {
|
|
458
|
-
throw new Error(`Linux keyring recovery helper failed with exit code ${result.status ?? "unknown"}`);
|
|
459
|
-
}
|
|
460
|
-
let response;
|
|
461
|
-
try {
|
|
462
|
-
response = JSON.parse(result.stdout.trim());
|
|
463
|
-
} catch (error) {
|
|
464
|
-
throw new Error("Linux keyring recovery helper returned invalid JSON", { cause: error });
|
|
465
|
-
}
|
|
466
|
-
if (typeof response !== "object" || response === null || typeof response.ok !== "boolean") {
|
|
467
|
-
throw new Error("Linux keyring recovery helper returned an invalid response");
|
|
468
|
-
}
|
|
469
|
-
const typedResponse = response;
|
|
470
|
-
if (typedResponse.ok === false) {
|
|
471
|
-
throw new Error(typedResponse.error || "Linux keyring recovery helper failed");
|
|
472
|
-
}
|
|
473
|
-
if (operation === "read" && typedResponse.found === true && typeof typedResponse.value !== "string") {
|
|
474
|
-
throw new Error("Linux keyring recovery helper returned an invalid read response");
|
|
475
|
-
}
|
|
476
|
-
return typedResponse;
|
|
477
|
-
}
|
|
478
|
-
const linuxKeyringRecoveryAuthSecretStore = {
|
|
479
|
-
read(account) {
|
|
480
|
-
const response = runLinuxKeyringRecoveryOperation("read", account);
|
|
481
|
-
return response.ok && response.found === true ? response.value : undefined;
|
|
482
|
-
},
|
|
483
|
-
write(account, payload) {
|
|
484
|
-
runLinuxKeyringRecoveryOperation("write", account, payload);
|
|
485
|
-
},
|
|
486
|
-
remove(account) {
|
|
487
|
-
runLinuxKeyringRecoveryOperation("remove", account);
|
|
488
|
-
}
|
|
489
|
-
};
|
|
490
|
-
export function loadTestKeyringEntryClass(keyringRequire, platform, arch) {
|
|
491
|
-
return loadKeyringEntryClass(keyringRequire, platform, arch);
|
|
492
|
-
}
|
|
493
|
-
export function getAuthStorageOptions(oauthDir, cwd = process.cwd(), oauthCredentialStore) {
|
|
494
|
-
if (oauthCredentialStore !== undefined && oauthCredentialStore !== "encrypted-file") {
|
|
495
|
-
throw new Error('settings.oauthCredentialStore must be "encrypted-file" when set');
|
|
496
|
-
}
|
|
497
|
-
if (oauthCredentialStore === "encrypted-file")
|
|
498
|
-
return { credentialStore: "encrypted-file" };
|
|
499
|
-
const baseDir = resolveConfiguredOAuthDir(oauthDir, cwd);
|
|
500
|
-
return baseDir ? { baseDir } : {};
|
|
501
|
-
}
|
|
502
|
-
export function getAuthBaseDir(options = {}) {
|
|
503
|
-
const override = process.env.MCP_OAUTH_DIR?.trim();
|
|
504
|
-
if (override)
|
|
505
|
-
return override;
|
|
506
|
-
return options.baseDir ?? getAgentPath("mcp-oauth");
|
|
507
|
-
}
|
|
508
|
-
function getServerDir(serverName, options) {
|
|
509
|
-
if (typeof serverName !== "string") {
|
|
510
|
-
throw new Error(`Invalid MCP server name: ${JSON.stringify(serverName)}`);
|
|
511
|
-
}
|
|
512
|
-
const storageKey = getAuthEntryAccount(serverName);
|
|
513
|
-
return join(getAuthBaseDir(options), storageKey);
|
|
514
|
-
}
|
|
515
|
-
function getAuthEntryAccount(serverName) {
|
|
516
|
-
if (typeof serverName !== "string") {
|
|
517
|
-
throw new Error(`Invalid MCP server name: ${JSON.stringify(serverName)}`);
|
|
518
|
-
}
|
|
519
|
-
return `sha256-${createHash("sha256").update(serverName, "utf8").digest("hex")}`;
|
|
520
|
-
}
|
|
521
|
-
export function getAuthEntryFilePath(serverName, options) {
|
|
522
|
-
return join(getServerDir(serverName, options), "tokens.json");
|
|
523
|
-
}
|
|
524
|
-
function parseJsonPayload(serverName, payload, source) {
|
|
525
|
-
try {
|
|
526
|
-
return JSON.parse(payload);
|
|
527
|
-
} catch (error) {
|
|
528
|
-
throw new Error(`Failed to parse OAuth credentials for ${serverName} from ${source}`, { cause: error });
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
function parseAuthEntryPayload(serverName, payload, source) {
|
|
532
|
-
const parsed = parseJsonPayload(serverName, payload, source);
|
|
533
|
-
const entry = toAuthEntry(parsed);
|
|
534
|
-
if (!entry) {
|
|
535
|
-
throw new Error(`Failed to parse OAuth credentials for ${serverName} from ${source}: invalid credential shape`);
|
|
536
|
-
}
|
|
537
|
-
return entry;
|
|
538
|
-
}
|
|
539
|
-
function toAuthEntry(value) {
|
|
540
|
-
const entry = toRecord(value);
|
|
541
|
-
if (!entry)
|
|
542
|
-
return;
|
|
543
|
-
const codeVerifier = optionalString(entry.codeVerifier);
|
|
544
|
-
const oauthState = optionalString(entry.oauthState);
|
|
545
|
-
const serverUrl = optionalString(entry.serverUrl);
|
|
546
|
-
if (codeVerifier === null || oauthState === null || serverUrl === null)
|
|
547
|
-
return;
|
|
548
|
-
const tokens = entry.tokens === undefined ? undefined : toStoredTokens(entry.tokens);
|
|
549
|
-
const clientInfo = entry.clientInfo === undefined ? undefined : toStoredClientInfo(entry.clientInfo);
|
|
550
|
-
if (entry.tokens !== undefined && !tokens || entry.clientInfo !== undefined && !clientInfo)
|
|
551
|
-
return;
|
|
552
|
-
const authEntry = {};
|
|
553
|
-
if (tokens)
|
|
554
|
-
authEntry.tokens = tokens;
|
|
555
|
-
if (clientInfo)
|
|
556
|
-
authEntry.clientInfo = clientInfo;
|
|
557
|
-
if (codeVerifier !== undefined)
|
|
558
|
-
authEntry.codeVerifier = codeVerifier;
|
|
559
|
-
if (oauthState !== undefined)
|
|
560
|
-
authEntry.oauthState = oauthState;
|
|
561
|
-
if (serverUrl !== undefined)
|
|
562
|
-
authEntry.serverUrl = serverUrl;
|
|
563
|
-
return authEntry;
|
|
564
|
-
}
|
|
565
|
-
function toStoredTokens(value) {
|
|
566
|
-
const tokens = toRecord(value);
|
|
567
|
-
if (!tokens || typeof tokens.accessToken !== "string")
|
|
568
|
-
return;
|
|
569
|
-
const refreshToken = optionalString(tokens.refreshToken);
|
|
570
|
-
const scope = optionalString(tokens.scope);
|
|
571
|
-
const issuer = optionalString(tokens.issuer);
|
|
572
|
-
const expiresAt = optionalNumber(tokens.expiresAt);
|
|
573
|
-
if (refreshToken === null || scope === null || issuer === null || expiresAt === null)
|
|
574
|
-
return;
|
|
575
|
-
const storedTokens = { accessToken: tokens.accessToken };
|
|
576
|
-
if (refreshToken !== undefined)
|
|
577
|
-
storedTokens.refreshToken = refreshToken;
|
|
578
|
-
if (expiresAt !== undefined)
|
|
579
|
-
storedTokens.expiresAt = expiresAt;
|
|
580
|
-
if (scope !== undefined)
|
|
581
|
-
storedTokens.scope = scope;
|
|
582
|
-
if (issuer !== undefined)
|
|
583
|
-
storedTokens.issuer = issuer;
|
|
584
|
-
return storedTokens;
|
|
585
|
-
}
|
|
586
|
-
function toStoredClientInfo(value) {
|
|
587
|
-
const clientInfo = toRecord(value);
|
|
588
|
-
if (!clientInfo || typeof clientInfo.clientId !== "string")
|
|
589
|
-
return;
|
|
590
|
-
const clientSecret = optionalString(clientInfo.clientSecret);
|
|
591
|
-
const issuer = optionalString(clientInfo.issuer);
|
|
592
|
-
const clientIdIssuedAt = optionalNumber(clientInfo.clientIdIssuedAt);
|
|
593
|
-
const clientSecretExpiresAt = optionalNumber(clientInfo.clientSecretExpiresAt);
|
|
594
|
-
const configPreRegistered = optionalBoolean(clientInfo.configPreRegistered);
|
|
595
|
-
if (clientSecret === null || issuer === null || clientIdIssuedAt === null || clientSecretExpiresAt === null || configPreRegistered === null)
|
|
596
|
-
return;
|
|
597
|
-
const storedClient = { clientId: clientInfo.clientId };
|
|
598
|
-
const redirectUris = stringArray(clientInfo.redirectUris);
|
|
599
|
-
if (clientSecret !== undefined)
|
|
600
|
-
storedClient.clientSecret = clientSecret;
|
|
601
|
-
if (clientIdIssuedAt !== undefined)
|
|
602
|
-
storedClient.clientIdIssuedAt = clientIdIssuedAt;
|
|
603
|
-
if (clientSecretExpiresAt !== undefined)
|
|
604
|
-
storedClient.clientSecretExpiresAt = clientSecretExpiresAt;
|
|
605
|
-
if (redirectUris !== undefined)
|
|
606
|
-
storedClient.redirectUris = redirectUris;
|
|
607
|
-
if (issuer !== undefined)
|
|
608
|
-
storedClient.issuer = issuer;
|
|
609
|
-
if (configPreRegistered !== undefined)
|
|
610
|
-
storedClient.configPreRegistered = configPreRegistered;
|
|
611
|
-
return storedClient;
|
|
612
|
-
}
|
|
613
|
-
function toRecord(value) {
|
|
614
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
|
|
615
|
-
}
|
|
616
|
-
function optionalString(value) {
|
|
617
|
-
if (value === undefined)
|
|
618
|
-
return;
|
|
619
|
-
return typeof value === "string" ? value : null;
|
|
620
|
-
}
|
|
621
|
-
function optionalNumber(value) {
|
|
622
|
-
if (value === undefined)
|
|
623
|
-
return;
|
|
624
|
-
return typeof value === "number" ? value : null;
|
|
625
|
-
}
|
|
626
|
-
function optionalBoolean(value) {
|
|
627
|
-
if (value === undefined)
|
|
628
|
-
return;
|
|
629
|
-
return typeof value === "boolean" ? value : null;
|
|
630
|
-
}
|
|
631
|
-
function stringArray(value) {
|
|
632
|
-
return Array.isArray(value) && value.every((uri) => typeof uri === "string") ? value : undefined;
|
|
633
|
-
}
|
|
634
|
-
function isAuthEntryChunkManifest(value) {
|
|
635
|
-
if (typeof value !== "object" || value === null)
|
|
636
|
-
return false;
|
|
637
|
-
const manifest = value;
|
|
638
|
-
return manifest[AUTH_CHUNK_MANIFEST_KEY] === 1 && typeof manifest.chunkCount === "number" && Number.isInteger(manifest.chunkCount) && manifest.chunkCount > 0 && typeof manifest.chunkDigest === "string" && /^[a-f0-9]{16}$/.test(manifest.chunkDigest);
|
|
639
|
-
}
|
|
640
|
-
function getAuthEntryChunkAccount(account, manifest, index) {
|
|
641
|
-
return `${account}.chunk.${manifest.chunkDigest}.${index}`;
|
|
642
|
-
}
|
|
643
|
-
function getAuthEntryChunkAccounts(account, manifest) {
|
|
644
|
-
return Array.from({ length: manifest.chunkCount }, (_, index) => getAuthEntryChunkAccount(account, manifest, index));
|
|
645
|
-
}
|
|
646
|
-
function readChunkManifestFromPayload(serverName, payload, source) {
|
|
647
|
-
const parsed = parseJsonPayload(serverName, payload, source);
|
|
648
|
-
return isAuthEntryChunkManifest(parsed) ? parsed : undefined;
|
|
649
|
-
}
|
|
650
|
-
function readExistingChunkManifest(store, serverName, account) {
|
|
651
|
-
try {
|
|
652
|
-
const payload = store.read(account);
|
|
653
|
-
return payload === undefined ? undefined : readChunkManifestFromPayload(serverName, payload, authSecretStoreLabel(store));
|
|
654
|
-
} catch {
|
|
655
|
-
return;
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
function removeChunkPayloads(store, account, manifest) {
|
|
659
|
-
for (const chunkAccount of getAuthEntryChunkAccounts(account, manifest)) {
|
|
660
|
-
store.remove(chunkAccount);
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
function tryRemoveChunkPayloads(store, account, manifest) {
|
|
664
|
-
if (!manifest)
|
|
665
|
-
return;
|
|
666
|
-
try {
|
|
667
|
-
removeChunkPayloads(store, account, manifest);
|
|
668
|
-
} catch {}
|
|
669
|
-
}
|
|
670
|
-
function shouldChunkAuthPayload(store, payload) {
|
|
671
|
-
return store.kind !== "encrypted-file" && payload.length > AUTH_SECRET_CHUNK_SIZE && (process.platform === "win32" || process.env[TEST_AUTH_STORE_ENV] === "sizelimited");
|
|
672
|
-
}
|
|
673
|
-
function getAuthEntryChunkDigest(payload) {
|
|
674
|
-
return createHash("sha256").update(payload, "utf8").digest("hex").slice(0, 16);
|
|
675
|
-
}
|
|
676
|
-
function splitAuthPayload(payload) {
|
|
677
|
-
const chunks = [];
|
|
678
|
-
for (let start = 0;start < payload.length; ) {
|
|
679
|
-
let end = Math.min(start + AUTH_SECRET_CHUNK_SIZE, payload.length);
|
|
680
|
-
const lastCodeUnit = payload.charCodeAt(end - 1);
|
|
681
|
-
if (end < payload.length && lastCodeUnit >= 55296 && lastCodeUnit <= 56319)
|
|
682
|
-
end--;
|
|
683
|
-
chunks.push(payload.slice(start, end));
|
|
684
|
-
start = end;
|
|
685
|
-
}
|
|
686
|
-
return chunks;
|
|
687
|
-
}
|
|
688
|
-
function createChunkManifest(payload, chunkCount) {
|
|
689
|
-
return {
|
|
690
|
-
[AUTH_CHUNK_MANIFEST_KEY]: 1,
|
|
691
|
-
chunkCount,
|
|
692
|
-
chunkDigest: getAuthEntryChunkDigest(payload)
|
|
693
|
-
};
|
|
694
|
-
}
|
|
695
|
-
function readChunkedAuthEntry(store, serverName, account, manifest) {
|
|
696
|
-
let payload;
|
|
697
|
-
try {
|
|
698
|
-
payload = getAuthEntryChunkAccounts(account, manifest).map((chunkAccount) => {
|
|
699
|
-
const chunk = store.read(chunkAccount);
|
|
700
|
-
if (chunk === undefined) {
|
|
701
|
-
throw new Error(`Missing OAuth credential chunk ${chunkAccount} for ${serverName}`);
|
|
702
|
-
}
|
|
703
|
-
return chunk;
|
|
704
|
-
}).join("");
|
|
705
|
-
if (getAuthEntryChunkDigest(payload) !== manifest.chunkDigest) {
|
|
706
|
-
throw new Error("OAuth credential chunk integrity check failed");
|
|
707
|
-
}
|
|
708
|
-
} catch (error) {
|
|
709
|
-
throw new OAuthCredentialStoreError(`Failed to read OAuth credentials for ${serverName} from the ${authSecretStoreLabel(store)}`, "read", error);
|
|
710
|
-
}
|
|
711
|
-
return parseAuthEntryPayload(serverName, payload, `${authSecretStoreLabel(store)} chunks`);
|
|
712
|
-
}
|
|
713
|
-
function readLegacyAuthEntry(serverName, options) {
|
|
714
|
-
const filePath = getAuthEntryFilePath(serverName, options);
|
|
715
|
-
if (!existsSync(filePath))
|
|
716
|
-
return;
|
|
717
|
-
const data = readFileSync(filePath, "utf-8");
|
|
718
|
-
return parseAuthEntryPayload(serverName, data, filePath);
|
|
719
|
-
}
|
|
720
|
-
function removeLegacyAuthEntry(serverName, options) {
|
|
721
|
-
const filePath = getAuthEntryFilePath(serverName, options);
|
|
722
|
-
if (!existsSync(filePath))
|
|
723
|
-
return;
|
|
724
|
-
try {
|
|
725
|
-
rmSync(filePath, { force: true });
|
|
726
|
-
} catch (error) {
|
|
727
|
-
throw new Error(`Failed to remove legacy plaintext OAuth credentials for ${serverName} at ${filePath}`, { cause: error });
|
|
728
|
-
}
|
|
729
|
-
const dir = getServerDir(serverName, options);
|
|
730
|
-
try {
|
|
731
|
-
rmSync(dir, { recursive: true });
|
|
732
|
-
} catch {}
|
|
733
|
-
}
|
|
734
|
-
function writeSecureAuthEntryToStore(store, serverName, entry) {
|
|
735
|
-
const account = getAuthEntryAccount(serverName);
|
|
736
|
-
const payload = JSON.stringify(entry);
|
|
737
|
-
const previousManifest = readExistingChunkManifest(store, serverName, account);
|
|
738
|
-
const chunks = shouldChunkAuthPayload(store, payload) ? splitAuthPayload(payload) : undefined;
|
|
739
|
-
const manifest = chunks ? createChunkManifest(payload, chunks.length) : undefined;
|
|
740
|
-
try {
|
|
741
|
-
if (manifest && chunks) {
|
|
742
|
-
for (const [index, chunk] of chunks.entries()) {
|
|
743
|
-
store.write(getAuthEntryChunkAccount(account, manifest, index), chunk);
|
|
744
|
-
}
|
|
745
|
-
store.write(account, JSON.stringify(manifest));
|
|
746
|
-
} else {
|
|
747
|
-
store.write(account, payload);
|
|
748
|
-
}
|
|
749
|
-
if (previousManifest?.chunkDigest !== manifest?.chunkDigest) {
|
|
750
|
-
tryRemoveChunkPayloads(store, account, previousManifest);
|
|
751
|
-
}
|
|
752
|
-
} catch (error) {
|
|
753
|
-
tryRemoveChunkPayloads(store, account, manifest);
|
|
754
|
-
throw new OAuthCredentialStoreError(`Failed to write OAuth credentials for ${serverName} to the ${authSecretStoreLabel(store)}`, "write", error, store.kind);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
function authEntryCacheKey(serverName, options = {}, operation = "read") {
|
|
758
|
-
if (options.credentialStore !== "encrypted-file")
|
|
759
|
-
return `os\x00${serverName}`;
|
|
760
|
-
try {
|
|
761
|
-
const generation = createHash("sha256").update(getEncryptedFileKey()).digest("hex");
|
|
762
|
-
return `encrypted-file:${generation}\x00${serverName}`;
|
|
763
|
-
} catch (error) {
|
|
764
|
-
throw new OAuthCredentialStoreError(`Failed to ${operation} OAuth credentials for ${serverName} with the encrypted OAuth credential file store`, operation, error, "encrypted-file");
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
function publishAuthEntryToCache(serverName, payload, options) {
|
|
768
|
-
if (!isAuthEntryCacheEnabled())
|
|
769
|
-
return;
|
|
770
|
-
const cacheKey = authEntryCacheKey(serverName, options, "write");
|
|
771
|
-
const normalized = toAuthEntry(JSON.parse(payload));
|
|
772
|
-
if (!normalized) {
|
|
773
|
-
authEntryCache.delete(cacheKey);
|
|
774
|
-
return;
|
|
775
|
-
}
|
|
776
|
-
authEntryCache.set(cacheKey, cloneAuthEntry(normalized));
|
|
777
|
-
}
|
|
778
|
-
function writeSecureAuthEntry(serverName, entry, options) {
|
|
779
|
-
try {
|
|
780
|
-
writeSecureAuthEntryToStore(getAuthSecretStore(options), serverName, entry);
|
|
781
|
-
} catch (error) {
|
|
782
|
-
if (options?.credentialStore === "encrypted-file" || !shouldAttemptLinuxKeyringRecovery(error))
|
|
783
|
-
throw error;
|
|
784
|
-
writeSecureAuthEntryToStore(linuxKeyringRecoveryAuthSecretStore, serverName, entry);
|
|
785
|
-
}
|
|
786
|
-
publishAuthEntryToCache(serverName, JSON.stringify(entry), options);
|
|
787
|
-
}
|
|
788
|
-
function readAuthEntryFromStore(store, serverName, options, behavior = {}) {
|
|
789
|
-
const account = getAuthEntryAccount(serverName);
|
|
790
|
-
let payload;
|
|
791
|
-
try {
|
|
792
|
-
payload = store.read(account);
|
|
793
|
-
} catch (error) {
|
|
794
|
-
throw new OAuthCredentialStoreError(`Failed to read OAuth credentials for ${serverName} from the ${authSecretStoreLabel(store)}`, "read", error, store.kind);
|
|
795
|
-
}
|
|
796
|
-
if (payload !== undefined) {
|
|
797
|
-
const manifest = store.kind === "encrypted-file" ? undefined : readChunkManifestFromPayload(serverName, payload, authSecretStoreLabel(store));
|
|
798
|
-
const entry = manifest ? readChunkedAuthEntry(store, serverName, account, manifest) : parseAuthEntryPayload(serverName, payload, authSecretStoreLabel(store));
|
|
799
|
-
if (store.kind !== "encrypted-file")
|
|
800
|
-
removeLegacyAuthEntry(serverName, options);
|
|
801
|
-
if (manifest && behavior.migrateLegacy !== false && !shouldChunkAuthPayload(store, JSON.stringify(entry))) {
|
|
802
|
-
writeSecureAuthEntryToStore(store, serverName, entry);
|
|
803
|
-
}
|
|
804
|
-
return entry;
|
|
805
|
-
}
|
|
806
|
-
if (store.kind === "encrypted-file")
|
|
807
|
-
return;
|
|
808
|
-
const legacyEntry = readLegacyAuthEntry(serverName, options);
|
|
809
|
-
if (!legacyEntry)
|
|
810
|
-
return;
|
|
811
|
-
if (behavior.migrateLegacy === false)
|
|
812
|
-
return legacyEntry;
|
|
813
|
-
writeSecureAuthEntryToStore(store, serverName, legacyEntry);
|
|
814
|
-
removeLegacyAuthEntry(serverName, options);
|
|
815
|
-
return legacyEntry;
|
|
816
|
-
}
|
|
817
|
-
function readAuthEntry(serverName, options, behavior = {}) {
|
|
818
|
-
const cacheable = behavior.migrateLegacy !== false && isAuthEntryCacheEnabled();
|
|
819
|
-
const cacheKey = authEntryCacheKey(serverName, options);
|
|
820
|
-
if (cacheable && authEntryCache.has(cacheKey)) {
|
|
821
|
-
return cloneAuthEntry(authEntryCache.get(cacheKey));
|
|
822
|
-
}
|
|
823
|
-
let entry;
|
|
824
|
-
try {
|
|
825
|
-
entry = readAuthEntryFromStore(getAuthSecretStore(options), serverName, options, behavior);
|
|
826
|
-
} catch (error) {
|
|
827
|
-
if (options?.credentialStore === "encrypted-file" || !shouldAttemptLinuxKeyringRecovery(error))
|
|
828
|
-
throw error;
|
|
829
|
-
entry = readAuthEntryFromStore(linuxKeyringRecoveryAuthSecretStore, serverName, options, behavior);
|
|
830
|
-
}
|
|
831
|
-
if (cacheable)
|
|
832
|
-
authEntryCache.set(cacheKey, cloneAuthEntry(entry));
|
|
833
|
-
return entry;
|
|
834
|
-
}
|
|
835
|
-
export function getAuthEntry(serverName, options) {
|
|
836
|
-
return readAuthEntry(serverName, options);
|
|
837
|
-
}
|
|
838
|
-
export function getAuthForUrl(serverName, serverUrl, options) {
|
|
839
|
-
const entry = getAuthEntry(serverName, options);
|
|
840
|
-
if (!entry)
|
|
841
|
-
return;
|
|
842
|
-
if (!entry.serverUrl)
|
|
843
|
-
return;
|
|
844
|
-
if (entry.serverUrl !== serverUrl)
|
|
845
|
-
return;
|
|
846
|
-
return entry;
|
|
847
|
-
}
|
|
848
|
-
export function inspectAuthForUrl(serverName, serverUrl, options) {
|
|
849
|
-
try {
|
|
850
|
-
const entry = readAuthEntry(serverName, options, { migrateLegacy: false });
|
|
851
|
-
if (!entry?.serverUrl || entry.serverUrl !== serverUrl)
|
|
852
|
-
return { status: "absent" };
|
|
853
|
-
return { status: "present", entry };
|
|
854
|
-
} catch (error) {
|
|
855
|
-
if (!(error instanceof OAuthCredentialStoreError))
|
|
856
|
-
throw error;
|
|
857
|
-
return { status: "unavailable", message: formatOAuthCredentialStoreUnavailable(error) };
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
export function saveAuthEntry(serverName, entry, serverUrl, options) {
|
|
861
|
-
if (serverUrl) {
|
|
862
|
-
entry.serverUrl = serverUrl;
|
|
863
|
-
}
|
|
864
|
-
writeSecureAuthEntry(serverName, entry, options);
|
|
865
|
-
if (options?.credentialStore !== "encrypted-file")
|
|
866
|
-
removeLegacyAuthEntry(serverName, options);
|
|
867
|
-
}
|
|
868
|
-
function removeAuthEntryFromStore(store, serverName) {
|
|
869
|
-
const account = getAuthEntryAccount(serverName);
|
|
870
|
-
try {
|
|
871
|
-
if (store.kind === "encrypted-file") {
|
|
872
|
-
store.remove(account);
|
|
873
|
-
return;
|
|
874
|
-
}
|
|
875
|
-
const payload = store.read(account);
|
|
876
|
-
const manifest = payload === undefined ? undefined : readChunkManifestFromPayload(serverName, payload, authSecretStoreLabel(store));
|
|
877
|
-
if (manifest)
|
|
878
|
-
removeChunkPayloads(store, account, manifest);
|
|
879
|
-
store.remove(account);
|
|
880
|
-
} catch (error) {
|
|
881
|
-
throw new OAuthCredentialStoreError(`Failed to remove OAuth credentials for ${serverName} from the ${authSecretStoreLabel(store)}`, "remove", error, store.kind);
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
export function removeAuthEntry(serverName, options) {
|
|
885
|
-
try {
|
|
886
|
-
removeAuthEntryFromStore(getAuthSecretStore(options), serverName);
|
|
887
|
-
} catch (error) {
|
|
888
|
-
if (options?.credentialStore === "encrypted-file" || !shouldAttemptLinuxKeyringRecovery(error))
|
|
889
|
-
throw error;
|
|
890
|
-
removeAuthEntryFromStore(linuxKeyringRecoveryAuthSecretStore, serverName);
|
|
891
|
-
}
|
|
892
|
-
evictAuthEntryCache(serverName, options);
|
|
893
|
-
if (options?.credentialStore !== "encrypted-file")
|
|
894
|
-
removeLegacyAuthEntry(serverName, options);
|
|
895
|
-
}
|
|
896
|
-
function evictAuthEntryCache(serverName, options = {}) {
|
|
897
|
-
if (options.credentialStore !== "encrypted-file") {
|
|
898
|
-
authEntryCache.delete(authEntryCacheKey(serverName, options, "remove"));
|
|
899
|
-
return;
|
|
900
|
-
}
|
|
901
|
-
for (const key of authEntryCache.keys()) {
|
|
902
|
-
const separator = key.indexOf("\x00");
|
|
903
|
-
if (key.startsWith("encrypted-file:") && separator !== -1 && key.slice(separator + 1) === serverName)
|
|
904
|
-
authEntryCache.delete(key);
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
export function invalidateAuthEntryCache(serverName) {
|
|
908
|
-
evictAuthEntryCache(serverName);
|
|
909
|
-
evictAuthEntryCache(serverName, { credentialStore: "encrypted-file" });
|
|
910
|
-
}
|
|
911
|
-
export function updateTokens(serverName, tokens, serverUrl, options) {
|
|
912
|
-
const entry = getAuthEntry(serverName, options) ?? {};
|
|
913
|
-
if (serverUrl && entry.serverUrl !== serverUrl) {
|
|
914
|
-
delete entry.clientInfo;
|
|
915
|
-
delete entry.codeVerifier;
|
|
916
|
-
delete entry.oauthState;
|
|
917
|
-
}
|
|
918
|
-
entry.tokens = tokens;
|
|
919
|
-
saveAuthEntry(serverName, entry, serverUrl, options);
|
|
920
|
-
}
|
|
921
|
-
export function updateClientInfo(serverName, clientInfo, serverUrl, options) {
|
|
922
|
-
const entry = getAuthEntry(serverName, options) ?? {};
|
|
923
|
-
if (serverUrl && entry.serverUrl !== serverUrl) {
|
|
924
|
-
delete entry.tokens;
|
|
925
|
-
delete entry.codeVerifier;
|
|
926
|
-
delete entry.oauthState;
|
|
927
|
-
}
|
|
928
|
-
entry.clientInfo = clientInfo;
|
|
929
|
-
saveAuthEntry(serverName, entry, serverUrl, options);
|
|
930
|
-
}
|
|
931
|
-
export function updateCodeVerifier(serverName, codeVerifier, serverUrl, options) {
|
|
932
|
-
const entry = getAuthEntry(serverName, options) ?? {};
|
|
933
|
-
if (serverUrl && entry.serverUrl !== serverUrl) {
|
|
934
|
-
delete entry.tokens;
|
|
935
|
-
delete entry.clientInfo;
|
|
936
|
-
delete entry.oauthState;
|
|
937
|
-
}
|
|
938
|
-
entry.codeVerifier = codeVerifier;
|
|
939
|
-
saveAuthEntry(serverName, entry, serverUrl, options);
|
|
940
|
-
}
|
|
941
|
-
export function clearCodeVerifier(serverName, options) {
|
|
942
|
-
const entry = getAuthEntry(serverName, options);
|
|
943
|
-
if (entry) {
|
|
944
|
-
delete entry.codeVerifier;
|
|
945
|
-
saveAuthEntry(serverName, entry, undefined, options);
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
export function updateOAuthState(serverName, state, serverUrl, options) {
|
|
949
|
-
const entry = getAuthEntry(serverName, options) ?? {};
|
|
950
|
-
if (serverUrl && entry.serverUrl !== serverUrl) {
|
|
951
|
-
delete entry.tokens;
|
|
952
|
-
delete entry.clientInfo;
|
|
953
|
-
delete entry.codeVerifier;
|
|
954
|
-
}
|
|
955
|
-
entry.oauthState = state;
|
|
956
|
-
saveAuthEntry(serverName, entry, serverUrl, options);
|
|
957
|
-
}
|
|
958
|
-
export function getOAuthState(serverName, options) {
|
|
959
|
-
const entry = getAuthEntry(serverName, options);
|
|
960
|
-
return entry?.oauthState;
|
|
961
|
-
}
|
|
962
|
-
export function clearOAuthState(serverName, options) {
|
|
963
|
-
const entry = getAuthEntry(serverName, options);
|
|
964
|
-
if (entry) {
|
|
965
|
-
delete entry.oauthState;
|
|
966
|
-
saveAuthEntry(serverName, entry, undefined, options);
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
export function isTokenExpired(serverName, options) {
|
|
970
|
-
const entry = getAuthEntry(serverName, options);
|
|
971
|
-
if (!entry?.tokens)
|
|
972
|
-
return null;
|
|
973
|
-
if (!entry.tokens.expiresAt)
|
|
974
|
-
return false;
|
|
975
|
-
return entry.tokens.expiresAt < Date.now() / 1000;
|
|
976
|
-
}
|
|
977
|
-
export function hasStoredTokens(serverName, options) {
|
|
978
|
-
const entry = getAuthEntry(serverName, options);
|
|
979
|
-
return !!entry?.tokens;
|
|
980
|
-
}
|
|
981
|
-
export function clearAllCredentials(serverName, options) {
|
|
982
|
-
removeAuthEntry(serverName, options);
|
|
983
|
-
}
|
|
984
|
-
export function clearClientInfo(serverName, options) {
|
|
985
|
-
const entry = getAuthEntry(serverName, options);
|
|
986
|
-
if (entry) {
|
|
987
|
-
delete entry.clientInfo;
|
|
988
|
-
saveAuthEntry(serverName, entry, undefined, options);
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
export function clearTokens(serverName, options) {
|
|
992
|
-
const entry = getAuthEntry(serverName, options);
|
|
993
|
-
if (entry) {
|
|
994
|
-
delete entry.tokens;
|
|
995
|
-
saveAuthEntry(serverName, entry, undefined, options);
|
|
996
|
-
}
|
|
997
|
-
}
|