@herbertgao/pi-extensions 2026.9.0 → 2026.9.1
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/node_modules/@czottmann/pi-automode/CHANGELOG.md +13 -1
- package/node_modules/@czottmann/pi-automode/README.md +20 -0
- package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +1 -1
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +2 -1
- package/node_modules/@czottmann/pi-automode/docs/defaults.md +3 -2
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +38 -2
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +5 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +11 -3
- package/node_modules/@czottmann/pi-automode/package.json +1 -1
- package/node_modules/@pi-plugins/fast-mode/README.md +5 -3
- package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +20 -55
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/package.json +1 -1
- package/node_modules/pi-lens/CHANGELOG.md +988 -0
- package/node_modules/pi-lens/README.md +3 -0
- package/node_modules/pi-lens/config/biome/core.jsonc +11 -2
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +13 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +927 -80
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +13 -4
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +123 -3
- package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +60 -5
- package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +1 -3
- package/node_modules/pi-lens/dist/clients/biome-client.js +9 -2
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +14 -0
- package/node_modules/pi-lens/dist/clients/bootstrap.js +509 -73
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +152 -12
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +59 -4
- package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +113 -0
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +31 -4
- package/node_modules/pi-lens/dist/clients/cache-manager.js +105 -6
- package/node_modules/pi-lens/dist/clients/cache-observability.js +44 -18
- package/node_modules/pi-lens/dist/clients/cargo-manifest.js +422 -0
- package/node_modules/pi-lens/dist/clients/cascade-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +13 -3
- package/node_modules/pi-lens/dist/clients/complexity-client.js +16 -5
- package/node_modules/pi-lens/dist/clients/config-core/deny.js +221 -0
- package/node_modules/pi-lens/dist/clients/config-core/index.js +47 -0
- package/node_modules/pi-lens/dist/clients/config-core/merge.js +357 -0
- package/node_modules/pi-lens/dist/clients/config-core/normalize.js +340 -0
- package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +248 -0
- package/node_modules/pi-lens/dist/clients/config-core/provenance.js +171 -0
- package/node_modules/pi-lens/dist/clients/config-core/records.js +218 -0
- package/node_modules/pi-lens/dist/clients/config-core/resolve.js +125 -0
- package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +78 -0
- package/node_modules/pi-lens/dist/clients/config-core/schema.js +167 -0
- package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +281 -0
- package/node_modules/pi-lens/dist/clients/config-locations.js +160 -0
- package/node_modules/pi-lens/dist/clients/config-resolve.js +789 -0
- package/node_modules/pi-lens/dist/clients/config-schema.js +197 -0
- package/node_modules/pi-lens/dist/clients/config-warn.js +407 -0
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -14
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +178 -0
- package/node_modules/pi-lens/dist/clients/debug-handles.js +2 -2
- package/node_modules/pi-lens/dist/clients/debug-heap.js +3 -3
- package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +106 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +113 -7
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +8 -19
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +12 -9
- package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +14 -4
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +162 -18
- package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +97 -0
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +9 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +380 -26
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +13 -18
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +7 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +3 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +3 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +194 -80
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +84 -15
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/disposition-logger.js +3 -3
- package/node_modules/pi-lens/dist/clients/effective-config.js +403 -0
- package/node_modules/pi-lens/dist/clients/error-class.js +23 -0
- package/node_modules/pi-lens/dist/clients/event-loop-hold.js +274 -0
- package/node_modules/pi-lens/dist/clients/extension-log.js +2 -2
- package/node_modules/pi-lens/dist/clients/feature-hints.js +2 -1
- package/node_modules/pi-lens/dist/clients/file-time.js +6 -1
- package/node_modules/pi-lens/dist/clients/file-utils.js +112 -9
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +50 -13
- package/node_modules/pi-lens/dist/clients/format-service.js +6 -1
- package/node_modules/pi-lens/dist/clients/formatters.js +276 -102
- package/node_modules/pi-lens/dist/clients/freshness-cadence.js +17 -0
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +114 -19
- package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -9
- package/node_modules/pi-lens/dist/clients/git-guard.js +1 -1
- package/node_modules/pi-lens/dist/clients/go-client.js +39 -0
- package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +252 -0
- package/node_modules/pi-lens/dist/clients/hashline-anchor.js +424 -0
- package/node_modules/pi-lens/dist/clients/hook-budgets.js +76 -0
- package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +5 -2
- package/node_modules/pi-lens/dist/clients/host-ports.js +1 -1
- package/node_modules/pi-lens/dist/clients/installer/index.js +71 -52
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +104 -230
- package/node_modules/pi-lens/dist/clients/instance-registry.js +6 -3
- package/node_modules/pi-lens/dist/clients/language-registry.js +595 -0
- package/node_modules/pi-lens/dist/clients/latency-logger.js +160 -2
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +13 -0
- package/node_modules/pi-lens/dist/clients/lens-config.js +141 -30
- package/node_modules/pi-lens/dist/clients/lens-engine.js +30 -37
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +59 -6
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -2
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +3 -1
- package/node_modules/pi-lens/dist/clients/lsp/client.js +168 -30
- package/node_modules/pi-lens/dist/clients/lsp/config.js +483 -158
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +15 -2
- package/node_modules/pi-lens/dist/clients/lsp/index.js +676 -71
- package/node_modules/pi-lens/dist/clients/lsp/language.js +18 -169
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +5 -16
- package/node_modules/pi-lens/dist/clients/lsp/server.js +284 -147
- package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +116 -23
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +2 -7
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +9 -2
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +163 -21
- package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +36 -0
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +33 -4
- package/node_modules/pi-lens/dist/clients/mcp/session.js +5 -16
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +8 -3
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +2 -4
- package/node_modules/pi-lens/dist/clients/module-report.js +20 -45
- package/node_modules/pi-lens/dist/clients/mutating-tool.js +651 -0
- package/node_modules/pi-lens/dist/clients/mutation-attribution.js +368 -0
- package/node_modules/pi-lens/dist/clients/mutation-bridge.js +240 -0
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +247 -20
- package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +101 -0
- package/node_modules/pi-lens/dist/clients/observed-mutation.js +1215 -0
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +68 -22
- package/node_modules/pi-lens/dist/clients/opengrep-config.js +4 -0
- package/node_modules/pi-lens/dist/clients/package-manager.js +195 -26
- package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +359 -80
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +23 -7
- package/node_modules/pi-lens/dist/clients/path-keyed-map.js +21 -2
- package/node_modules/pi-lens/dist/clients/path-utils.js +428 -13
- package/node_modules/pi-lens/dist/clients/persist-debounce.js +8 -1
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +114 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +77 -16
- package/node_modules/pi-lens/dist/clients/probe-home-state.js +228 -0
- package/node_modules/pi-lens/dist/clients/process-bridge.js +66 -0
- package/node_modules/pi-lens/dist/clients/process-snapshot.js +68 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +4 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +27 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +51 -20
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +393 -122
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +52 -24
- package/node_modules/pi-lens/dist/clients/python-environment.js +217 -0
- package/node_modules/pi-lens/dist/clients/python-provenance.js +639 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +6 -1
- package/node_modules/pi-lens/dist/clients/read-bridge.js +13 -21
- package/node_modules/pi-lens/dist/clients/read-expansion.js +9 -46
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +15 -4
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +364 -212
- package/node_modules/pi-lens/dist/clients/read-guard.js +21 -0
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +195 -96
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +152 -109
- package/node_modules/pi-lens/dist/clients/review-graph/service.js +55 -3
- package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +7 -15
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +10 -74
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +9 -3
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +18 -2
- package/node_modules/pi-lens/dist/clients/runtime-context.js +49 -16
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +25 -6
- package/node_modules/pi-lens/dist/clients/runtime-session.js +139 -22
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +168 -35
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +797 -243
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +1028 -53
- package/node_modules/pi-lens/dist/clients/rust-client.js +31 -0
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +33 -10
- package/node_modules/pi-lens/dist/clients/sanitize.js +7 -1
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +1 -3
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +3 -0
- package/node_modules/pi-lens/dist/clients/session-lifecycle.js +1 -1
- package/node_modules/pi-lens/dist/clients/session-start-observability.js +79 -0
- package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +12 -3
- package/node_modules/pi-lens/dist/clients/sgconfig.js +6 -1
- package/node_modules/pi-lens/dist/clients/skills-resolver.js +105 -0
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +2 -2
- package/node_modules/pi-lens/dist/clients/string-utils.js +13 -0
- package/node_modules/pi-lens/dist/clients/subagent-mode.js +17 -4
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +176 -39
- package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +239 -0
- package/node_modules/pi-lens/dist/clients/tool-definition.js +41 -1
- package/node_modules/pi-lens/dist/clients/tool-policy.js +91 -21
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +40 -40
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +86 -48
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +81 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +51 -46
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +28 -0
- package/node_modules/pi-lens/dist/clients/typos-config.js +5 -0
- package/node_modules/pi-lens/dist/clients/user-notify.js +6 -2
- package/node_modules/pi-lens/dist/clients/widget-state.js +191 -26
- package/node_modules/pi-lens/dist/clients/word-index-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/word-index-store.js +20 -5
- package/node_modules/pi-lens/dist/clients/word-index.js +243 -31
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -1
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +3 -0
- package/node_modules/pi-lens/dist/index.js +64335 -54300
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -1
- package/node_modules/pi-lens/dist/mcp/server.js +127 -5
- package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +583 -0
- package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +129 -0
- package/node_modules/pi-lens/dist/tools/effective-config.js +89 -0
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +95 -24
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +67 -80
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +37 -16
- package/node_modules/pi-lens/dist/tools/shared.js +0 -1
- package/node_modules/pi-lens/docs/agent-guide.md +64 -1
- package/node_modules/pi-lens/docs/configuration.md +222 -0
- package/node_modules/pi-lens/docs/dependencies.md +3 -3
- package/node_modules/pi-lens/docs/features.md +44 -5
- package/node_modules/pi-lens/docs/language-coverage.md +2 -2
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +25 -0
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +25 -0
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +27 -0
- package/node_modules/pi-lens/docs/pi-lens-subagent.md +38 -0
- package/node_modules/pi-lens/docs/pi-lens-warden.md +55 -0
- package/node_modules/pi-lens/docs/public-api-stability.md +359 -0
- package/node_modules/pi-lens/docs/release-qa-baseline.md +182 -0
- package/node_modules/pi-lens/docs/subagent-compat.md +110 -30
- package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +2 -2
- package/node_modules/pi-lens/package.json +15 -23
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-cross-language-method.yml +3 -3
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-hallucinated-import.yml +2 -2
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-sql-injection.yml +12 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +192 -1
- package/node_modules/pi-lens/scripts/install-selftest.mjs +58 -2
- package/node_modules/pi-lens/scripts/lib/skills-predicate.mjs +129 -0
- package/node_modules/pi-lens/scripts/rpc-load-check.mjs +3 -1
- package/node_modules/pi-web-access/CHANGELOG.md +28 -0
- package/node_modules/pi-web-access/README.md +62 -15
- package/node_modules/pi-web-access/curator-page.ts +3 -1
- package/node_modules/pi-web-access/curator-server.ts +5 -1
- package/node_modules/pi-web-access/gemini-search.ts +8 -4
- package/node_modules/pi-web-access/github-extract.ts +242 -1
- package/node_modules/pi-web-access/index.ts +118 -64
- package/node_modules/pi-web-access/mistral-search.ts +281 -0
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/perplexity.ts +14 -1
- package/node_modules/pi-web-access/utils.ts +23 -6
- package/node_modules/pi-web-access/xai-search.ts +96 -33
- package/package.json +5 -5
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { chmodSync, closeSync, existsSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, readSync, readdirSync, realpathSync, rmSync, statSync, unlinkSync } from "node:fs";
|
|
1
|
+
import { chmodSync, closeSync, constants as fsConstants, existsSync, fstatSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, readSync, readdirSync, realpathSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { lstat as lstatAsync, open as openAsync, opendir as opendirAsync, readFile as readFileAsync, realpath as realpathAsync, rm as rmAsync, type FileHandle } from "node:fs/promises";
|
|
2
3
|
import { execFile, spawn, type ChildProcess } from "node:child_process";
|
|
3
4
|
import { createHash } from "node:crypto";
|
|
4
5
|
import { basename, dirname, extname, join, resolve as resolvePath, sep as pathSep } from "node:path";
|
|
@@ -29,6 +30,9 @@ const NOISE_DIRS = new Set([
|
|
|
29
30
|
|
|
30
31
|
const MAX_INLINE_FILE_CHARS = 100_000;
|
|
31
32
|
const MAX_TREE_ENTRIES = 200;
|
|
33
|
+
const CLONE_RUNTIME_OWNER_FILENAME = ".owner.json";
|
|
34
|
+
const CLONE_RUNTIME_OWNER_VERSION = 1;
|
|
35
|
+
const MAX_CLONE_RUNTIME_OWNER_BYTES = 1024;
|
|
32
36
|
|
|
33
37
|
export interface GitHubUrlInfo {
|
|
34
38
|
owner: string;
|
|
@@ -49,6 +53,14 @@ interface CloneDestination {
|
|
|
49
53
|
localPath: string;
|
|
50
54
|
}
|
|
51
55
|
|
|
56
|
+
interface CloneRuntimeOwner {
|
|
57
|
+
version: 1;
|
|
58
|
+
pid: number;
|
|
59
|
+
platform: string;
|
|
60
|
+
bootId?: string;
|
|
61
|
+
startTime?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
52
64
|
interface GitHubCloneConfig {
|
|
53
65
|
enabled: boolean;
|
|
54
66
|
maxRepoSizeMB: number;
|
|
@@ -57,6 +69,7 @@ interface GitHubCloneConfig {
|
|
|
57
69
|
}
|
|
58
70
|
|
|
59
71
|
const cloneCache = new Map<string, CachedClone>();
|
|
72
|
+
const startedCloneRuntimeCleanups = new Set<string>();
|
|
60
73
|
|
|
61
74
|
let cachedConfig: GitHubCloneConfig | null = null;
|
|
62
75
|
let cloneRuntime: { parentPath: string; rootPath: string } | null = null;
|
|
@@ -190,6 +203,232 @@ function cacheKey(owner: string, repo: string, ref?: string): string {
|
|
|
190
203
|
return ref ? `${owner}/${repo}@${ref}` : `${owner}/${repo}`;
|
|
191
204
|
}
|
|
192
205
|
|
|
206
|
+
function readLinuxBootId(): string | null {
|
|
207
|
+
try {
|
|
208
|
+
const bootId = readFileSync("/proc/sys/kernel/random/boot_id", "utf-8").trim();
|
|
209
|
+
return bootId.length > 0 ? bootId : null;
|
|
210
|
+
} catch {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function readLinuxBootIdAsync(): Promise<string | null> {
|
|
216
|
+
try {
|
|
217
|
+
const bootId = (await readFileAsync("/proc/sys/kernel/random/boot_id", "utf-8")).trim();
|
|
218
|
+
return bootId.length > 0 ? bootId : null;
|
|
219
|
+
} catch {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
interface LinuxProcessInfo {
|
|
225
|
+
state: string;
|
|
226
|
+
startTime: string | null;
|
|
227
|
+
dead: boolean;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function parseLinuxProcessInfo(stat: string): LinuxProcessInfo | null {
|
|
231
|
+
const closingParen = stat.lastIndexOf(") ");
|
|
232
|
+
if (closingParen < 0) return null;
|
|
233
|
+
const fields = stat.slice(closingParen + 2).trim().split(/\s+/);
|
|
234
|
+
const state = fields[0];
|
|
235
|
+
const startTime = fields[19];
|
|
236
|
+
if (!state || !startTime || !/^\d+$/.test(startTime)) return null;
|
|
237
|
+
return { state, startTime, dead: false };
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function readLinuxProcessInfo(pid: number): LinuxProcessInfo | null {
|
|
241
|
+
try {
|
|
242
|
+
return parseLinuxProcessInfo(readFileSync(`/proc/${pid}/stat`, "utf-8"));
|
|
243
|
+
} catch (err) {
|
|
244
|
+
if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") {
|
|
245
|
+
return { state: "", startTime: null, dead: true };
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async function readLinuxProcessInfoAsync(pid: number): Promise<LinuxProcessInfo | null> {
|
|
252
|
+
try {
|
|
253
|
+
return parseLinuxProcessInfo(await readFileAsync(`/proc/${pid}/stat`, "utf-8"));
|
|
254
|
+
} catch (err) {
|
|
255
|
+
if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") {
|
|
256
|
+
return { state: "", startTime: null, dead: true };
|
|
257
|
+
}
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function currentCloneRuntimeOwner(): CloneRuntimeOwner {
|
|
263
|
+
const owner: CloneRuntimeOwner = {
|
|
264
|
+
version: CLONE_RUNTIME_OWNER_VERSION,
|
|
265
|
+
pid: process.pid,
|
|
266
|
+
platform: process.platform,
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
if (process.platform === "linux") {
|
|
270
|
+
const bootId = readLinuxBootId();
|
|
271
|
+
const processInfo = readLinuxProcessInfo(process.pid);
|
|
272
|
+
if (bootId && processInfo?.startTime) {
|
|
273
|
+
owner.bootId = bootId;
|
|
274
|
+
owner.startTime = processInfo.startTime;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return owner;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function writeCloneRuntimeOwner(runtimePath: string): void {
|
|
282
|
+
const ownerPath = join(runtimePath, CLONE_RUNTIME_OWNER_FILENAME);
|
|
283
|
+
writeFileSync(ownerPath, JSON.stringify(currentCloneRuntimeOwner()), {
|
|
284
|
+
encoding: "utf-8",
|
|
285
|
+
flag: "wx",
|
|
286
|
+
mode: 0o600,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function parseCloneRuntimeOwner(text: string): CloneRuntimeOwner | null {
|
|
291
|
+
let parsed: unknown;
|
|
292
|
+
try {
|
|
293
|
+
parsed = JSON.parse(text);
|
|
294
|
+
} catch {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
298
|
+
|
|
299
|
+
const record = parsed as Record<string, unknown>;
|
|
300
|
+
if (
|
|
301
|
+
record.version !== CLONE_RUNTIME_OWNER_VERSION ||
|
|
302
|
+
typeof record.pid !== "number" ||
|
|
303
|
+
!Number.isSafeInteger(record.pid) ||
|
|
304
|
+
record.pid <= 0 ||
|
|
305
|
+
typeof record.platform !== "string" ||
|
|
306
|
+
record.platform.length === 0 ||
|
|
307
|
+
record.platform.length > 32
|
|
308
|
+
) {
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const owner: CloneRuntimeOwner = {
|
|
313
|
+
version: CLONE_RUNTIME_OWNER_VERSION,
|
|
314
|
+
pid: record.pid,
|
|
315
|
+
platform: record.platform,
|
|
316
|
+
};
|
|
317
|
+
if (record.bootId !== undefined) {
|
|
318
|
+
if (typeof record.bootId !== "string" || record.bootId.length === 0 || record.bootId.length > 256) return null;
|
|
319
|
+
owner.bootId = record.bootId;
|
|
320
|
+
}
|
|
321
|
+
if (record.startTime !== undefined) {
|
|
322
|
+
if (typeof record.startTime !== "string" || !/^\d+$/.test(record.startTime)) return null;
|
|
323
|
+
owner.startTime = record.startTime;
|
|
324
|
+
}
|
|
325
|
+
return owner;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async function readCloneRuntimeOwner(runtimePath: string): Promise<CloneRuntimeOwner | null> {
|
|
329
|
+
const ownerPath = join(runtimePath, CLONE_RUNTIME_OWNER_FILENAME);
|
|
330
|
+
let file: FileHandle | undefined;
|
|
331
|
+
try {
|
|
332
|
+
const entry = await lstatAsync(ownerPath);
|
|
333
|
+
if (!entry.isFile() || entry.size > MAX_CLONE_RUNTIME_OWNER_BYTES) return null;
|
|
334
|
+
const noFollow = fsConstants.O_NOFOLLOW ?? 0;
|
|
335
|
+
file = await openAsync(ownerPath, fsConstants.O_RDONLY | noFollow);
|
|
336
|
+
const opened = await file.stat();
|
|
337
|
+
if (!opened.isFile() || opened.size > MAX_CLONE_RUNTIME_OWNER_BYTES) return null;
|
|
338
|
+
return parseCloneRuntimeOwner(await file.readFile("utf-8"));
|
|
339
|
+
} catch {
|
|
340
|
+
return null;
|
|
341
|
+
} finally {
|
|
342
|
+
if (file !== undefined) {
|
|
343
|
+
try {
|
|
344
|
+
await file.close();
|
|
345
|
+
} catch {
|
|
346
|
+
// The handle may already have been closed externally.
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function processNonexistenceProven(pid: number): boolean {
|
|
353
|
+
try {
|
|
354
|
+
process.kill(pid, 0);
|
|
355
|
+
return false;
|
|
356
|
+
} catch (err) {
|
|
357
|
+
return Boolean(err && typeof err === "object" && "code" in err && err.code === "ESRCH");
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
async function cloneRuntimeOwnerIsDead(owner: CloneRuntimeOwner, bootId: string | null): Promise<boolean> {
|
|
362
|
+
if (owner.platform !== process.platform) return false;
|
|
363
|
+
|
|
364
|
+
if (process.platform !== "linux") {
|
|
365
|
+
return processNonexistenceProven(owner.pid);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Linux PID values can be reused. Require both boot ID and proc start time
|
|
369
|
+
// before treating a runtime as owned, and preserve it when either check is
|
|
370
|
+
// unavailable.
|
|
371
|
+
if (!owner.bootId || !owner.startTime || !bootId) return false;
|
|
372
|
+
const processInfo = await readLinuxProcessInfoAsync(owner.pid);
|
|
373
|
+
if (!processInfo) return false;
|
|
374
|
+
if (processInfo.dead || processInfo.state === "Z" || processInfo.state === "X") return true;
|
|
375
|
+
return processInfo.startTime !== owner.startTime || bootId !== owner.bootId;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
async function removeCloneRuntimeAsync(parentPath: string, runtimePath: string): Promise<void> {
|
|
379
|
+
const normalizedParentPath = resolvePath(parentPath);
|
|
380
|
+
const normalizedRuntimePath = resolvePath(runtimePath);
|
|
381
|
+
if (dirname(normalizedRuntimePath) !== normalizedParentPath || !basename(normalizedRuntimePath).startsWith("runtime-")) return;
|
|
382
|
+
|
|
383
|
+
try {
|
|
384
|
+
const realRuntimePath = await realpathAsync(normalizedRuntimePath);
|
|
385
|
+
if (dirname(realRuntimePath) !== normalizedParentPath || basename(realRuntimePath) !== basename(normalizedRuntimePath)) return;
|
|
386
|
+
const entry = await lstatAsync(normalizedRuntimePath);
|
|
387
|
+
if (entry.isSymbolicLink() || !entry.isDirectory()) return;
|
|
388
|
+
await rmAsync(normalizedRuntimePath, { recursive: true, force: true });
|
|
389
|
+
} catch {
|
|
390
|
+
// The runtime directory may already have been removed externally.
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
async function sweepStaleCloneRuntimes(parentPath: string): Promise<void> {
|
|
395
|
+
const normalizedParentPath = resolvePath(parentPath);
|
|
396
|
+
const bootId = process.platform === "linux" ? await readLinuxBootIdAsync() : null;
|
|
397
|
+
try {
|
|
398
|
+
const directory = await opendirAsync(normalizedParentPath);
|
|
399
|
+
for await (const entry of directory) {
|
|
400
|
+
if (!entry.name.startsWith("runtime-")) continue;
|
|
401
|
+
try {
|
|
402
|
+
if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
|
|
403
|
+
const runtimePath = resolvePath(normalizedParentPath, entry.name);
|
|
404
|
+
if (dirname(runtimePath) !== normalizedParentPath) continue;
|
|
405
|
+
const runtimeEntry = await lstatAsync(runtimePath);
|
|
406
|
+
if (!runtimeEntry.isDirectory() || runtimeEntry.isSymbolicLink()) continue;
|
|
407
|
+
const realRuntimePath = await realpathAsync(runtimePath);
|
|
408
|
+
if (dirname(realRuntimePath) !== normalizedParentPath || basename(realRuntimePath) !== basename(runtimePath)) continue;
|
|
409
|
+
const owner = await readCloneRuntimeOwner(runtimePath);
|
|
410
|
+
if (!owner || !(await cloneRuntimeOwnerIsDead(owner, bootId))) continue;
|
|
411
|
+
await removeCloneRuntimeAsync(normalizedParentPath, runtimePath);
|
|
412
|
+
} catch {
|
|
413
|
+
// A changing or unreadable runtime must not stop the rest of the sweep.
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
} catch {
|
|
417
|
+
// Cleanup is opportunistic. A changing or unreadable cache must not stop
|
|
418
|
+
// GitHub extraction from falling back to the API.
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function startStaleCloneRuntimeCleanup(parentPath: string): void {
|
|
423
|
+
const normalizedParentPath = resolvePath(parentPath);
|
|
424
|
+
if (startedCloneRuntimeCleanups.has(normalizedParentPath)) return;
|
|
425
|
+
startedCloneRuntimeCleanups.add(normalizedParentPath);
|
|
426
|
+
// Keep runtime creation synchronous and let the complete sweep run in the background.
|
|
427
|
+
void sweepStaleCloneRuntimes(normalizedParentPath).catch(() => {
|
|
428
|
+
// Cleanup is best effort and must never affect extraction.
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
|
|
193
432
|
function removeCloneRuntime(parentPath: string, runtimePath: string): void {
|
|
194
433
|
const normalizedParentPath = resolvePath(parentPath);
|
|
195
434
|
const normalizedRuntimePath = resolvePath(runtimePath);
|
|
@@ -213,6 +452,7 @@ function getCloneRuntimeRoot(config: GitHubCloneConfig): string | null {
|
|
|
213
452
|
const configuredPath = resolvePath(config.clonePath);
|
|
214
453
|
mkdirSync(configuredPath, { recursive: true });
|
|
215
454
|
parentPath = realpathSync(configuredPath);
|
|
455
|
+
startStaleCloneRuntimeCleanup(parentPath);
|
|
216
456
|
runtimePath = mkdtempSync(join(parentPath, "runtime-"));
|
|
217
457
|
chmodSync(runtimePath, 0o700);
|
|
218
458
|
const rootPath = realpathSync(runtimePath);
|
|
@@ -220,6 +460,7 @@ function getCloneRuntimeRoot(config: GitHubCloneConfig): string | null {
|
|
|
220
460
|
removeCloneRuntime(parentPath, runtimePath);
|
|
221
461
|
return null;
|
|
222
462
|
}
|
|
463
|
+
writeCloneRuntimeOwner(rootPath);
|
|
223
464
|
cloneRuntime = { parentPath, rootPath };
|
|
224
465
|
return rootPath;
|
|
225
466
|
} catch {
|