@herbertgao/pi-extensions 2026.10.0 → 2026.10.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/README.md +16 -12
- package/THIRD_PARTY_NOTICES.md +3 -3
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-audit.md +2 -2
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-debt.md +2 -2
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-gain.md +1 -1
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-help.md +1 -1
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-review.md +2 -2
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail.md +1 -1
- package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/index.js +4 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail-frontmatter.cjs +43 -3
- package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail.mjs +142 -59
- package/node_modules/@dietrichgebert/ponytail/.qoder/rules/ponytail.md +21 -21
- package/node_modules/@dietrichgebert/ponytail/.qoder-plugin/plugin.json +1 -1
- package/node_modules/@dietrichgebert/ponytail/AGENTS.md +21 -21
- package/node_modules/@dietrichgebert/ponytail/README.md +52 -242
- package/node_modules/@dietrichgebert/ponytail/hooks/claude-codex-hooks.json +3 -3
- package/node_modules/@dietrichgebert/ponytail/hooks/copilot-hooks.json +4 -4
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-activate.js +70 -16
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-config.js +8 -7
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-instructions.js +30 -30
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-map.js +103 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-mode-tracker.js +46 -23
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-runtime.js +39 -7
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-subagent.js +20 -3
- package/node_modules/@dietrichgebert/ponytail/hooks/qoder-hooks.json +3 -3
- package/node_modules/@dietrichgebert/ponytail/package.json +3 -3
- package/node_modules/@dietrichgebert/ponytail/pi-extension/index.js +47 -17
- package/node_modules/@dietrichgebert/ponytail/scripts/uninstall.js +21 -7
- package/node_modules/@dietrichgebert/ponytail/skills/plugin.json +5 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail/SKILL.md +33 -101
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-audit/SKILL.md +89 -27
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-debt/SKILL.md +13 -12
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-gain/SKILL.md +21 -18
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-help/SKILL.md +12 -13
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-review/SKILL.md +96 -52
- package/node_modules/@herbertgao/pi-agency/LICENSE +21 -0
- package/node_modules/@herbertgao/pi-agency/README.md +40 -0
- package/node_modules/@herbertgao/pi-agency/package.json +53 -0
- package/node_modules/@herbertgao/pi-agency/src/index.ts +441 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +12 -12
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +30 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +15 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +27 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/codemode.ts +4 -1
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +2 -2
- package/node_modules/@narumitw/pi-caffeinate/package.json +4 -4
- package/node_modules/@tifan/pi-mermaid-open/package.json +5 -1
- package/node_modules/@tifan/pi-mermaid-open/src/index.ts +26 -9
- package/node_modules/@tifan/pi-recap/package.json +1 -1
- package/node_modules/@tifan/pi-recap/src/index.ts +104 -20
- package/node_modules/@tifan/pi-recap/src/models.ts +46 -4
- package/node_modules/pi-antigravity/README.md +23 -2
- package/node_modules/pi-antigravity/package.json +5 -3
- package/node_modules/pi-antigravity/src/diagnostics/diagnostics.ts +3 -2
- package/node_modules/pi-antigravity/src/features/generate-image.ts +72 -0
- package/node_modules/pi-antigravity/src/features/google-search.ts +71 -0
- package/node_modules/pi-antigravity/src/image/image.ts +86 -47
- package/node_modules/pi-antigravity/src/image/native.ts +69 -0
- package/node_modules/pi-antigravity/src/index.ts +52 -137
- package/node_modules/pi-antigravity/src/search/search.ts +130 -31
- package/node_modules/pi-antigravity/src/stream/stream.ts +162 -113
- package/node_modules/pi-antigravity/src/types/enums.ts +1 -0
- package/node_modules/pi-antigravity/src/types/types.ts +1 -1
- package/node_modules/pi-antigravity/src/utils/security.ts +47 -1
- package/node_modules/pi-antigravity/src/utils/util.ts +38 -6
- package/node_modules/pi-lens/CHANGELOG.md +1064 -0
- package/node_modules/pi-lens/README.md +115 -25
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +6 -2
- package/node_modules/pi-lens/dist/chunk-22AVIGXS.js +560 -0
- package/node_modules/pi-lens/dist/chunk-27BBHSZC.js +106 -0
- package/node_modules/pi-lens/dist/chunk-2BEMIWEW.js +51 -0
- package/node_modules/pi-lens/dist/chunk-2EECBNC5.js +89 -0
- package/node_modules/pi-lens/dist/chunk-34U7PLGE.js +23 -0
- package/node_modules/pi-lens/dist/chunk-3I5QFT3N.js +181 -0
- package/node_modules/pi-lens/dist/chunk-3MED75HT.js +37 -0
- package/node_modules/pi-lens/dist/chunk-47D2BO4S.js +87 -0
- package/node_modules/pi-lens/dist/chunk-4RERDEXR.js +348 -0
- package/node_modules/pi-lens/dist/chunk-4W2PLC4J.js +27 -0
- package/node_modules/pi-lens/dist/chunk-52H5B5TC.js +202 -0
- package/node_modules/pi-lens/dist/chunk-54B42YRX.js +27 -0
- package/node_modules/pi-lens/dist/chunk-5RXBNSW2.js +266 -0
- package/node_modules/pi-lens/dist/chunk-5THXD6X5.js +201 -0
- package/node_modules/pi-lens/dist/chunk-5W3R6LFT.js +24 -0
- package/node_modules/pi-lens/dist/chunk-5ZEJHV35.js +341 -0
- package/node_modules/pi-lens/dist/chunk-6P62QVEA.js +118 -0
- package/node_modules/pi-lens/dist/chunk-6QIUX4EP.js +459 -0
- package/node_modules/pi-lens/dist/chunk-6VCD4VKZ.js +78 -0
- package/node_modules/pi-lens/dist/chunk-7F72PXY2.js +326 -0
- package/node_modules/pi-lens/dist/chunk-7FBF7NPR.js +998 -0
- package/node_modules/pi-lens/dist/chunk-7U2IDNXN.js +37 -0
- package/node_modules/pi-lens/dist/chunk-ABBOA7UD.js +157 -0
- package/node_modules/pi-lens/dist/chunk-AHDW3GPE.js +50 -0
- package/node_modules/pi-lens/dist/chunk-AJ3QXTRQ.js +756 -0
- package/node_modules/pi-lens/dist/chunk-AJVLWNFN.js +1610 -0
- package/node_modules/pi-lens/dist/chunk-AJXODZY6.js +112 -0
- package/node_modules/pi-lens/dist/chunk-ARFCXG7S.js +84 -0
- package/node_modules/pi-lens/dist/chunk-AS44CFQ4.js +708 -0
- package/node_modules/pi-lens/dist/chunk-AWE5TMPO.js +38 -0
- package/node_modules/pi-lens/dist/chunk-B3I2UUT4.js +4692 -0
- package/node_modules/pi-lens/dist/chunk-BRJKOBZP.js +331 -0
- package/node_modules/pi-lens/dist/chunk-BW5KFIQC.js +59 -0
- package/node_modules/pi-lens/dist/chunk-C2AUYXQH.js +149 -0
- package/node_modules/pi-lens/dist/chunk-CGGAIP7J.js +29 -0
- package/node_modules/pi-lens/dist/chunk-D6QS3U6M.js +30 -0
- package/node_modules/pi-lens/dist/chunk-DFVMIKMQ.js +349 -0
- package/node_modules/pi-lens/dist/chunk-DIULIWKU.js +169 -0
- package/node_modules/pi-lens/dist/chunk-DQ2NZ7C4.js +2317 -0
- package/node_modules/pi-lens/dist/chunk-E2WFBRHM.js +213 -0
- package/node_modules/pi-lens/dist/chunk-E4MAEDPM.js +50 -0
- package/node_modules/pi-lens/dist/chunk-EOKRQ3SA.js +30 -0
- package/node_modules/pi-lens/dist/chunk-F3AU2TMM.js +2626 -0
- package/node_modules/pi-lens/dist/chunk-F3P7VQ7H.js +170 -0
- package/node_modules/pi-lens/dist/chunk-FC4RP4I2.js +12 -0
- package/node_modules/pi-lens/dist/chunk-FJNKANOS.js +32 -0
- package/node_modules/pi-lens/dist/chunk-GUOGVTCQ.js +146 -0
- package/node_modules/pi-lens/dist/chunk-GVXA6CCE.js +18 -0
- package/node_modules/pi-lens/dist/chunk-HHYAELLJ.js +2334 -0
- package/node_modules/pi-lens/dist/chunk-HMFXILPV.js +83 -0
- package/node_modules/pi-lens/dist/chunk-HVUZXSWK.js +421 -0
- package/node_modules/pi-lens/dist/chunk-HWBZIGMJ.js +62 -0
- package/node_modules/pi-lens/dist/chunk-I3R7GKDR.js +17 -0
- package/node_modules/pi-lens/dist/chunk-I7SPGOWI.js +55 -0
- package/node_modules/pi-lens/dist/chunk-IIXOAGHR.js +38 -0
- package/node_modules/pi-lens/dist/chunk-IVP5KAB7.js +2250 -0
- package/node_modules/pi-lens/dist/chunk-IXEBJSUE.js +22 -0
- package/node_modules/pi-lens/dist/chunk-JOLITGCC.js +27 -0
- package/node_modules/pi-lens/dist/chunk-K6VYLB2U.js +145 -0
- package/node_modules/pi-lens/dist/chunk-LJDODBBZ.js +78 -0
- package/node_modules/pi-lens/dist/chunk-LNAKEO63.js +78 -0
- package/node_modules/pi-lens/dist/chunk-LSMJ6KBE.js +4139 -0
- package/node_modules/pi-lens/dist/chunk-LW6XKDZQ.js +5565 -0
- package/node_modules/pi-lens/dist/chunk-N3YQJI6O.js +899 -0
- package/node_modules/pi-lens/dist/chunk-NABLC7W3.js +148 -0
- package/node_modules/pi-lens/dist/chunk-NKOUFPQF.js +659 -0
- package/node_modules/pi-lens/dist/chunk-NL5GLMFI.js +211 -0
- package/node_modules/pi-lens/dist/chunk-NMABWBZN.js +327 -0
- package/node_modules/pi-lens/dist/chunk-NTHH2J74.js +27 -0
- package/node_modules/pi-lens/dist/chunk-NTUJEGDZ.js +59 -0
- package/node_modules/pi-lens/dist/chunk-NXL4FFQQ.js +47 -0
- package/node_modules/pi-lens/dist/chunk-NXPS2L6U.js +466 -0
- package/node_modules/pi-lens/dist/chunk-O5WILGMI.js +42 -0
- package/node_modules/pi-lens/dist/chunk-O6TQT6RI.js +48 -0
- package/node_modules/pi-lens/dist/chunk-OAXNDZJ7.js +323 -0
- package/node_modules/pi-lens/dist/chunk-ODEEOXPH.js +44 -0
- package/node_modules/pi-lens/dist/chunk-OQGFCZJ4.js +4533 -0
- package/node_modules/pi-lens/dist/chunk-ORTMY4Q4.js +282 -0
- package/node_modules/pi-lens/dist/chunk-OS32RNR2.js +442 -0
- package/node_modules/pi-lens/dist/chunk-PAK6IDME.js +189 -0
- package/node_modules/pi-lens/dist/chunk-PWFHBTSF.js +406 -0
- package/node_modules/pi-lens/dist/chunk-Q5U6FMDI.js +2352 -0
- package/node_modules/pi-lens/dist/chunk-QOZXJ4NA.js +3364 -0
- package/node_modules/pi-lens/dist/chunk-QYF5S6P6.js +45 -0
- package/node_modules/pi-lens/dist/chunk-RIISMHKN.js +36 -0
- package/node_modules/pi-lens/dist/chunk-RPD4ZSB7.js +25 -0
- package/node_modules/pi-lens/dist/chunk-RPD5K5NC.js +79 -0
- package/node_modules/pi-lens/dist/chunk-RUOG5D2C.js +262 -0
- package/node_modules/pi-lens/dist/chunk-T4ERT73Y.js +599 -0
- package/node_modules/pi-lens/dist/chunk-T6D4Q4AQ.js +54 -0
- package/node_modules/pi-lens/dist/chunk-TGPXLY2J.js +391 -0
- package/node_modules/pi-lens/dist/chunk-TLGFBM3F.js +12116 -0
- package/node_modules/pi-lens/dist/chunk-TO6WL3GM.js +88 -0
- package/node_modules/pi-lens/dist/chunk-TT22N74J.js +517 -0
- package/node_modules/pi-lens/dist/chunk-TVN5N6GY.js +21216 -0
- package/node_modules/pi-lens/dist/chunk-U3VGR4VU.js +308 -0
- package/node_modules/pi-lens/dist/chunk-UK3CMEAL.js +1250 -0
- package/node_modules/pi-lens/dist/chunk-UOPVJQ4N.js +103 -0
- package/node_modules/pi-lens/dist/chunk-UXVNL3D7.js +23 -0
- package/node_modules/pi-lens/dist/chunk-UY752QSN.js +45 -0
- package/node_modules/pi-lens/dist/chunk-V5PXFSZK.js +188 -0
- package/node_modules/pi-lens/dist/chunk-V7R425XG.js +398 -0
- package/node_modules/pi-lens/dist/chunk-VCSRSYLF.js +81 -0
- package/node_modules/pi-lens/dist/chunk-VD4JQCQC.js +162 -0
- package/node_modules/pi-lens/dist/chunk-VDBPVIKD.js +62 -0
- package/node_modules/pi-lens/dist/chunk-VHQLPIRJ.js +114 -0
- package/node_modules/pi-lens/dist/chunk-VN2AXLEX.js +5414 -0
- package/node_modules/pi-lens/dist/chunk-VNMT7C64.js +478 -0
- package/node_modules/pi-lens/dist/chunk-WONERJTP.js +309 -0
- package/node_modules/pi-lens/dist/chunk-XECLWQZN.js +85 -0
- package/node_modules/pi-lens/dist/chunk-XIMYZ3JA.js +27 -0
- package/node_modules/pi-lens/dist/chunk-XK4CIILI.js +144 -0
- package/node_modules/pi-lens/dist/chunk-Y4T27COV.js +562 -0
- package/node_modules/pi-lens/dist/chunk-YGVYKNSN.js +1860 -0
- package/node_modules/pi-lens/dist/chunk-YLF3PPT5.js +308 -0
- package/node_modules/pi-lens/dist/chunk-YSNFMJKN.js +14 -0
- package/node_modules/pi-lens/dist/chunk-Z3CCVDUB.js +76 -0
- package/node_modules/pi-lens/dist/chunk-Z54ZSOBZ.js +61 -0
- package/node_modules/pi-lens/dist/chunk-ZAWW3AF6.js +97 -0
- package/node_modules/pi-lens/dist/chunk-ZMOL6RQC.js +167 -0
- package/node_modules/pi-lens/dist/index.js +16456 -8335
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +186 -232
- package/node_modules/pi-lens/dist/mcp/cli.js +137 -98
- package/node_modules/pi-lens/dist/mcp/server.js +22589 -1573
- package/node_modules/pi-lens/dist/mcp/worker.js +97 -38
- package/node_modules/pi-lens/dist/probes/installer.js +135 -0
- package/node_modules/pi-lens/dist/workers/project-snapshot-persist-worker.js +22 -0
- package/node_modules/pi-lens/dist/workers/review-graph-persist-worker.js +15 -0
- package/node_modules/pi-lens/docs/agent-guide.md +13 -4
- package/node_modules/pi-lens/docs/agent-tools.md +42 -0
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +3 -2
- package/node_modules/pi-lens/docs/configuration.md +20 -1
- package/node_modules/pi-lens/docs/environment-variables.md +52 -2
- package/node_modules/pi-lens/docs/features.md +8 -4
- package/node_modules/pi-lens/docs/globalconfig.md +1 -0
- package/node_modules/pi-lens/docs/io-bridge-v2-migration.md +94 -0
- package/node_modules/pi-lens/docs/lsp-capability-matrix.md +36 -4
- package/node_modules/pi-lens/docs/lsp-idle-eviction.md +124 -0
- package/node_modules/pi-lens/docs/mcp.md +21 -5
- package/node_modules/pi-lens/docs/merge-queue-rollout.md +77 -0
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +156 -88
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +74 -26
- package/node_modules/pi-lens/docs/pi-lens-merge-policy.md +694 -0
- package/node_modules/pi-lens/docs/pi-lens-monitor.md +73 -7
- package/node_modules/pi-lens/docs/pi-lens-retro.md +6 -4
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +188 -48
- package/node_modules/pi-lens/docs/pi-lens-subagent.md +246 -45
- package/node_modules/pi-lens/docs/pi-lens-warden.md +18 -7
- package/node_modules/pi-lens/docs/public-api-stability.md +55 -0
- package/node_modules/pi-lens/docs/release-qa-baseline.md +84 -17
- package/node_modules/pi-lens/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
- package/node_modules/pi-lens/docs/servercapabilities.md +53 -49
- package/node_modules/pi-lens/docs/settings.md +1 -0
- package/node_modules/pi-lens/docs/usage.md +5 -1
- package/node_modules/pi-lens/grammars/tree-sitter-bash.wasm +0 -0
- package/node_modules/pi-lens/grammars/tree-sitter-bash.wasm.json +3 -3
- package/node_modules/pi-lens/package.json +18 -6
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +1275 -62
- package/node_modules/pi-lens/scripts/download-grammars.js +5 -0
- package/node_modules/pi-lens/scripts/grammars.lock.json +6 -1
- package/node_modules/pi-lens/scripts/install-selftest.mjs +33 -34
- package/node_modules/pi-lens/scripts/lib/host-provided-deps.mjs +13 -4
- package/node_modules/pi-lens/scripts/lib/web-tree-sitter-dir.mjs +18 -0
- package/node_modules/pi-typesafe/README.md +1 -1
- package/node_modules/pi-typesafe/dist/backends.d.ts +15 -5
- package/node_modules/pi-typesafe/dist/backends.js +18 -0
- package/node_modules/pi-typesafe/dist/client.d.ts +4 -3
- package/node_modules/pi-typesafe/dist/client.js +22 -7
- package/node_modules/pi-typesafe/dist/index.d.ts +2 -2
- package/node_modules/pi-typesafe/dist/index.js +1 -1
- package/node_modules/pi-typesafe/dist/usage.d.ts +14 -4
- package/node_modules/pi-typesafe/dist/usage.js +147 -42
- package/node_modules/pi-typesafe/package.json +1 -1
- package/node_modules/pi-web-access/CHANGELOG.md +48 -0
- package/node_modules/pi-web-access/README.md +57 -11
- package/node_modules/pi-web-access/brave-rate-limit.ts +8 -2
- package/node_modules/pi-web-access/curator-page.ts +5 -1
- package/node_modules/pi-web-access/curator-server.ts +2 -0
- package/node_modules/pi-web-access/declared-web-links.ts +2 -2
- package/node_modules/pi-web-access/degoog.ts +323 -0
- package/node_modules/pi-web-access/dist/index.js +3483 -2745
- package/node_modules/pi-web-access/dist/mcp-cli.js +27443 -0
- package/node_modules/pi-web-access/exa.ts +5 -1
- package/node_modules/pi-web-access/extract.ts +41 -3
- package/node_modules/pi-web-access/firecrawl.ts +35 -4
- package/node_modules/pi-web-access/gemini-search.ts +34 -11
- package/node_modules/pi-web-access/gemini-web.ts +14 -9
- package/node_modules/pi-web-access/index.ts +153 -1202
- package/node_modules/pi-web-access/keenable.ts +221 -0
- package/node_modules/pi-web-access/mcp-cli.ts +40 -0
- package/node_modules/pi-web-access/mcp-server.ts +81 -0
- package/node_modules/pi-web-access/mcp-tool-definitions.ts +117 -0
- package/node_modules/pi-web-access/openai-search.ts +34 -1
- package/node_modules/pi-web-access/package.json +23 -5
- package/node_modules/pi-web-access/perplexity.ts +64 -56
- package/node_modules/pi-web-access/tool-arguments.ts +20 -0
- package/node_modules/pi-web-access/video-extract.ts +1 -1
- package/node_modules/pi-web-access/web-tool-contract.ts +86 -0
- package/node_modules/pi-web-access/web-tool-core.ts +1502 -0
- package/node_modules/pi-web-access/youtube-extract.ts +2 -5
- package/package.json +17 -12
- package/node_modules/@dietrichgebert/ponytail/README.es.md +0 -329
- package/node_modules/@dietrichgebert/ponytail/README.ko.md +0 -346
- package/node_modules/@dietrichgebert/ponytail/assets/benchmark-3model.svg +0 -21
- package/node_modules/@dietrichgebert/ponytail/assets/benchmark-agentic.svg +0 -62
- package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.svg +0 -115
- package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt-dark.svg +0 -27
- package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt.svg +0 -27
- package/node_modules/@dietrichgebert/ponytail/assets/logo.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/retriever-icon.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/retriever-logo-dark.svg +0 -4
- package/node_modules/@dietrichgebert/ponytail/assets/retriever-logo-light.svg +0 -4
- package/node_modules/@dietrichgebert/ponytail/assets/social-preview.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-es.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-ko.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner.png +0 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +0 -35
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +0 -1610
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +0 -593
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +0 -147
- package/node_modules/pi-lens/dist/clients/agent-nudge.js +0 -325
- package/node_modules/pi-lens/dist/clients/analysed-root.js +0 -1
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +0 -731
- package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +0 -146
- package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +0 -118
- package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -10
- package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +0 -154
- package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +0 -75
- package/node_modules/pi-lens/dist/clients/atomic-write.js +0 -189
- package/node_modules/pi-lens/dist/clients/availability-probe-flight.js +0 -12
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +0 -1056
- package/node_modules/pi-lens/dist/clients/biome-client.js +0 -357
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +0 -837
- package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +0 -129
- package/node_modules/pi-lens/dist/clients/bootstrap.js +0 -569
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +0 -190
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +0 -202
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +0 -295
- package/node_modules/pi-lens/dist/clients/build-identity.js +0 -95
- package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +0 -113
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +0 -105
- package/node_modules/pi-lens/dist/clients/bus-publish.js +0 -171
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +0 -190
- package/node_modules/pi-lens/dist/clients/cache-manager.js +0 -524
- package/node_modules/pi-lens/dist/clients/cache-observability.js +0 -1313
- package/node_modules/pi-lens/dist/clients/call-graph.js +0 -852
- package/node_modules/pi-lens/dist/clients/cargo-manifest.js +0 -422
- package/node_modules/pi-lens/dist/clients/cascade-budget.js +0 -196
- package/node_modules/pi-lens/dist/clients/cascade-format.js +0 -315
- package/node_modules/pi-lens/dist/clients/cascade-logger.js +0 -31
- package/node_modules/pi-lens/dist/clients/cascade-types.js +0 -9
- package/node_modules/pi-lens/dist/clients/child-unref.js +0 -124
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +0 -286
- package/node_modules/pi-lens/dist/clients/codebase-model.js +0 -173
- package/node_modules/pi-lens/dist/clients/collateral-test-role.js +0 -40
- package/node_modules/pi-lens/dist/clients/complexity-client.js +0 -462
- package/node_modules/pi-lens/dist/clients/config-core/deny.js +0 -221
- package/node_modules/pi-lens/dist/clients/config-core/index.js +0 -50
- package/node_modules/pi-lens/dist/clients/config-core/merge.js +0 -357
- package/node_modules/pi-lens/dist/clients/config-core/normalize.js +0 -340
- package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +0 -248
- package/node_modules/pi-lens/dist/clients/config-core/provenance.js +0 -164
- package/node_modules/pi-lens/dist/clients/config-core/records.js +0 -218
- package/node_modules/pi-lens/dist/clients/config-core/resolve.js +0 -125
- package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +0 -78
- package/node_modules/pi-lens/dist/clients/config-core/schema.js +0 -165
- package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +0 -285
- package/node_modules/pi-lens/dist/clients/config-locations.js +0 -388
- package/node_modules/pi-lens/dist/clients/config-resolve.js +0 -798
- package/node_modules/pi-lens/dist/clients/config-schema.js +0 -251
- package/node_modules/pi-lens/dist/clients/config-warn.js +0 -407
- package/node_modules/pi-lens/dist/clients/console-guard-install.js +0 -26
- package/node_modules/pi-lens/dist/clients/cooperative-budget.js +0 -42
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +0 -510
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +0 -30
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +0 -280
- package/node_modules/pi-lens/dist/clients/debug-handles.js +0 -211
- package/node_modules/pi-lens/dist/clients/debug-heap.js +0 -174
- package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +0 -106
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +0 -426
- package/node_modules/pi-lens/dist/clients/demoted-finding-render.js +0 -169
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +0 -885
- package/node_modules/pi-lens/dist/clients/deps/ast-grep-napi.js +0 -22
- package/node_modules/pi-lens/dist/clients/deps/js-yaml.js +0 -9
- package/node_modules/pi-lens/dist/clients/deps/minimatch.js +0 -4
- package/node_modules/pi-lens/dist/clients/deps/pi-tui.js +0 -14
- package/node_modules/pi-lens/dist/clients/deps/typebox.js +0 -14
- package/node_modules/pi-lens/dist/clients/deps/vscode-jsonrpc.js +0 -1
- package/node_modules/pi-lens/dist/clients/deps/web-tree-sitter.js +0 -24
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +0 -630
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +0 -305
- package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +0 -73
- package/node_modules/pi-lens/dist/clients/diagnostic-tracker.js +0 -105
- package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +0 -230
- package/node_modules/pi-lens/dist/clients/dispatch/ast-grep-catalog.js +0 -65
- package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +0 -343
- package/node_modules/pi-lens/dist/clients/dispatch/collect-later-tier.js +0 -35
- package/node_modules/pi-lens/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +0 -1269
- package/node_modules/pi-lens/dist/clients/dispatch/fact-provider-types.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/fact-rule-runner.js +0 -17
- package/node_modules/pi-lens/dist/clients/dispatch/fact-runner.js +0 -30
- package/node_modules/pi-lens/dist/clients/dispatch/fact-scheduler.js +0 -68
- package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +0 -377
- package/node_modules/pi-lens/dist/clients/dispatch/facts/comment-facts.js +0 -22
- package/node_modules/pi-lens/dist/clients/dispatch/facts/file-content.js +0 -19
- package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +0 -348
- package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +0 -204
- package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
- package/node_modules/pi-lens/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
- package/node_modules/pi-lens/dist/clients/dispatch/finding-policy.js +0 -339
- package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +0 -417
- package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +0 -89
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +0 -2377
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +0 -11
- package/node_modules/pi-lens/dist/clients/dispatch/pending-runner-findings.js +0 -87
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +0 -278
- package/node_modules/pi-lens/dist/clients/dispatch/priorities.js +0 -20
- package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +0 -50
- package/node_modules/pi-lens/dist/clients/dispatch/rule-ignores.js +0 -69
- package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +0 -135
- package/node_modules/pi-lens/dist/clients/dispatch/rules/async-noise.js +0 -40
- package/node_modules/pi-lens/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
- package/node_modules/pi-lens/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
- package/node_modules/pi-lens/dist/clients/dispatch/rules/error-obscuring.js +0 -32
- package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +0 -31
- package/node_modules/pi-lens/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
- package/node_modules/pi-lens/dist/clients/dispatch/rules/high-complexity.js +0 -72
- package/node_modules/pi-lens/dist/clients/dispatch/rules/high-fan-out.js +0 -74
- package/node_modules/pi-lens/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
- package/node_modules/pi-lens/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
- package/node_modules/pi-lens/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
- package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
- package/node_modules/pi-lens/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
- package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
- package/node_modules/pi-lens/dist/clients/dispatch/runner-context.js +0 -52
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -111
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -296
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +0 -219
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -82
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -416
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -183
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -176
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -164
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -195
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -137
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -29
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -69
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -167
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +0 -104
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -135
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -91
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -171
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +0 -940
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -117
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +0 -108
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -99
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -110
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -379
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -167
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -102
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +0 -414
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -85
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -120
- package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -62
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +0 -169
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -99
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +0 -88
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +0 -256
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +0 -173
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -102
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +0 -128
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -259
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -183
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -166
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -163
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -174
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -168
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -125
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -643
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -253
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -95
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils.js +0 -15
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -128
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +0 -95
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -79
- package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +0 -79
- package/node_modules/pi-lens/dist/clients/dispatch/tool-profile.js +0 -30
- package/node_modules/pi-lens/dist/clients/dispatch/types.js +0 -21
- package/node_modules/pi-lens/dist/clients/dispatch/utils/format-utils.js +0 -45
- package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
- package/node_modules/pi-lens/dist/clients/disposition-logger.js +0 -32
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +0 -124
- package/node_modules/pi-lens/dist/clients/durable-store.js +0 -97
- package/node_modules/pi-lens/dist/clients/effective-config.js +0 -415
- package/node_modules/pi-lens/dist/clients/env-utils.js +0 -83
- package/node_modules/pi-lens/dist/clients/error-class.js +0 -23
- package/node_modules/pi-lens/dist/clients/eval-timestamp.js +0 -17
- package/node_modules/pi-lens/dist/clients/event-loop-hold.js +0 -274
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +0 -250
- package/node_modules/pi-lens/dist/clients/extension-log.js +0 -504
- package/node_modules/pi-lens/dist/clients/extension-mode.js +0 -73
- package/node_modules/pi-lens/dist/clients/feature-hints.js +0 -103
- package/node_modules/pi-lens/dist/clients/file-kinds.js +0 -412
- package/node_modules/pi-lens/dist/clients/file-role.js +0 -134
- package/node_modules/pi-lens/dist/clients/file-time.js +0 -160
- package/node_modules/pi-lens/dist/clients/file-utils.js +0 -1032
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +0 -494
- package/node_modules/pi-lens/dist/clients/finding-identity.js +0 -88
- package/node_modules/pi-lens/dist/clients/fix-worklog.js +0 -103
- package/node_modules/pi-lens/dist/clients/format-events-publish.js +0 -343
- package/node_modules/pi-lens/dist/clients/format-service.js +0 -222
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +0 -9
- package/node_modules/pi-lens/dist/clients/formatters.js +0 -2032
- package/node_modules/pi-lens/dist/clients/freshness-cadence.js +0 -17
- package/node_modules/pi-lens/dist/clients/freshness.js +0 -38
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +0 -394
- package/node_modules/pi-lens/dist/clients/generation-guard.js +0 -215
- package/node_modules/pi-lens/dist/clients/git-guard.js +0 -1136
- package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +0 -243
- package/node_modules/pi-lens/dist/clients/gitleaks-client.js +0 -509
- package/node_modules/pi-lens/dist/clients/go-client.js +0 -104
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +0 -605
- package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +0 -348
- package/node_modules/pi-lens/dist/clients/grammar-source.js +0 -465
- package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +0 -135
- package/node_modules/pi-lens/dist/clients/hashline-anchor.js +0 -424
- package/node_modules/pi-lens/dist/clients/hook-budgets.js +0 -76
- package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +0 -140
- package/node_modules/pi-lens/dist/clients/host-ports.js +0 -39
- package/node_modules/pi-lens/dist/clients/indent-retarget.js +0 -154
- package/node_modules/pi-lens/dist/clients/inline-blocker-dispositions.js +0 -186
- package/node_modules/pi-lens/dist/clients/install-diagnostics.js +0 -156
- package/node_modules/pi-lens/dist/clients/installer/index.js +0 -5416
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +0 -58
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +0 -783
- package/node_modules/pi-lens/dist/clients/instance-reaper-state.js +0 -7
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +0 -1137
- package/node_modules/pi-lens/dist/clients/instance-registry-lock.js +0 -145
- package/node_modules/pi-lens/dist/clients/instance-registry.js +0 -773
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +0 -378
- package/node_modules/pi-lens/dist/clients/json-cache-read.js +0 -65
- package/node_modules/pi-lens/dist/clients/knip-client.js +0 -788
- package/node_modules/pi-lens/dist/clients/language-policy.js +0 -252
- package/node_modules/pi-lens/dist/clients/language-profile.js +0 -361
- package/node_modules/pi-lens/dist/clients/language-registry.js +0 -603
- package/node_modules/pi-lens/dist/clients/latency-logger.js +0 -727
- package/node_modules/pi-lens/dist/clients/lazy-import.js +0 -21
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +0 -54
- package/node_modules/pi-lens/dist/clients/lens-config.js +0 -404
- package/node_modules/pi-lens/dist/clients/lens-engine.js +0 -358
- package/node_modules/pi-lens/dist/clients/lens-events.js +0 -125
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +0 -467
- package/node_modules/pi-lens/dist/clients/lens-map.js +0 -1156
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +0 -74
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +0 -222
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +0 -178
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +0 -421
- package/node_modules/pi-lens/dist/clients/lsp/client.js +0 -4593
- package/node_modules/pi-lens/dist/clients/lsp/config.js +0 -691
- package/node_modules/pi-lens/dist/clients/lsp/content-limits.js +0 -41
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +0 -225
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +0 -467
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +0 -1219
- package/node_modules/pi-lens/dist/clients/lsp/index.js +0 -8305
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +0 -216
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +0 -298
- package/node_modules/pi-lens/dist/clients/lsp/language.js +0 -63
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +0 -746
- package/node_modules/pi-lens/dist/clients/lsp/lombok.js +0 -158
- package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +0 -5
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +0 -251
- package/node_modules/pi-lens/dist/clients/lsp/position-encoding.js +0 -61
- package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +0 -83
- package/node_modules/pi-lens/dist/clients/lsp/server.js +0 -3290
- package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +0 -192
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +0 -17
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +0 -56
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +0 -332
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +0 -85
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/index.js +0 -10
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +0 -392
- package/node_modules/pi-lens/dist/clients/lsp/watch-queue.js +0 -61
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
- package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +0 -184
- package/node_modules/pi-lens/dist/clients/lsp-budget.js +0 -186
- package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +0 -110
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +0 -9
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +0 -396
- package/node_modules/pi-lens/dist/clients/lsp-status.js +0 -59
- package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +0 -40
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +0 -420
- package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +0 -31
- package/node_modules/pi-lens/dist/clients/mcp/ipc.js +0 -523
- package/node_modules/pi-lens/dist/clients/mcp/review.js +0 -197
- package/node_modules/pi-lens/dist/clients/mcp/session.js +0 -412
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +0 -208
- package/node_modules/pi-lens/dist/clients/message-end-attribution.js +0 -30
- package/node_modules/pi-lens/dist/clients/metrics-client.js +0 -107
- package/node_modules/pi-lens/dist/clients/metrics-history.js +0 -327
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +0 -263
- package/node_modules/pi-lens/dist/clients/model-provider.js +0 -53
- package/node_modules/pi-lens/dist/clients/module-report-lsp.js +0 -189
- package/node_modules/pi-lens/dist/clients/module-report.js +0 -2150
- package/node_modules/pi-lens/dist/clients/mutating-tool.js +0 -651
- package/node_modules/pi-lens/dist/clients/mutation-attribution.js +0 -368
- package/node_modules/pi-lens/dist/clients/mutation-bridge.js +0 -240
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +0 -734
- package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +0 -101
- package/node_modules/pi-lens/dist/clients/observed-mutation.js +0 -1253
- package/node_modules/pi-lens/dist/clients/oldtext-autopatch.js +0 -128
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +0 -496
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +0 -333
- package/node_modules/pi-lens/dist/clients/opengrep-config.js +0 -76
- package/node_modules/pi-lens/dist/clients/package-manager.js +0 -607
- package/node_modules/pi-lens/dist/clients/package-root.js +0 -38
- package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +0 -439
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +0 -43
- package/node_modules/pi-lens/dist/clients/path-keyed-map.js +0 -108
- package/node_modules/pi-lens/dist/clients/path-utils.js +0 -1244
- package/node_modules/pi-lens/dist/clients/performance-report.js +0 -331
- package/node_modules/pi-lens/dist/clients/persist-debounce.js +0 -70
- package/node_modules/pi-lens/dist/clients/persistent-reverify.js +0 -271
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +0 -119
- package/node_modules/pi-lens/dist/clients/pipeline.js +0 -1480
- package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +0 -37
- package/node_modules/pi-lens/dist/clients/print-mode.js +0 -21
- package/node_modules/pi-lens/dist/clients/probe-home-state.js +0 -228
- package/node_modules/pi-lens/dist/clients/process-bridge.js +0 -66
- package/node_modules/pi-lens/dist/clients/process-singletons.js +0 -210
- package/node_modules/pi-lens/dist/clients/process-snapshot.js +0 -68
- package/node_modules/pi-lens/dist/clients/project-changes.js +0 -181
- package/node_modules/pi-lens/dist/clients/project-conventions.js +0 -171
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +0 -137
- package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +0 -109
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +0 -668
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +0 -520
- package/node_modules/pi-lens/dist/clients/project-diagnostics/types.js +0 -1
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +0 -807
- package/node_modules/pi-lens/dist/clients/project-report.js +0 -701
- package/node_modules/pi-lens/dist/clients/project-scale.js +0 -237
- package/node_modules/pi-lens/dist/clients/project-scan-policy.js +0 -11
- package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +0 -48
- package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +0 -20
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +0 -1653
- package/node_modules/pi-lens/dist/clients/project-trust.js +0 -181
- package/node_modules/pi-lens/dist/clients/python-environment.js +0 -217
- package/node_modules/pi-lens/dist/clients/python-provenance.js +0 -639
- package/node_modules/pi-lens/dist/clients/quiet-window-config.js +0 -47
- package/node_modules/pi-lens/dist/clients/quiet-window.js +0 -236
- package/node_modules/pi-lens/dist/clients/read-bridge.js +0 -139
- package/node_modules/pi-lens/dist/clients/read-expansion.js +0 -266
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +0 -251
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +0 -1306
- package/node_modules/pi-lens/dist/clients/read-guard.js +0 -1561
- package/node_modules/pi-lens/dist/clients/recent-touches.js +0 -240
- package/node_modules/pi-lens/dist/clients/redact/secrets.js +0 -449
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +0 -628
- package/node_modules/pi-lens/dist/clients/reverse-deps.js +0 -270
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +0 -5126
- package/node_modules/pi-lens/dist/clients/review-graph/format.js +0 -33
- package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +0 -163
- package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +0 -481
- package/node_modules/pi-lens/dist/clients/review-graph/persist-worker.js +0 -10
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +0 -244
- package/node_modules/pi-lens/dist/clients/review-graph/revision-drift.js +0 -21
- package/node_modules/pi-lens/dist/clients/review-graph/service.js +0 -96
- package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +0 -82
- package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +0 -103
- package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +0 -299
- package/node_modules/pi-lens/dist/clients/review-graph/types.js +0 -1
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +0 -449
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +0 -81
- package/node_modules/pi-lens/dist/clients/ruff-client.js +0 -179
- package/node_modules/pi-lens/dist/clients/rules-scanner.js +0 -131
- package/node_modules/pi-lens/dist/clients/run-duration.js +0 -55
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +0 -746
- package/node_modules/pi-lens/dist/clients/runtime-config.js +0 -77
- package/node_modules/pi-lens/dist/clients/runtime-context.js +0 -211
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +0 -1324
- package/node_modules/pi-lens/dist/clients/runtime-session.js +0 -2485
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +0 -1295
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +0 -2049
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +0 -3767
- package/node_modules/pi-lens/dist/clients/rust-client.js +0 -97
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +0 -2357
- package/node_modules/pi-lens/dist/clients/sanitize.js +0 -286
- package/node_modules/pi-lens/dist/clients/scan-utils.js +0 -25
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +0 -165
- package/node_modules/pi-lens/dist/clients/search-read-registration.js +0 -94
- package/node_modules/pi-lens/dist/clients/secret-findings.js +0 -114
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +0 -352
- package/node_modules/pi-lens/dist/clients/session-event-guard.js +0 -297
- package/node_modules/pi-lens/dist/clients/session-lifecycle.js +0 -484
- package/node_modules/pi-lens/dist/clients/session-start-observability.js +0 -94
- package/node_modules/pi-lens/dist/clients/session-state-store.js +0 -101
- package/node_modules/pi-lens/dist/clients/session-summary.js +0 -15
- package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +0 -27
- package/node_modules/pi-lens/dist/clients/sg-runner.js +0 -876
- package/node_modules/pi-lens/dist/clients/sgconfig.js +0 -347
- package/node_modules/pi-lens/dist/clients/shared-checkout-guard.js +0 -338
- package/node_modules/pi-lens/dist/clients/single-flight.js +0 -158
- package/node_modules/pi-lens/dist/clients/situational-tool-telemetry.js +0 -108
- package/node_modules/pi-lens/dist/clients/skills-resolver.js +0 -141
- package/node_modules/pi-lens/dist/clients/slow-fs.js +0 -138
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +0 -231
- package/node_modules/pi-lens/dist/clients/source-filter.js +0 -596
- package/node_modules/pi-lens/dist/clients/source-walker.js +0 -211
- package/node_modules/pi-lens/dist/clients/spawn-output-cap.js +0 -120
- package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +0 -110
- package/node_modules/pi-lens/dist/clients/stale-marker.js +0 -17
- package/node_modules/pi-lens/dist/clients/startup-scan.js +0 -400
- package/node_modules/pi-lens/dist/clients/startup-timing.js +0 -130
- package/node_modules/pi-lens/dist/clients/string-utils.js +0 -33
- package/node_modules/pi-lens/dist/clients/subagent-mode.js +0 -111
- package/node_modules/pi-lens/dist/clients/symbol-containment.js +0 -24
- package/node_modules/pi-lens/dist/clients/symbol-types.js +0 -5
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +0 -2507
- package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +0 -287
- package/node_modules/pi-lens/dist/clients/todo-scanner.js +0 -229
- package/node_modules/pi-lens/dist/clients/tool-agreement.js +0 -423
- package/node_modules/pi-lens/dist/clients/tool-config.js +0 -249
- package/node_modules/pi-lens/dist/clients/tool-cwd.js +0 -270
- package/node_modules/pi-lens/dist/clients/tool-definition.js +0 -47
- package/node_modules/pi-lens/dist/clients/tool-event.js +0 -105
- package/node_modules/pi-lens/dist/clients/tool-policy.js +0 -2755
- package/node_modules/pi-lens/dist/clients/tool-probe.js +0 -53
- package/node_modules/pi-lens/dist/clients/tool-render.js +0 -156
- package/node_modules/pi-lens/dist/clients/tool-set-policy.js +0 -118
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +0 -364
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +0 -4195
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +0 -100
- package/node_modules/pi-lens/dist/clients/tree-sitter-navigator.js +0 -269
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +0 -569
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +0 -158
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
- package/node_modules/pi-lens/dist/clients/trivy-client.js +0 -467
- package/node_modules/pi-lens/dist/clients/tui-fit.js +0 -50
- package/node_modules/pi-lens/dist/clients/turn-context.js +0 -52
- package/node_modules/pi-lens/dist/clients/turn-end/lane.js +0 -51
- package/node_modules/pi-lens/dist/clients/turn-end/lanes/govulncheck.js +0 -112
- package/node_modules/pi-lens/dist/clients/turn-end/lanes/secrets.js +0 -204
- package/node_modules/pi-lens/dist/clients/turn-summary-render.js +0 -72
- package/node_modules/pi-lens/dist/clients/turn-summary.js +0 -132
- package/node_modules/pi-lens/dist/clients/typos-config.js +0 -29
- package/node_modules/pi-lens/dist/clients/user-notify.js +0 -51
- package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +0 -57
- package/node_modules/pi-lens/dist/clients/warm-attach.js +0 -305
- package/node_modules/pi-lens/dist/clients/widget-state.js +0 -1808
- package/node_modules/pi-lens/dist/clients/word-index-logger.js +0 -49
- package/node_modules/pi-lens/dist/clients/word-index-store.js +0 -459
- package/node_modules/pi-lens/dist/clients/word-index.js +0 -2080
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +0 -443
- package/node_modules/pi-lens/dist/clients/write-ordering-guard.js +0 -65
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +0 -340
- package/node_modules/pi-lens/dist/i18n.js +0 -69
- package/node_modules/pi-lens/dist/mcp/build-staleness.js +0 -124
- package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +0 -583
- package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +0 -129
- package/node_modules/pi-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -123
- package/node_modules/pi-lens/dist/tools/activate-tools.js +0 -87
- package/node_modules/pi-lens/dist/tools/ast-grep-outline.js +0 -137
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +0 -244
- package/node_modules/pi-lens/dist/tools/ast-grep-search.js +0 -762
- package/node_modules/pi-lens/dist/tools/effective-config.js +0 -90
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +0 -375
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +0 -2571
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +0 -1745
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +0 -1367
- package/node_modules/pi-lens/dist/tools/lsp-structured-output.js +0 -294
- package/node_modules/pi-lens/dist/tools/module-report.js +0 -382
- package/node_modules/pi-lens/dist/tools/project-report.js +0 -86
- package/node_modules/pi-lens/dist/tools/render-compact.js +0 -374
- package/node_modules/pi-lens/dist/tools/scan-progress.js +0 -53
- package/node_modules/pi-lens/dist/tools/shared.js +0 -29
- package/node_modules/pi-lens/dist/tools/symbol-search.js +0 -155
|
@@ -1,837 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Turn-boundary freshness gate for cached inline blockers (#1631).
|
|
3
|
-
*
|
|
4
|
-
* An inline blocker recorded for a file F is a verdict about F *and everything F
|
|
5
|
-
* imports*. The existing invalidation paths all key on F alone — a later dispatch
|
|
6
|
-
* of the SAME path returning no blockers, the path ceasing to exist (#1245), and a
|
|
7
|
-
* fresh confirmed-clean verdict (#1561/#1573). When only a DEPENDENCY of F changes,
|
|
8
|
-
* none of those events fire, so F's stale verdict re-served at every turn end for
|
|
9
|
-
* the rest of the session. The live instances in #1631 are exactly that shape: the
|
|
10
|
-
* missing export was added to the dependency (one via a bash script, so the
|
|
11
|
-
* dependency was never dispatched at all — even the same-path event was unreachable
|
|
12
|
-
* by construction).
|
|
13
|
-
*
|
|
14
|
-
* The gate here is a READ-time freshness sweep, not the #1561 dependency-axis
|
|
15
|
-
* invalidation (which stays blocked on a maintainer design decision). Before a cached
|
|
16
|
-
* blocking finding is re-served at turn end, stat the file and its forward imports.
|
|
17
|
-
* The file's own import list comes from the parse layer — no reverse-dependency index
|
|
18
|
-
* is needed, sidestepping the tests-free-index blocker that holds #1561's remainder.
|
|
19
|
-
*
|
|
20
|
-
* Drifted entries are DEMOTED, not dropped (#1419 precedent, as applied by sibling
|
|
21
|
-
* issue #1622): a surviving file whose content drifted gets re-served with a
|
|
22
|
-
* `[stale — re-run to confirm]` marker and out of the authoritative blocker channel,
|
|
23
|
-
* rather than being silently deleted or re-asserted at full authority. The gate never
|
|
24
|
-
* re-pulls LSP verdicts on its own — a drifted entry is marked stale and left for an
|
|
25
|
-
* explicit re-run or the next dispatch to resolve. That keeps the sweep bounded and
|
|
26
|
-
* free of the document-resync hazard the issue calls out (re-querying an LSP whose
|
|
27
|
-
* in-memory dependency document is itself stale would regenerate the stale verdict).
|
|
28
|
-
*
|
|
29
|
-
* Scope (#1631 review F4): an inline blocker is not always LSP-only —
|
|
30
|
-
* `dispatcher.ts` builds it from every `semantic === "blocking"` diagnostic across
|
|
31
|
-
* all runners, so an eslint, biome-check, or ast-grep security-rule (hardcoded
|
|
32
|
-
* secret, CVE) finding can land here too. Only a language-server verdict is
|
|
33
|
-
* actually invalidated by an IMPORT changing; an ast-grep secret match doesn't stop
|
|
34
|
-
* being true because a file it imports was edited.
|
|
35
|
-
*
|
|
36
|
-
* Self-drift axis (#1561 remainder). That reasoning covers the import axis and
|
|
37
|
-
* nothing else, but the original gate discarded BOTH axes for a non-LSP record:
|
|
38
|
-
* entries whose `sources` were not all `"lsp"` skipped the check entirely. A
|
|
39
|
-
* tree-sitter verdict about F's own syntax is emphatically invalidated by F's own
|
|
40
|
-
* bytes changing, and no other path could clear it —
|
|
41
|
-
* `retireInlineBlockerOnConfirmedClean` requires `coveredSources` to be a superset
|
|
42
|
-
* of the record's sources, `coveredSourcesForCheck` builds that set from the LSP
|
|
43
|
-
* server registry, and no registered server has id `"tree-sitter"`, so the retire
|
|
44
|
-
* could never fire however many clean checks ran. Live shape: a
|
|
45
|
-
* `ts-incomplete-assertion` blocker re-served every turn for the rest of a session
|
|
46
|
-
* against a file already proven clean by grep, LSP, and a passing test.
|
|
47
|
-
*
|
|
48
|
-
* So the sweep now runs over every entry that HAS recorded provenance, and picks
|
|
49
|
-
* the axis from the sources: all-`"lsp"` gets the own-file-plus-forward-imports
|
|
50
|
-
* walk, anything else (tree-sitter, ast-grep, mixed, or `"unknown"`) gets an
|
|
51
|
-
* own-file-only check. A record with NO recorded sources stays fail-closed and
|
|
52
|
-
* untouched, matching the test `retireInlineBlockerOnConfirmedClean` applies before
|
|
53
|
-
* it will retire.
|
|
54
|
-
*
|
|
55
|
-
* The self axis is CONTENT-CONFIRMED and RE-ARMING, and those two properties are
|
|
56
|
-
* why it carries its own `"self-drift"` reason rather than reusing
|
|
57
|
-
* `"dependency-drift"` (#2982 review).
|
|
58
|
-
*
|
|
59
|
-
* Content-confirmed: mtime moving is not evidence a byte moved. A `touch`, a
|
|
60
|
-
* `git checkout` restoring identical bytes, or a no-op formatter pass all move
|
|
61
|
-
* it. #2449 round 2 F7 settled this for `observed-mutation.ts` ("mtime-only
|
|
62
|
-
* drift has to be confirmed against content before anything is replayed"), and
|
|
63
|
-
* it binds harder here, where an unconfirmed demotion walks a finding out of the
|
|
64
|
-
* authoritative channel. `detectSelfDrift` applies that rule at both tiers:
|
|
65
|
-
* `size` first, then a sha256 of the bytes when size cannot separate a
|
|
66
|
-
* one-character edit from a `touch`. A same-LENGTH change is the common shape,
|
|
67
|
-
* not an exotic one (a renamed identifier of equal length, a flipped comparison,
|
|
68
|
-
* a changed digit), so a size-only tier would leave a genuinely changed record
|
|
69
|
-
* authoritative, which is #2982 arriving from the other side. The baseline is
|
|
70
|
-
* carried by `PipelineResult` beside the inline-blocker evidence and stamped
|
|
71
|
-
* synchronously by `recordInlineBlockers`. Every bound that expires, and every missing baseline, yields
|
|
72
|
-
* `unverifiable`, which changes no state in either direction and is counted so
|
|
73
|
-
* it is visible rather than silent.
|
|
74
|
-
*
|
|
75
|
-
* Re-arming: `setInlineBlockerSelfDriftStale` re-derives the verdict every turn
|
|
76
|
-
* and un-demotes a record whose bytes come back, exactly as
|
|
77
|
-
* `setInlineBlockerPastEofStale` does for a transient shrink-then-restore. That
|
|
78
|
-
* is what lets this axis stay OUT of the #1950 delivery cap. The cap retires a
|
|
79
|
-
* record permanently after `DEPENDENCY_DRIFT_MAX_DELIVERIES` stale deliveries,
|
|
80
|
-
* which suits recoverable LSP dependency drift; a self-drift record can carry
|
|
81
|
-
* ast-grep or tree-sitter security provenance, and retiring one because an
|
|
82
|
-
* advisory was shown three times would walk a hardcoded secret out of turn-end
|
|
83
|
-
* rendering with no dispatch to re-raise it. A record that heals on its own
|
|
84
|
-
* needs no bounded-noise retirement.
|
|
85
|
-
*
|
|
86
|
-
* Defect shape 24 is satisfied by composition, not by reusing a string: the new
|
|
87
|
-
* reason has per-writer semantics (re-arm, no cap), and like every sibling gate
|
|
88
|
-
* it never touches a demotion another gate made and never heals one it did not
|
|
89
|
-
* make. The commit gate is unaffected either way. `updateGitGuardStatus` counts
|
|
90
|
-
* `getInlineBlockersSnapshot().length` with no `stale` filter, so a demoted
|
|
91
|
-
* record still gates a commit; `tests/clients/blocker-freshness.test.ts` pins
|
|
92
|
-
* that, because it is what makes widening this sweep to security provenance
|
|
93
|
-
* safe at all.
|
|
94
|
-
*
|
|
95
|
-
* Resolution boundary (#1631 review F8): `extractForwardImportPaths` parses static
|
|
96
|
-
* import/require syntax via tree-sitter. It does not, and cannot, resolve a
|
|
97
|
-
* dependency reached only through a dynamic `import()` or `require()` behind a
|
|
98
|
-
* runtime condition — that edge is invisible to this gate, so a blocker whose only
|
|
99
|
-
* stale dependency arrives that way survives a replay. This is an honest boundary,
|
|
100
|
-
* not a silently-closed one.
|
|
101
|
-
*
|
|
102
|
-
* Delivery cap (#1950). A demoted-but-confirmable entry (`alreadyStale` above)
|
|
103
|
-
* is deliberately NOT retired after its past-EOF sibling's one-delivery rule
|
|
104
|
-
* (#1944, `blocker-past-eof.ts`) — its coordinates are still in bounds, so a
|
|
105
|
-
* fresh dispatch can genuinely confirm or clear it, and retiring on delivery
|
|
106
|
-
* one would discard a recoverable finding. But nothing capped how many times
|
|
107
|
-
* the SAME demoted record re-serves: incident data (#1944's lane sweep) showed
|
|
108
|
-
* 18 `alreadyStale` re-serves in one window, with repeat deliveries carrying
|
|
109
|
-
* near-zero information after the first. `runtime-turn.ts` counts each
|
|
110
|
-
* delivery (`InlineBlockerRecord.staleDeliveryCount`) and retires the record
|
|
111
|
-
* via `RuntimeCoordinator.retireDemotedDependencyDriftBlocker` once it reaches
|
|
112
|
-
* `DEPENDENCY_DRIFT_MAX_DELIVERIES` — a count, not a TTL or a session
|
|
113
|
-
* boundary, because "how many times has the agent already been told" is the
|
|
114
|
-
* quantity that actually went to zero information, not "how much time has
|
|
115
|
-
* passed". The ledger reason says "capped, re-run can still confirm" so it
|
|
116
|
-
* reads distinctly from #1944's "retired, unrecoverable" — a capped record
|
|
117
|
-
* COULD still resolve a fresh dispatch; it just stopped being handed one for
|
|
118
|
-
* free.
|
|
119
|
-
*
|
|
120
|
-
* Widget-footer sibling (#2275). The turn-end blocker channel above is not
|
|
121
|
-
* the only surface that demotes on dependency drift — `widget-state.ts`'s
|
|
122
|
-
* own `files` map carries the identical demotion shape
|
|
123
|
-
* (`markWidgetFileBlockersStale`) through a completely separate store, with
|
|
124
|
-
* its own `WidgetDiagnostic.staleDeliveryCount` and its own retire helpers
|
|
125
|
-
* (`incrementWidgetDependencyDriftDelivery`,
|
|
126
|
-
* `retireWidgetDependencyDriftBlockers`). It counts RENDERS rather than
|
|
127
|
-
* turn ends — the footer draws one record per pass, so `renderWidget` marks
|
|
128
|
-
* what it served and the turn-end step drains those marks — and it retires
|
|
129
|
-
* by HIDING the row from the footer rather than dropping the record, since
|
|
130
|
-
* the widget store also backs `lens_diagnostics mode=all`. What it shares
|
|
131
|
-
* with this module is the one number both caps retire against,
|
|
132
|
-
* `DEPENDENCY_DRIFT_MAX_DELIVERIES`, rather than inventing a second one.
|
|
133
|
-
*/
|
|
134
|
-
import { createHash } from "node:crypto";
|
|
135
|
-
import * as fs from "node:fs";
|
|
136
|
-
import { bounded } from "./deadline-utils.js";
|
|
137
|
-
import { recordDegradationOnce } from "./degradation-ledger.js";
|
|
138
|
-
import { HOOK_WALL_BUDGET_MS } from "./hook-budgets.js";
|
|
139
|
-
import { normalizeEphemeralMapKey } from "./path-utils.js";
|
|
140
|
-
import { toRunnerDisplayPath } from "./dispatch/runner-context.js";
|
|
141
|
-
import { resolveImportToFiles } from "./review-graph/import-resolvers.js";
|
|
142
|
-
import { getSharedTreeSitterClient, resolveTreeSitterLanguage, } from "./tree-sitter-shared.js";
|
|
143
|
-
import { TreeSitterSymbolExtractor } from "./tree-sitter-symbol-extractor.js";
|
|
144
|
-
/** See the module doc's "Delivery cap (#1950)" section above. */
|
|
145
|
-
export const DEPENDENCY_DRIFT_MAX_DELIVERIES = 3;
|
|
146
|
-
/**
|
|
147
|
-
* #2982: total bytes the self-drift axis may hash in ONE sweep.
|
|
148
|
-
*
|
|
149
|
-
* Each read is individually bounded by `bounded()`, but a turn with many
|
|
150
|
-
* non-LSP blockers would still issue many whole-file reads on a hook path, which
|
|
151
|
-
* is defect shape 9 (bounded on one axis, growing on another). Once a sweep has
|
|
152
|
-
* spent this budget the remaining same-size records are reported `unverifiable`
|
|
153
|
-
* and left exactly as they are, the same fail-closed direction as a read that
|
|
154
|
-
* times out.
|
|
155
|
-
*/
|
|
156
|
-
const SELF_DRIFT_HASH_BUDGET_BYTES = 8 * 1024 * 1024;
|
|
157
|
-
/**
|
|
158
|
-
* Upper bound on the number of forward imports stat-checked for a single blocker.
|
|
159
|
-
* Blocking entries are rare, but one file can import many modules; the sweep must
|
|
160
|
-
* stay bounded so it cannot inflate a turn end.
|
|
161
|
-
*/
|
|
162
|
-
const MAX_DRIFT_CHECK_IMPORTS = 128;
|
|
163
|
-
// Per-language extractor cache, mirroring review-graph/builder.ts and
|
|
164
|
-
// module-report.ts. Memoize failures too: a grammar that fails to load once is not
|
|
165
|
-
// re-probed for every blocker of that language within the process.
|
|
166
|
-
const extractorCache = new Map();
|
|
167
|
-
function getExtractor(languageId) {
|
|
168
|
-
let cached = extractorCache.get(languageId);
|
|
169
|
-
if (!cached) {
|
|
170
|
-
cached = (async () => {
|
|
171
|
-
const client = getSharedTreeSitterClient();
|
|
172
|
-
if (!client)
|
|
173
|
-
return null;
|
|
174
|
-
const extractor = new TreeSitterSymbolExtractor(languageId, client);
|
|
175
|
-
const ok = await extractor.init();
|
|
176
|
-
return ok ? extractor : null;
|
|
177
|
-
})().catch(() => null);
|
|
178
|
-
extractorCache.set(languageId, cached);
|
|
179
|
-
}
|
|
180
|
-
return cached;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* #1631 review F6: memoized forward-import RESOLUTION (the parse step, not the
|
|
184
|
-
* per-dependency mtime stats — those must always be read fresh so drift is never
|
|
185
|
-
* missed). Reviewer measurement: ~450ms/turn at 8 blockers × 300 imports
|
|
186
|
-
* unmemoized, ~435ms per `mode=all` call, because both the turn-end sweep and the
|
|
187
|
-
* `mode=all` gate independently re-parse the SAME consumer files' import lists.
|
|
188
|
-
*
|
|
189
|
-
* Keyed on (path, own mtime) — a cache hit is safe by construction: if the file's
|
|
190
|
-
* mtime hasn't moved, its parsed import LIST cannot have changed (the imports
|
|
191
|
-
* themselves may still have drifted; that's what the mtime stats after this cache
|
|
192
|
-
* check are for). Scoped PER TURN, not process-lifetime (the latch screen this
|
|
193
|
-
* class of state must pass): `noteImportResolutionMemoTurn` clears it whenever the
|
|
194
|
-
* `RuntimeCoordinator`'s `turnIndex` advances, so a resolver injected for one test
|
|
195
|
-
* or a project whose import graph is edited mid-session is never served a result
|
|
196
|
-
* from a stale earlier turn. When no turn index is available (mode=all called
|
|
197
|
-
* outside a tracked turn, or a test with no runtime), the cache is left alone —
|
|
198
|
-
* still correct because of the mtime key, just not turn-bounded in that case.
|
|
199
|
-
*/
|
|
200
|
-
const importResolutionMemo = new Map();
|
|
201
|
-
let importResolutionMemoTurnIndex;
|
|
202
|
-
function noteImportResolutionMemoTurn(turnIndex) {
|
|
203
|
-
if (turnIndex === undefined)
|
|
204
|
-
return;
|
|
205
|
-
if (importResolutionMemoTurnIndex !== turnIndex) {
|
|
206
|
-
importResolutionMemo.clear();
|
|
207
|
-
importResolutionMemoTurnIndex = turnIndex;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
async function resolveForwardImportsMemoized(cwd, filePath, resolveForwardImports) {
|
|
211
|
-
const sig = await statSignature(filePath);
|
|
212
|
-
if (sig === undefined) {
|
|
213
|
-
// Can't key reliably (deleted/unreadable) — resolve uncached rather than
|
|
214
|
-
// risk serving a memo entry for content that may no longer exist.
|
|
215
|
-
try {
|
|
216
|
-
return await resolveForwardImports(cwd, filePath);
|
|
217
|
-
}
|
|
218
|
-
catch {
|
|
219
|
-
return [];
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
const cached = importResolutionMemo.get(filePath);
|
|
223
|
-
// mtime alone collides for writes within the same timestamp tick (~1ms);
|
|
224
|
-
// size disambiguates the shrink-then-restore case (#1641's measurement).
|
|
225
|
-
if (cached && cached.mtimeMs === sig.mtimeMs && cached.size === sig.size)
|
|
226
|
-
return cached.imports;
|
|
227
|
-
let imports;
|
|
228
|
-
try {
|
|
229
|
-
imports = await resolveForwardImports(cwd, filePath);
|
|
230
|
-
}
|
|
231
|
-
catch {
|
|
232
|
-
imports = [];
|
|
233
|
-
}
|
|
234
|
-
importResolutionMemo.set(filePath, {
|
|
235
|
-
mtimeMs: sig.mtimeMs,
|
|
236
|
-
size: sig.size,
|
|
237
|
-
imports,
|
|
238
|
-
});
|
|
239
|
-
return imports;
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* Production forward-import resolver. Parses `filePath` with its tree-sitter grammar
|
|
243
|
-
* and resolves every extracted import source to in-project files. Degrades to an
|
|
244
|
-
* empty list (never throws) when the grammar, client, or file is unavailable — the
|
|
245
|
-
* sweep then falls back to checking only the blocker file's own drift.
|
|
246
|
-
*/
|
|
247
|
-
export async function extractForwardImportPaths(cwd, filePath) {
|
|
248
|
-
const languageId = resolveTreeSitterLanguage(filePath);
|
|
249
|
-
if (!languageId)
|
|
250
|
-
return [];
|
|
251
|
-
const client = getSharedTreeSitterClient();
|
|
252
|
-
if (!client)
|
|
253
|
-
return [];
|
|
254
|
-
const extractor = await getExtractor(languageId);
|
|
255
|
-
if (!extractor)
|
|
256
|
-
return [];
|
|
257
|
-
let content;
|
|
258
|
-
try {
|
|
259
|
-
content = fs.readFileSync(filePath, "utf-8");
|
|
260
|
-
}
|
|
261
|
-
catch {
|
|
262
|
-
return [];
|
|
263
|
-
}
|
|
264
|
-
const outcome = await client.withParsedTree(filePath, languageId, content, (tree) => extractor.extract(tree, filePath, content).imports);
|
|
265
|
-
if (!outcome.parsed)
|
|
266
|
-
return [];
|
|
267
|
-
const resolved = new Set();
|
|
268
|
-
for (const ref of outcome.value) {
|
|
269
|
-
for (const target of resolveImportToFiles(cwd, filePath, languageId, ref.source)) {
|
|
270
|
-
resolved.add(target);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
return [...resolved];
|
|
274
|
-
}
|
|
275
|
-
async function statSignature(filePath) {
|
|
276
|
-
try {
|
|
277
|
-
const stat = await fs.promises.stat(filePath);
|
|
278
|
-
return { mtimeMs: stat.mtimeMs, size: stat.size };
|
|
279
|
-
}
|
|
280
|
-
catch {
|
|
281
|
-
return undefined;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
async function statMtimeMs(filePath) {
|
|
285
|
-
try {
|
|
286
|
-
const stat = await fs.promises.stat(filePath);
|
|
287
|
-
return stat.mtimeMs;
|
|
288
|
-
}
|
|
289
|
-
catch {
|
|
290
|
-
return undefined;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Confirm a self-axis record against content, not mtime alone.
|
|
295
|
-
*
|
|
296
|
-
* mtime moving is not evidence that content changed: a `touch`, a `git
|
|
297
|
-
* checkout` restoring identical bytes, a no-op formatter pass, or a `chmod`
|
|
298
|
-
* all move it while every byte stays put. #2449 round 2 F7 settled this for
|
|
299
|
-
* `observed-mutation.ts` ("a `touch` bumps it without a byte moving, so
|
|
300
|
-
* mtime-only drift has to be confirmed against content before anything is
|
|
301
|
-
* replayed"), and the same reasoning governs here, where an unconfirmed
|
|
302
|
-
* demotion would walk a finding out of the authoritative channel.
|
|
303
|
-
*
|
|
304
|
-
* Three gates, in cost order. `size` decides most cases from the stat already
|
|
305
|
-
* taken, and it runs BEFORE the mtime gate: an out-of-band write (a formatter,
|
|
306
|
-
* a checkout) can land at-or-before the `recordedAtMs` baseline, so mtime alone
|
|
307
|
-
* is blind to the own-file drift this axis exists to catch — the size gate fires
|
|
308
|
-
* regardless of the mtime relationship. When the size matches, the mtime gate is
|
|
309
|
-
* a fast path that skips the expensive hash tier for non-LSP records (size same
|
|
310
|
-
* AND mtime never moved → the file almost certainly did not change, so we do
|
|
311
|
-
* not read and hash every unchanged file on the hook path). All-LSP records
|
|
312
|
-
* with an available hash baseline force the hash tier after the size check, so
|
|
313
|
-
* a same-size rewrite at-or-before the baseline cannot remain authoritative.
|
|
314
|
-
* When hashing is not forced and mtime moved, the hash separates a one-character
|
|
315
|
-
* edit from a `touch`, reading the bytes and comparing against the baseline
|
|
316
|
-
* `setInlineBlockerContentBaseline` attached off the dispatch path.
|
|
317
|
-
*
|
|
318
|
-
* Both tiers fail toward `"unverifiable"`, never toward `"drift"`: a bound that
|
|
319
|
-
* expires, a baseline that never landed, or a file past the per-sweep hash
|
|
320
|
-
* budget all leave the record exactly as it is. Demoting on a verdict the tier
|
|
321
|
-
* could not actually reach is the failure this function exists to prevent, and
|
|
322
|
-
* `bounded()` returning `undefined` on timeout makes that an easy mistake to
|
|
323
|
-
* write, so every bound's result is checked explicitly.
|
|
324
|
-
*/
|
|
325
|
-
async function detectSelfDrift(args) {
|
|
326
|
-
const boundOptions = (label) => ({
|
|
327
|
-
ms: HOOK_WALL_BUDGET_MS.turn_end,
|
|
328
|
-
signal: args.signal,
|
|
329
|
-
hook: "turn_end",
|
|
330
|
-
label,
|
|
331
|
-
});
|
|
332
|
-
// EVERY bound that expires yields `undefined`, and every one of those maps to
|
|
333
|
-
// `unverifiable`, never to drift. A timed-out stat compared against the
|
|
334
|
-
// recorded size would read as a size change and demote the record, which is
|
|
335
|
-
// the exact failure this tier exists to prevent.
|
|
336
|
-
const stat = await bounded(fs.promises.stat(args.filePath), boundOptions("selfDriftStat"));
|
|
337
|
-
if (stat === undefined)
|
|
338
|
-
return { verdict: "unverifiable", unverifiableReason: "stat-unavailable" };
|
|
339
|
-
// Size gate FIRST, before the mtime gate. mtime is a blind signal for the
|
|
340
|
-
// out-of-band-rewrite case: an external write (a formatter, a checkout) can
|
|
341
|
-
// land at-or-before the `recordedAtMs` baseline, so `freshnessFromMtime`
|
|
342
|
-
// reports the own file unchanged even though its bytes differ. Size is cheap
|
|
343
|
-
// content confirmation from the same stat, and it fires regardless of the
|
|
344
|
-
// mtime relationship — the all-LSP own-file case the mtime gate alone misses.
|
|
345
|
-
if (args.recordedSize === undefined)
|
|
346
|
-
return { verdict: "unverifiable", unverifiableReason: "missing-baseline" };
|
|
347
|
-
if (stat.size !== args.recordedSize)
|
|
348
|
-
return { verdict: "drift" };
|
|
349
|
-
// Size matches. Non-LSP records retain the mtime fast path. All-LSP records
|
|
350
|
-
// with a hash baseline force content confirmation because a same-size rewrite
|
|
351
|
-
// can land at-or-before the baseline.
|
|
352
|
-
const freshness = freshnessFromMtime({
|
|
353
|
-
mtimeMs: stat.mtimeMs,
|
|
354
|
-
referenceMs: args.recordedAtMs,
|
|
355
|
-
});
|
|
356
|
-
if (!args.forceContent && freshness.verdict !== "stale")
|
|
357
|
-
return { verdict: "unchanged" };
|
|
358
|
-
// Same length AND mtime moved. Only the hash can separate a one-character
|
|
359
|
-
// edit from a `touch`, and a same-length edit is the common shape, not an
|
|
360
|
-
// exotic one. Forced all-LSP confirmation reaches this tier even when mtime
|
|
361
|
-
// did not move.
|
|
362
|
-
if (args.recordedHash === undefined)
|
|
363
|
-
return { verdict: "unverifiable", unverifiableReason: "missing-baseline" };
|
|
364
|
-
// Defect shape 9: each read is individually bounded, but N blockers in one
|
|
365
|
-
// turn is an unbounded AGGREGATE read on a hook path. The per-sweep byte
|
|
366
|
-
// budget bounds the other axis; past it the record is unverifiable, not
|
|
367
|
-
// drifted.
|
|
368
|
-
if (stat.size > args.budget.bytesLeft) {
|
|
369
|
-
args.budget.exhausted = true;
|
|
370
|
-
return {
|
|
371
|
-
verdict: "unverifiable",
|
|
372
|
-
unverifiableReason: "hash-budget-exhausted",
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
const content = await bounded(fs.promises.readFile(args.filePath), boundOptions("selfDriftHash"));
|
|
376
|
-
if (content === undefined)
|
|
377
|
-
return { verdict: "unverifiable", unverifiableReason: "hash-unavailable" };
|
|
378
|
-
args.budget.bytesLeft -= content.byteLength;
|
|
379
|
-
const hash = createHash("sha256").update(content).digest("hex");
|
|
380
|
-
return { verdict: hash === args.recordedHash ? "unchanged" : "drift" };
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* Resolve `filePath`'s forward imports and stat each, returning the imports that
|
|
384
|
-
* exist together with their mtime. Shared by the inline-blocker sweep and the
|
|
385
|
-
* widget-store dependency reconcile so both gates weigh drift identically. A path
|
|
386
|
-
* that cannot be stat'ed (deleted/unreadable) is omitted — a deleted dependency is
|
|
387
|
-
* not a content drift this gate reports.
|
|
388
|
-
*/
|
|
389
|
-
export async function collectForwardImportMtimes(cwd, filePath, resolveForwardImports = extractForwardImportPaths, turnIndex) {
|
|
390
|
-
noteImportResolutionMemoTurn(turnIndex);
|
|
391
|
-
let imports = [];
|
|
392
|
-
try {
|
|
393
|
-
imports = await resolveForwardImportsMemoized(cwd, filePath, resolveForwardImports);
|
|
394
|
-
}
|
|
395
|
-
catch {
|
|
396
|
-
imports = [];
|
|
397
|
-
}
|
|
398
|
-
const truncated = imports.length > MAX_DRIFT_CHECK_IMPORTS;
|
|
399
|
-
const out = [];
|
|
400
|
-
for (const dep of imports.slice(0, MAX_DRIFT_CHECK_IMPORTS)) {
|
|
401
|
-
const mtimeMs = await statMtimeMs(dep);
|
|
402
|
-
if (mtimeMs !== undefined)
|
|
403
|
-
out.push({ path: dep, mtimeMs });
|
|
404
|
-
}
|
|
405
|
-
return { mtimes: out, truncated };
|
|
406
|
-
}
|
|
407
|
-
/**
|
|
408
|
-
* Detect drift for one blocker entry. Returns the set of paths (the file itself plus
|
|
409
|
-
* any forward import) whose mtime is strictly newer than the verdict baseline. A
|
|
410
|
-
* missing/unstat-able path contributes nothing here — a DELETED blocker file is
|
|
411
|
-
* already dropped by `reconcileInlineBlockers`, and a deleted dependency is not a
|
|
412
|
-
* content drift this gate is responsible for.
|
|
413
|
-
*
|
|
414
|
-
* +50ms tolerance. The verdict baseline is `Date.now()`, but on Windows a file's
|
|
415
|
-
* mtime can LEAD `Date.now()` by a measurable margin — not just sub-millisecond
|
|
416
|
-
* rounding. Reviewer measurement across 200 writes on Windows: 184/200 mtimes read
|
|
417
|
-
* ahead of the immediately-following `Date.now()`, by up to ~11.4ms, the same host
|
|
418
|
-
* skew #1491/#1498 hit for install-probe timestamps. A +1ms tolerance (the
|
|
419
|
-
* convention borrowed from `reconcileStaleWidgetFiles` /
|
|
420
|
-
* `reconcileProjectDiagnosticsSnapshot`, both same-process single-writer paths
|
|
421
|
-
* without this skew) demoted a blocker recorded immediately after its own file
|
|
422
|
-
* write with zero real drift — 42 false demotions in 50 runs, and two of this
|
|
423
|
-
* gate's own tests went host-dependent (red 3/6 runs on Windows, green 6/6 at
|
|
424
|
-
* +50ms). +50ms comfortably clears the measured skew while staying far below the
|
|
425
|
-
* gap between genuinely distinct edits.
|
|
426
|
-
*/
|
|
427
|
-
// Single implementation lives in the freshness kernel (#1739); this
|
|
428
|
-
// re-export preserves every existing importer's path.
|
|
429
|
-
export { MTIME_DRIFT_TOLERANCE_MS } from "./freshness.js";
|
|
430
|
-
import { freshnessFromMtime } from "./freshness.js";
|
|
431
|
-
async function detectDrift(cwd, filePath, recordedAtMs, resolveForwardImports, turnIndex,
|
|
432
|
-
/** Skip the own-file mtime tier after content confirms it is unchanged. */
|
|
433
|
-
skipOwnFile = false) {
|
|
434
|
-
const drifted = [];
|
|
435
|
-
if (!skipOwnFile) {
|
|
436
|
-
const ownFreshness = freshnessFromMtime({
|
|
437
|
-
mtimeMs: await statMtimeMs(filePath),
|
|
438
|
-
referenceMs: recordedAtMs,
|
|
439
|
-
});
|
|
440
|
-
if (ownFreshness.verdict === "stale")
|
|
441
|
-
drifted.push(filePath);
|
|
442
|
-
}
|
|
443
|
-
const { mtimes, truncated } = await collectForwardImportMtimes(cwd, filePath, resolveForwardImports, turnIndex);
|
|
444
|
-
for (const { path: depPath, mtimeMs } of mtimes) {
|
|
445
|
-
const verdict = freshnessFromMtime({
|
|
446
|
-
mtimeMs,
|
|
447
|
-
referenceMs: recordedAtMs,
|
|
448
|
-
});
|
|
449
|
-
if (verdict.verdict === "stale")
|
|
450
|
-
drifted.push(depPath);
|
|
451
|
-
}
|
|
452
|
-
return { drifted, truncated };
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* Whether a population entry is eligible for the drift check at all — the same
|
|
456
|
-
* three gates the main sweep loop applies (not already stale, has a timestamp
|
|
457
|
-
* baseline, HAS recorded provenance). Factored out so the #1790 review F5 dedup
|
|
458
|
-
* decision below (chain vs. separate row) asks the IDENTICAL question the main
|
|
459
|
-
* loop will ask, rather than a second hand-written approximation of it that
|
|
460
|
-
* could drift from the real gates.
|
|
461
|
-
*
|
|
462
|
-
* The third gate reads "has provenance", not "is all-`lsp`": a non-LSP record is
|
|
463
|
-
* now eligible for the self-drift axis (own file only, no import walk). Widening
|
|
464
|
-
* it here and in the loop together is the point of the shared predicate — the
|
|
465
|
-
* loop still decides WHICH axis each eligible entry gets.
|
|
466
|
-
*/
|
|
467
|
-
function isEligibleForDriftCheck(entry) {
|
|
468
|
-
if (entry.stale)
|
|
469
|
-
return false;
|
|
470
|
-
if (entry.recordedAtMs === undefined)
|
|
471
|
-
return false;
|
|
472
|
-
return entry.sources !== undefined && entry.sources.length > 0;
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* All recorded sources are `"lsp"` — the record gets the full own-file PLUS
|
|
476
|
-
* forward-import walk. Anything else (tree-sitter, ast-grep, mixed, `"unknown"`)
|
|
477
|
-
* gets the self-only axis. One spelling, shared by the sweep loop and the
|
|
478
|
-
* chain decision below so the two can never disagree about which axis an entry
|
|
479
|
-
* is on.
|
|
480
|
-
*/
|
|
481
|
-
function isAllLspSourced(sources) {
|
|
482
|
-
return (sources !== undefined &&
|
|
483
|
-
sources.length > 0 &&
|
|
484
|
-
sources.every((source) => source === "lsp"));
|
|
485
|
-
}
|
|
486
|
-
/**
|
|
487
|
-
* Whether a duplicated widget row may be CHAINED onto this inline entry's single
|
|
488
|
-
* drift check instead of being given its own population row (#1790 review F5).
|
|
489
|
-
*
|
|
490
|
-
* Strictly stronger than {@link isEligibleForDriftCheck} since the self-drift
|
|
491
|
-
* axis landed, and deliberately so. A widget row from
|
|
492
|
-
* `getWidgetBlockingFilesForSweep` is pure-LSP by construction, so the check that
|
|
493
|
-
* speaks for it must walk forward imports. An inline entry on the self-only axis
|
|
494
|
-
* never consults imports, so chaining a widget row onto it would silently drop
|
|
495
|
-
* that row's import axis — the #1790 ghost, in a new disguise: the inline entry
|
|
496
|
-
* reports `kept`, the widget row is never independently checked, and its
|
|
497
|
-
* `isBlocking` stays true for a dependency that drifted.
|
|
498
|
-
*
|
|
499
|
-
* Such an inline entry is still drift-checked on its own axis. It just cannot
|
|
500
|
-
* answer another store's question.
|
|
501
|
-
*/
|
|
502
|
-
function canSubsumeLspWidgetRow(entry) {
|
|
503
|
-
return isEligibleForDriftCheck(entry) && isAllLspSourced(entry.sources);
|
|
504
|
-
}
|
|
505
|
-
/**
|
|
506
|
-
* Freshness sweep over every blocking row the widget currently serves — the cached
|
|
507
|
-
* inline blockers (`RuntimeCoordinator`) AND, since #1790, any widget-store row
|
|
508
|
-
* reached only through a cache-served replay (`options.additionalEntries`, injected
|
|
509
|
-
* by the call site to avoid an import cycle with `widget-state.ts`). Called at turn
|
|
510
|
-
* end before the blockers are re-served. Entries whose own file or forward imports
|
|
511
|
-
* drifted since the verdict are demoted via `demote`; the turn-end renderer then
|
|
512
|
-
* serves them out of the advisory channel with a `[stale — re-run to confirm]`
|
|
513
|
-
* marker instead of as an authoritative blocker.
|
|
514
|
-
*
|
|
515
|
-
* #1790: a file present in BOTH stores — the common case, since a live dispatch
|
|
516
|
-
* writes an inline blocker (`runtime-tool-result.ts`) AND a widget-store record
|
|
517
|
-
* (`pipeline.ts`) for the SAME verdict — is drift-checked ONCE, via its
|
|
518
|
-
* inline-blocker entry, so the sweep's one drift check never runs twice over the
|
|
519
|
-
* same file WHEN that inline entry is itself eligible for the check. But
|
|
520
|
-
* `markInlineBlockerStale` only ever touches `RuntimeCoordinator`'s map, never
|
|
521
|
-
* the widget store; on drift for a duplicated path, the widget demote is
|
|
522
|
-
* CHAINED onto the inline entry's `demote` (both stores write) rather than the
|
|
523
|
-
* widget row being silently dropped — the reviewer's F1 probe caught an earlier
|
|
524
|
-
* revision that discarded it: `revalidated:1` while the widget's own
|
|
525
|
-
* `isBlocking` for the file still read true, the exact ghost #1790 exists to
|
|
526
|
-
* kill.
|
|
527
|
-
*
|
|
528
|
-
* #1790 review F5: chaining is conditional on the inline entry actually being
|
|
529
|
-
* ELIGIBLE for the drift check (`isEligibleForDriftCheck` — not already stale,
|
|
530
|
-
* timestamped, all-LSP sources). An ineligible inline entry never reaches
|
|
531
|
-
* `demote()` in the loop below, so chaining onto one is ALSO a silent drop —
|
|
532
|
-
* just one store removed from F1's. The widget row's eligibility belongs to the
|
|
533
|
-
* WIDGET STORE, not to whatever inline entry happens to share its file path; an
|
|
534
|
-
* ineligible duplicate therefore gets its own separate population row instead
|
|
535
|
-
* of being chained, so a file can legitimately count twice (once per store) when
|
|
536
|
-
* the two stores disagree on eligibility.
|
|
537
|
-
*
|
|
538
|
-
* Never throws: any internal failure leaves the entry untouched (existing re-serve
|
|
539
|
-
* behavior) rather than failing the turn end.
|
|
540
|
-
*/
|
|
541
|
-
export async function sweepInlineBlockerFreshness(runtime, cwd, options) {
|
|
542
|
-
const counts = {
|
|
543
|
-
total: 0,
|
|
544
|
-
kept: 0,
|
|
545
|
-
revalidated: 0,
|
|
546
|
-
alreadyStale: 0,
|
|
547
|
-
truncatedImports: 0,
|
|
548
|
-
selfHealed: 0,
|
|
549
|
-
selfUnverifiable: 0,
|
|
550
|
-
hashBudgetExhausted: 0,
|
|
551
|
-
};
|
|
552
|
-
const resolveForwardImports = options?.resolveForwardImports ?? extractForwardImportPaths;
|
|
553
|
-
let turnIndex;
|
|
554
|
-
try {
|
|
555
|
-
turnIndex = runtime.turnIndex;
|
|
556
|
-
}
|
|
557
|
-
catch {
|
|
558
|
-
turnIndex = undefined;
|
|
559
|
-
}
|
|
560
|
-
let inlineEntries;
|
|
561
|
-
try {
|
|
562
|
-
inlineEntries = runtime.getInlineBlockersSnapshot();
|
|
563
|
-
}
|
|
564
|
-
catch {
|
|
565
|
-
return counts;
|
|
566
|
-
}
|
|
567
|
-
const population = inlineEntries.map((entry) => ({
|
|
568
|
-
filePath: entry.filePath,
|
|
569
|
-
stale: entry.stale ?? false,
|
|
570
|
-
recordedAtMs: entry.recordedAtMs,
|
|
571
|
-
sources: entry.sources,
|
|
572
|
-
staleReason: entry.staleReason,
|
|
573
|
-
recordedSize: entry.recordedSize,
|
|
574
|
-
recordedHash: entry.recordedHash,
|
|
575
|
-
demote: () => runtime.markInlineBlockerStale(entry.filePath, "dependency-drift"),
|
|
576
|
-
setSelfDrift: (isSelfDrift) => runtime.setInlineBlockerSelfDriftStale(entry.filePath, isSelfDrift),
|
|
577
|
-
}));
|
|
578
|
-
// #1790 review F2: dedup key is `normalizeEphemeralMapKey`, not
|
|
579
|
-
// `normalizeMapKey` — the latter realpaths a live file and walks up the
|
|
580
|
-
// directory tree for a missing one (measured ~313µs per deleted path, exactly
|
|
581
|
-
// the population this sweep processes) on a turn-end hot path. The widget
|
|
582
|
-
// store this population is reconciled against keys on
|
|
583
|
-
// `normalizeEphemeralMapKey` too (see `widget-state.ts`'s module doc on why
|
|
584
|
-
// `normalizeMapKey` is wrong for this in-process, single-walk kind of key),
|
|
585
|
-
// so this also keeps the dedup consistent with the store it is deduping
|
|
586
|
-
// against, not just cheaper.
|
|
587
|
-
const inlineByKey = new Map();
|
|
588
|
-
for (const entry of population) {
|
|
589
|
-
inlineByKey.set(normalizeEphemeralMapKey(entry.filePath), entry);
|
|
590
|
-
}
|
|
591
|
-
for (const extra of options?.additionalEntries ?? []) {
|
|
592
|
-
const key = normalizeEphemeralMapKey(extra.filePath);
|
|
593
|
-
const inlineEntry = inlineByKey.get(key);
|
|
594
|
-
// #1790 review F5: chaining onto an INELIGIBLE inline entry is a silent
|
|
595
|
-
// drop, not a merge. The main loop below short-circuits BEFORE ever
|
|
596
|
-
// calling `demote()` for an already-stale entry (the one-way
|
|
597
|
-
// dependency-drift latch — a forever-ghost once it fires once), an
|
|
598
|
-
// unstamped legacy record, or a record with no provenance at all. Any of
|
|
599
|
-
// those swallows a chained widget demote even though the widget row is
|
|
600
|
-
// pure-LSP by construction (`getWidgetBlockingFilesForSweep` only emits
|
|
601
|
-
// LSP-sourced rows) and carries its OWN baseline. Eligibility belongs to
|
|
602
|
-
// the STORE the row came from, not the file path two stores happen to
|
|
603
|
-
// share — so only chain when the inline entry would itself reach
|
|
604
|
-
// `demote()`; otherwise give the widget row its own population entry so
|
|
605
|
-
// its own gates and its own drift check decide its own fate.
|
|
606
|
-
//
|
|
607
|
-
// Since the self-drift axis landed, "would reach `demote()`" is no longer
|
|
608
|
-
// enough: a non-LSP inline entry IS drift-checked now, but only against
|
|
609
|
-
// its own file. It never consults imports, so it cannot speak for a
|
|
610
|
-
// pure-LSP widget row whose dependency drifted. `canSubsumeLspWidgetRow`
|
|
611
|
-
// carries that stronger test; the unrelated-ast-grep-finding case in the
|
|
612
|
-
// paragraph above is now excluded by the axis, not by ineligibility.
|
|
613
|
-
if (inlineEntry && canSubsumeLspWidgetRow(inlineEntry)) {
|
|
614
|
-
// #1790 review F1: a duplicated path is counted and drift-checked ONCE
|
|
615
|
-
// (via the inline entry above), but BOTH stores must record the
|
|
616
|
-
// verdict — `markInlineBlockerStale` only ever touches
|
|
617
|
-
// `RuntimeCoordinator`'s map, so without this chain the widget store's
|
|
618
|
-
// own diagnostic for this file stays fully blocking (`isBlocking` true)
|
|
619
|
-
// even after the inline entry demotes. Chain, don't replace: either
|
|
620
|
-
// store's own untouched failure path must not suppress the other's
|
|
621
|
-
// write.
|
|
622
|
-
const demoteInline = inlineEntry.demote;
|
|
623
|
-
const demoteWidget = extra.demote;
|
|
624
|
-
inlineEntry.demote = () => {
|
|
625
|
-
const inlineChanged = demoteInline();
|
|
626
|
-
const widgetChanged = demoteWidget();
|
|
627
|
-
return inlineChanged || widgetChanged;
|
|
628
|
-
};
|
|
629
|
-
continue;
|
|
630
|
-
}
|
|
631
|
-
population.push({
|
|
632
|
-
filePath: extra.filePath,
|
|
633
|
-
stale: false,
|
|
634
|
-
recordedAtMs: extra.recordedAtMs,
|
|
635
|
-
sources: ["lsp"],
|
|
636
|
-
demote: extra.demote,
|
|
637
|
-
// A widget row is pure-LSP by construction, so it takes the import
|
|
638
|
-
// axis and never reaches the self axis. No `setSelfDrift` (#2982):
|
|
639
|
-
// the widget store has no re-arming self-drift setter, and an entry
|
|
640
|
-
// without one is not eligible for that axis.
|
|
641
|
-
staleReason: undefined,
|
|
642
|
-
recordedSize: undefined,
|
|
643
|
-
recordedHash: undefined,
|
|
644
|
-
});
|
|
645
|
-
}
|
|
646
|
-
counts.total = population.length;
|
|
647
|
-
// One budget for the whole sweep (defect shape 9), consumed by the self
|
|
648
|
-
// axis's hash tier as it goes.
|
|
649
|
-
const hashBudget = {
|
|
650
|
-
bytesLeft: SELF_DRIFT_HASH_BUDGET_BYTES,
|
|
651
|
-
exhausted: false,
|
|
652
|
-
};
|
|
653
|
-
for (const entry of population) {
|
|
654
|
-
try {
|
|
655
|
-
// #2982: a latched demotion belongs to the gate that made it and this
|
|
656
|
-
// loop leaves it alone. Its OWN self-drift demotion is re-armable, so
|
|
657
|
-
// it is re-derived every turn instead: bytes that come back must
|
|
658
|
-
// un-demote the record, which is what lets the self axis skip the
|
|
659
|
-
// #1950 delivery cap rather than retire a security finding for good.
|
|
660
|
-
const selfDriftDemoted = entry.stale && entry.staleReason === "self-drift";
|
|
661
|
-
if (entry.stale && !selfDriftDemoted) {
|
|
662
|
-
counts.alreadyStale += 1;
|
|
663
|
-
continue;
|
|
664
|
-
}
|
|
665
|
-
// No timestamp baseline (legacy/unstamped record) — we cannot order disk
|
|
666
|
-
// mtimes against the verdict, so leave it untouched (fail toward the
|
|
667
|
-
// existing behavior rather than fabricating a drift signal).
|
|
668
|
-
if (entry.recordedAtMs === undefined) {
|
|
669
|
-
counts.kept += 1;
|
|
670
|
-
continue;
|
|
671
|
-
}
|
|
672
|
-
// #1631 review F4 kept every non-`"lsp"` record at full authority. Its
|
|
673
|
-
// stated reason is about the IMPORT axis only — "an ast-grep secret match
|
|
674
|
-
// doesn't stop being true because a file it imports was edited" — but the
|
|
675
|
-
// gate discarded the self axis with it. A record with NO provenance at all
|
|
676
|
-
// stays fail-closed here, the same test
|
|
677
|
-
// `retireInlineBlockerOnConfirmedClean` applies before it will retire.
|
|
678
|
-
const recordedSources = entry.sources !== undefined && entry.sources.length > 0
|
|
679
|
-
? entry.sources
|
|
680
|
-
: undefined;
|
|
681
|
-
if (recordedSources === undefined) {
|
|
682
|
-
counts.kept += 1;
|
|
683
|
-
continue;
|
|
684
|
-
}
|
|
685
|
-
// #2982 remainder: the record's OWN file is checked via the content-
|
|
686
|
-
// confirmed self-drift axis (size → hash, re-arming) for records that
|
|
687
|
-
// have a re-arming setter — shared by the non-LSP self axis below and
|
|
688
|
-
// the all-LSP axis. The mtime-only own-file check in `detectDrift` is
|
|
689
|
-
// blind to the out-of-band-rewrite case (an external write can land at-
|
|
690
|
-
// or-before the `recordedAtMs` baseline), so the content axis owns the
|
|
691
|
-
// own-file verdict when it can decide. One bounded() call site for both
|
|
692
|
-
// axes — the #2523 registry requires a single occurrence, so the two
|
|
693
|
-
// branches must not each wrap the identical call. Demotion, not deletion
|
|
694
|
-
// (#1419): a demoted entry is re-served in the advisory channel marked
|
|
695
|
-
// `[stale — re-run to confirm]` and retires through the existing #1950
|
|
696
|
-
// delivery cap.
|
|
697
|
-
const setSelfDrift = entry.setSelfDrift;
|
|
698
|
-
const isLspSourced = isAllLspSourced(recordedSources);
|
|
699
|
-
let ownVerdict;
|
|
700
|
-
if (setSelfDrift) {
|
|
701
|
-
// The outer bound too: an expired one yields `undefined`, and that
|
|
702
|
-
// means "could not decide", never "changed".
|
|
703
|
-
const hashBudgetWasExhausted = hashBudget.exhausted;
|
|
704
|
-
const selfDrift = (await bounded(detectSelfDrift({
|
|
705
|
-
filePath: entry.filePath,
|
|
706
|
-
recordedAtMs: entry.recordedAtMs,
|
|
707
|
-
recordedSize: entry.recordedSize,
|
|
708
|
-
recordedHash: entry.recordedHash,
|
|
709
|
-
forceContent: isLspSourced &&
|
|
710
|
-
entry.recordedSize !== undefined &&
|
|
711
|
-
entry.recordedHash !== undefined,
|
|
712
|
-
signal: options?.signal,
|
|
713
|
-
budget: hashBudget,
|
|
714
|
-
}), {
|
|
715
|
-
ms: HOOK_WALL_BUDGET_MS.turn_end,
|
|
716
|
-
signal: options?.signal,
|
|
717
|
-
hook: "turn_end",
|
|
718
|
-
label: "detectSelfDrift",
|
|
719
|
-
})) ?? {
|
|
720
|
-
verdict: "unverifiable",
|
|
721
|
-
unverifiableReason: "bound-expired",
|
|
722
|
-
};
|
|
723
|
-
ownVerdict = selfDrift.verdict;
|
|
724
|
-
if (ownVerdict === "unverifiable") {
|
|
725
|
-
// Decide nothing. Leave the record in whatever state it holds.
|
|
726
|
-
counts.selfUnverifiable += 1;
|
|
727
|
-
const reason = selfDrift.unverifiableReason ??
|
|
728
|
-
(hashBudgetWasExhausted || hashBudget.exhausted
|
|
729
|
-
? "hash-budget-exhausted"
|
|
730
|
-
: "hash-unavailable");
|
|
731
|
-
recordDegradationOnce({
|
|
732
|
-
kind: "self-drift-unverifiable",
|
|
733
|
-
subject: `inline-blocker:${toRunnerDisplayPath(cwd, entry.filePath)}#${reason}`,
|
|
734
|
-
reason: `the self-drift check was unverifiable: ${reason}`,
|
|
735
|
-
});
|
|
736
|
-
if (reason === "hash-budget-exhausted") {
|
|
737
|
-
recordDegradationOnce({
|
|
738
|
-
kind: "self-drift-hash-budget-exhausted",
|
|
739
|
-
subject: `inline-blocker:${toRunnerDisplayPath(cwd, entry.filePath)}`,
|
|
740
|
-
reason: "the aggregate self-drift hash budget was exhausted",
|
|
741
|
-
});
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
if (!isLspSourced) {
|
|
746
|
-
// The self axis. Content-confirmed, re-arming, and outside the
|
|
747
|
-
// #1950 delivery cap. A store with no re-arming setter is not
|
|
748
|
-
// eligible for it and stays authoritative (fail-closed).
|
|
749
|
-
if (!setSelfDrift || ownVerdict === undefined) {
|
|
750
|
-
counts.kept += 1;
|
|
751
|
-
continue;
|
|
752
|
-
}
|
|
753
|
-
if (ownVerdict === "unverifiable") {
|
|
754
|
-
if (selfDriftDemoted)
|
|
755
|
-
counts.alreadyStale += 1;
|
|
756
|
-
else
|
|
757
|
-
counts.kept += 1;
|
|
758
|
-
continue;
|
|
759
|
-
}
|
|
760
|
-
const shouldDemote = ownVerdict === "drift";
|
|
761
|
-
const transitioned = setSelfDrift(shouldDemote);
|
|
762
|
-
if (shouldDemote) {
|
|
763
|
-
if (transitioned)
|
|
764
|
-
counts.revalidated += 1;
|
|
765
|
-
else
|
|
766
|
-
counts.alreadyStale += 1;
|
|
767
|
-
}
|
|
768
|
-
else if (transitioned) {
|
|
769
|
-
counts.selfHealed += 1;
|
|
770
|
-
}
|
|
771
|
-
else {
|
|
772
|
-
counts.kept += 1;
|
|
773
|
-
}
|
|
774
|
-
continue;
|
|
775
|
-
}
|
|
776
|
-
// The LSP axis (#1618). The own file is checked by the content axis
|
|
777
|
-
// above when a baseline was captured; without one it falls back to the
|
|
778
|
-
// mtime check (the pre-#2982 behavior, fail-open). The forward-import
|
|
779
|
-
// walk stays on the one-way dependency-drift axis.
|
|
780
|
-
let contentDecidedOwnFile = false;
|
|
781
|
-
if (setSelfDrift !== undefined &&
|
|
782
|
-
ownVerdict !== undefined &&
|
|
783
|
-
entry.recordedSize !== undefined) {
|
|
784
|
-
if (ownVerdict === "drift") {
|
|
785
|
-
const transitioned = setSelfDrift(true);
|
|
786
|
-
if (transitioned)
|
|
787
|
-
counts.revalidated += 1;
|
|
788
|
-
else
|
|
789
|
-
counts.alreadyStale += 1;
|
|
790
|
-
// Own file drifted; the record is out of the authoritative
|
|
791
|
-
// channel, so the import walk is moot this turn.
|
|
792
|
-
continue;
|
|
793
|
-
}
|
|
794
|
-
if (ownVerdict === "unchanged") {
|
|
795
|
-
// Content confirms the own file is unchanged: skip the mtime check
|
|
796
|
-
// below (a `touch` must not demote a still-valid record), and
|
|
797
|
-
// un-demote a record self-drifted last turn.
|
|
798
|
-
contentDecidedOwnFile = true;
|
|
799
|
-
const transitioned = setSelfDrift(false);
|
|
800
|
-
if (transitioned)
|
|
801
|
-
counts.selfHealed += 1;
|
|
802
|
-
}
|
|
803
|
-
else {
|
|
804
|
-
// "unverifiable": the content axis could not decide (a stat that
|
|
805
|
-
// failed, or a size that matched but whose hash never landed). Fall
|
|
806
|
-
// back to the mtime check below.
|
|
807
|
-
if (selfDriftDemoted) {
|
|
808
|
-
counts.alreadyStale += 1;
|
|
809
|
-
continue;
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
// Forward-import walk (one-way dependency-drift). Skip the own file ONLY
|
|
814
|
-
// when the content axis decided it "unchanged" — the one case where the
|
|
815
|
-
// mtime check would wrongly demote on a `touch`. A widget row (no setter)
|
|
816
|
-
// and an inline entry without a baseline never reach the content axis, so
|
|
817
|
-
// they still get the mtime own-file check (fail-open).
|
|
818
|
-
const skipOwnFile = contentDecidedOwnFile;
|
|
819
|
-
const { drifted, truncated } = await detectDrift(cwd, entry.filePath, entry.recordedAtMs, resolveForwardImports, turnIndex, skipOwnFile);
|
|
820
|
-
if (truncated)
|
|
821
|
-
counts.truncatedImports += 1;
|
|
822
|
-
if (drifted.length > 0) {
|
|
823
|
-
entry.demote();
|
|
824
|
-
counts.revalidated += 1;
|
|
825
|
-
}
|
|
826
|
-
else {
|
|
827
|
-
counts.kept += 1;
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
catch {
|
|
831
|
-
// Per-entry failure: keep the entry as-is.
|
|
832
|
-
counts.kept += 1;
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
counts.hashBudgetExhausted = hashBudget.exhausted ? 1 : 0;
|
|
836
|
-
return counts;
|
|
837
|
-
}
|