@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,628 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cross-platform CPU/RSS sampling (#620), used two ways:
|
|
3
|
-
*
|
|
4
|
-
* 1. **Long-lived processes** (this host process + the LSP children recorded
|
|
5
|
-
* in clients/instance-registry.ts): `sampleProcesses` takes a snapshot of
|
|
6
|
-
* a pid set at heartbeat cadence (clients/quiet-window.ts /
|
|
7
|
-
* clients/runtime-turn.ts already call `updateHeartbeat` at that cadence —
|
|
8
|
-
* this module doesn't own a timer of its own).
|
|
9
|
-
* 2. **Transient analyzer children** (jscpd/knip/madge/gitleaks/etc., spawned
|
|
10
|
-
* via clients/safe-spawn.ts's `safeSpawnAsync`): `SpawnUsageSampler`
|
|
11
|
-
* brackets a single spawn with a short-interval poll (started right after
|
|
12
|
-
* `spawn()`, stopped at `child.on("close", ...)`), tracking peak/average
|
|
13
|
-
* CPU% and RSS for that one invocation.
|
|
14
|
-
*
|
|
15
|
-
* On **Linux/macOS** it uses `pidusage` (procfs on Linux, `ps` on macOS) — a
|
|
16
|
-
* small pure-JS package (one transitive dep, `safe-buffer`) that bundles like
|
|
17
|
-
* the repo's other pure-JS runtime deps (minimatch, js-yaml) rather than
|
|
18
|
-
* needing an EXTERNAL entry in scripts/bundle-dist.mjs.
|
|
19
|
-
*
|
|
20
|
-
* On **Windows** it does NOT use `pidusage`: pidusage's Windows path shells out
|
|
21
|
-
* to `gwmi` via an internal `spawn(..., { shell: "powershell.exe" })` that has
|
|
22
|
-
* NO try/catch, and it runs that spawn from inside a ChildProcess `close`
|
|
23
|
-
* callback (a detached async context). Under real Windows handle/commit
|
|
24
|
-
* pressure that `spawn()` can throw `spawn UNKNOWN` (errno -4094)
|
|
25
|
-
* **synchronously in that detached callback**, which no `try { await pidusage }
|
|
26
|
-
* catch {}` at the call site can catch → uncaughtException → the pi host
|
|
27
|
-
* crashes (#620, #533). pidusage 4.0.1 exposes no option to avoid the gwmi
|
|
28
|
-
* path. So on Windows this module asks the shared, fully guarded process-table
|
|
29
|
-
* seam (`clients/process-snapshot.ts` over `scripts/lib/process-scan.mjs`,
|
|
30
|
-
* #2443) for the CPU/RSS columns instead, and computes CPU% from the same
|
|
31
|
-
* KernelModeTime/UserModeTime delta-over-elapsed formula gwmi uses — so a
|
|
32
|
-
* spawn failure can only ever lose a data point, never throw.
|
|
33
|
-
*
|
|
34
|
-
* Every export here is best-effort: a sampling failure (pid already exited,
|
|
35
|
-
* `pidusage` throwing, permission denied, etc.) must never throw into the
|
|
36
|
-
* caller and must never block/slow the operation it's measuring — this
|
|
37
|
-
* module only ever "loses a data point", matching the repo's existing
|
|
38
|
-
* instrumentation-must-never-fail-the-operation-it-measures convention (see
|
|
39
|
-
* clients/latency-logger.ts's fire-and-forget `logLatency` calls).
|
|
40
|
-
*
|
|
41
|
-
* The accumulation math (peak/average over a stream of samples) is split out
|
|
42
|
-
* as a PURE class (`UsageAccumulator`) so it's unit-testable without any real
|
|
43
|
-
* process/pidusage involvement — mirrors the pure/impure split in
|
|
44
|
-
* clients/instance-reaper.ts (`decideOrphanReaping` vs `sweepOrphans`).
|
|
45
|
-
*/
|
|
46
|
-
import pidusage from "pidusage";
|
|
47
|
-
import { incrementDegradationCount, recordDegradationOnce, } from "./degradation-ledger.js";
|
|
48
|
-
import { terminateScannerChild } from "./instance-reaper.js";
|
|
49
|
-
import { queryProcessTable } from "./process-snapshot.js";
|
|
50
|
-
export const RESOURCE_SAMPLE_QUERY_TIMEOUT_MS = 2_000;
|
|
51
|
-
/**
|
|
52
|
-
* ONE ledger subject for every spawn sampler in the session (#2968). The
|
|
53
|
-
* per-spawn identity (pid, command) is NOT the subject: a subject is a
|
|
54
|
-
* `tallies` key, and one key per spawn would make the ledger grow with the
|
|
55
|
-
* session's spawn count — catalog shape 9, the same leak this fix exists to
|
|
56
|
-
* close. The command that was sampled is already on the `spawn_resource_usage`
|
|
57
|
-
* latency row; what the ledger answers is "did sampling hit its bounds, and
|
|
58
|
-
* how often", which is a per-session tally.
|
|
59
|
-
*/
|
|
60
|
-
const SPAWN_SAMPLER_LEDGER_SUBJECT = "spawn-usage-sampler";
|
|
61
|
-
function recordQueryFailure(subject, status, exitCode) {
|
|
62
|
-
const exitReason = status === "exit-error" ? ` (exit code ${exitCode ?? "unknown"})` : "";
|
|
63
|
-
recordDegradationOnce({
|
|
64
|
-
kind: "resource-sampler-query-failed",
|
|
65
|
-
subject,
|
|
66
|
-
reason: `process-table query ${status}${exitReason}`,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
// Read the platform live (not a module-load const) so both the Windows and the
|
|
70
|
-
// POSIX sampling paths are exercisable in unit tests regardless of the host OS.
|
|
71
|
-
function runningOnWindows() {
|
|
72
|
-
return process.platform === "win32";
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* PURE BFS over a (pid, parentPid) snapshot: every live descendant of
|
|
76
|
-
* `rootPid`, however deep. Split out from `findDescendantPidsWindows` so the
|
|
77
|
-
* tree-walk itself is unit-testable with a fake pid/ppid table — no real CIM
|
|
78
|
-
* query/spawn involved (mirrors clients/instance-reaper.ts's pure/impure
|
|
79
|
-
* split). Cycle-guarded (`visited`) in case a malformed/racy snapshot ever
|
|
80
|
-
* produced a loop — a live process tree never actually has one, but a
|
|
81
|
-
* best-effort sampler must not hang if the data is ever wrong.
|
|
82
|
-
*/
|
|
83
|
-
export function walkDescendantPids(rootPid, pairs) {
|
|
84
|
-
const childrenByParent = new Map();
|
|
85
|
-
for (const [pid, ppid] of pairs) {
|
|
86
|
-
const list = childrenByParent.get(ppid);
|
|
87
|
-
if (list)
|
|
88
|
-
list.push(pid);
|
|
89
|
-
else
|
|
90
|
-
childrenByParent.set(ppid, [pid]);
|
|
91
|
-
}
|
|
92
|
-
const descendants = [];
|
|
93
|
-
const queue = [rootPid];
|
|
94
|
-
const visited = new Set([rootPid]);
|
|
95
|
-
while (queue.length > 0) {
|
|
96
|
-
const current = queue.shift();
|
|
97
|
-
for (const child of childrenByParent.get(current) ?? []) {
|
|
98
|
-
if (visited.has(child))
|
|
99
|
-
continue;
|
|
100
|
-
visited.add(child);
|
|
101
|
-
descendants.push(child);
|
|
102
|
-
queue.push(child);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return descendants;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Windows-only descendant-pid resolution (best-effort; `[]` on any failure).
|
|
109
|
-
*
|
|
110
|
-
* WHY THIS EXISTS: `clients/safe-spawn.ts` spawns with `shell: true` on
|
|
111
|
-
* Windows (needed for `.cmd`-shimmed tools like pyright/biome — see its
|
|
112
|
-
* `buildWindowsShellCommand` docstring), so `child.pid` there is `cmd.exe`'s
|
|
113
|
-
* pid, not the real tool's. `cmd.exe` itself does almost no work — sampling
|
|
114
|
-
* only its pid would report ~0% CPU / minimal RSS for the entire spawn,
|
|
115
|
-
* which is a misleading answer on the platform this repo primarily runs on.
|
|
116
|
-
* Resolving the live descendant tree (cmd.exe's children, and THEIR
|
|
117
|
-
* children — covers e.g. `npx` re-spawning `node`) via one CIM query per poll
|
|
118
|
-
* tick lets the sampler aggregate the pids that are actually doing the work.
|
|
119
|
-
* Mirrors the identity-verification CIM queries in clients/instance-reaper.ts.
|
|
120
|
-
*/
|
|
121
|
-
async function findDescendantPidsWindows(rootPid) {
|
|
122
|
-
if (!runningOnWindows() || !Number.isFinite(rootPid) || rootPid <= 0)
|
|
123
|
-
return [];
|
|
124
|
-
// One query pulls every process's (pid, parentPid) pair; walk the BFS in
|
|
125
|
-
// JS rather than issuing N queries for N tree levels. The listing itself is
|
|
126
|
-
// the shared seam (#2443), which also supplies the fire-and-forget spawn
|
|
127
|
-
// rails this call has always needed (#1155): the child AND its piped stdout
|
|
128
|
-
// are unref'd, so this one-shot query can never keep a settled
|
|
129
|
-
// `pi --print` process alive past its own close, and a scanner child that
|
|
130
|
-
// blows the timeout is tree-killed and verified rather than abandoned. The
|
|
131
|
-
// result status keeps a failed query distinct from a successful empty
|
|
132
|
-
// process table.
|
|
133
|
-
const result = await queryProcessTable({ fields: ["pid", "ppid"] }, {
|
|
134
|
-
timeoutMs: RESOURCE_SAMPLE_QUERY_TIMEOUT_MS,
|
|
135
|
-
onTimeout: (child) => terminateScannerChild(child, {
|
|
136
|
-
kind: "resource-sampler-scanner-escalated",
|
|
137
|
-
timeoutMs: RESOURCE_SAMPLE_QUERY_TIMEOUT_MS,
|
|
138
|
-
}),
|
|
139
|
-
});
|
|
140
|
-
if (result.status !== "ok") {
|
|
141
|
-
recordQueryFailure("windows-descendant-process-table", result.status, result.exitCode);
|
|
142
|
-
return null;
|
|
143
|
-
}
|
|
144
|
-
return walkDescendantPids(rootPid, result.rows.map((row) => [row.pid, row.ppid]));
|
|
145
|
-
}
|
|
146
|
-
const windowsCpuHistory = new Map();
|
|
147
|
-
const CPU_HISTORY_MAX_AGE_MS = 60_000;
|
|
148
|
-
const CPU_HISTORY_MAX_ENTRIES = 4_096;
|
|
149
|
-
/**
|
|
150
|
-
* TEST-ONLY: clear the Windows CPU%-history so a test's two-sample CPU%
|
|
151
|
-
* assertion starts from a known-empty state (module-level state otherwise
|
|
152
|
-
* persists across tests in the same worker).
|
|
153
|
-
*/
|
|
154
|
-
export function __resetWindowsCpuHistoryForTests() {
|
|
155
|
-
windowsCpuHistory.clear();
|
|
156
|
-
}
|
|
157
|
-
export function __windowsCpuHistorySizeForTests() {
|
|
158
|
-
return windowsCpuHistory.size;
|
|
159
|
-
}
|
|
160
|
-
export function __windowsCpuHistoryHasForTests(pid, processIdentity) {
|
|
161
|
-
return windowsCpuHistory.has(`${pid}:${processIdentity}`);
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Windows-only CPU%/RSS sampling through the FULLY GUARDED process-table
|
|
165
|
-
* seam (mirrors `findDescendantPidsWindows`): a synchronous throw from
|
|
166
|
-
* `spawn` (the `spawn UNKNOWN` crash vector, #620), a `child` `error` event,
|
|
167
|
-
* or a non-zero/garbage exit all resolve to an errored/absent map — this
|
|
168
|
-
* function can NEVER throw or reject. Deliberately does NOT call `pidusage`,
|
|
169
|
-
* whose unguarded internal `gwmi` spawn is the crash we're fixing.
|
|
170
|
-
*
|
|
171
|
-
* RSS comes from `WorkingSetSize` (`rssBytes`); CPU% from `KernelModeTime`
|
|
172
|
-
* plus `UserModeTime` (both in 100 ns units → ms via `/1e4`) differenced
|
|
173
|
-
* against this pid's prior sample over the elapsed wall time — the same
|
|
174
|
-
* computation pidusage's gwmi path uses. The first time a pid is seen it has
|
|
175
|
-
* no prior sample, so CPU% is reported as 0 for that tick and a real rate
|
|
176
|
-
* lands on the next one. The process creation date (`startedAt`) is the
|
|
177
|
-
* pid-reuse discriminator: a recycled pid must not inherit the previous
|
|
178
|
-
* process's CPU baseline.
|
|
179
|
-
*/
|
|
180
|
-
async function sampleProcessesWindows(valid) {
|
|
181
|
-
const samples = new Map();
|
|
182
|
-
if (valid.length === 0)
|
|
183
|
-
return samples;
|
|
184
|
-
// pids are pre-validated finite positive integers, and the seam validates
|
|
185
|
-
// them again before they reach the query text, so the filter is
|
|
186
|
-
// injection-safe. The seam also supplies the fire-and-forget spawn rails
|
|
187
|
-
// (#1155: the child and its piped stdout are unref'd, so this one-shot
|
|
188
|
-
// query cannot keep a settled `pi --print` alive past its own close) and
|
|
189
|
-
// absorbs every failure mode this function used to guard inline — a
|
|
190
|
-
// synchronous `spawn` throw (the `spawn UNKNOWN` crash vector, #620), an
|
|
191
|
-
// async `error` event, a timeout, or a non-zero exit — reporting each
|
|
192
|
-
// through `status` rather than as an indistinguishable empty table.
|
|
193
|
-
const query = await queryProcessTable({
|
|
194
|
-
fields: [
|
|
195
|
-
"pid",
|
|
196
|
-
"rssBytes",
|
|
197
|
-
"cpuKernel100ns",
|
|
198
|
-
"cpuUser100ns",
|
|
199
|
-
"startedAt",
|
|
200
|
-
],
|
|
201
|
-
filter: { column: "ProcessId", op: "eq", values: valid },
|
|
202
|
-
}, {
|
|
203
|
-
timeoutMs: RESOURCE_SAMPLE_QUERY_TIMEOUT_MS,
|
|
204
|
-
onTimeout: (child) => terminateScannerChild(child, {
|
|
205
|
-
kind: "resource-sampler-scanner-escalated",
|
|
206
|
-
timeoutMs: RESOURCE_SAMPLE_QUERY_TIMEOUT_MS,
|
|
207
|
-
}),
|
|
208
|
-
});
|
|
209
|
-
if (query.status !== "ok") {
|
|
210
|
-
recordQueryFailure("windows-process-table", query.status, query.exitCode);
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
try {
|
|
214
|
-
const now = Date.now();
|
|
215
|
-
const seen = new Set();
|
|
216
|
-
for (const row of query.rows) {
|
|
217
|
-
const pid = row.pid;
|
|
218
|
-
const workingSet = row.rssBytes;
|
|
219
|
-
const kernel100ns = row.cpuKernel100ns;
|
|
220
|
-
const user100ns = row.cpuUser100ns;
|
|
221
|
-
const processIdentity = row.startedAt ?? "";
|
|
222
|
-
// The seam already rejects a non-integer or negative column as
|
|
223
|
-
// UNKNOWN (undefined), so an absent value here means the row cannot
|
|
224
|
-
// be sampled — never that the process used zero.
|
|
225
|
-
if (workingSet === undefined ||
|
|
226
|
-
kernel100ns === undefined ||
|
|
227
|
-
user100ns === undefined ||
|
|
228
|
-
processIdentity.length === 0)
|
|
229
|
-
continue;
|
|
230
|
-
const cpuMs = Math.round(kernel100ns / 1e4) + Math.round(user100ns / 1e4);
|
|
231
|
-
const historyKey = `${pid}:${processIdentity}`;
|
|
232
|
-
// A reused PID must start a fresh rate window. Drop every prior identity
|
|
233
|
-
// for this PID before looking up the current one.
|
|
234
|
-
for (const [key, prior] of windowsCpuHistory) {
|
|
235
|
-
if (prior.processIdentity !== processIdentity &&
|
|
236
|
-
key.startsWith(`${pid}:`)) {
|
|
237
|
-
windowsCpuHistory.delete(key);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
const prev = windowsCpuHistory.get(historyKey);
|
|
241
|
-
if (prev && cpuMs < prev.cpuMs) {
|
|
242
|
-
// A counter reset is not a flat sample. Retire the baseline so the
|
|
243
|
-
// next valid observation starts a new rate window.
|
|
244
|
-
windowsCpuHistory.delete(historyKey);
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
let cpuPercent = 0;
|
|
248
|
-
if (prev) {
|
|
249
|
-
const wallMs = now - prev.ts;
|
|
250
|
-
if (wallMs > 0) {
|
|
251
|
-
cpuPercent = ((cpuMs - prev.cpuMs) / wallMs) * 100;
|
|
252
|
-
if (!Number.isFinite(cpuPercent) || cpuPercent < 0)
|
|
253
|
-
cpuPercent = 0;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
windowsCpuHistory.set(historyKey, { processIdentity, cpuMs, ts: now });
|
|
257
|
-
seen.add(pid);
|
|
258
|
-
samples.set(pid, { rssBytes: workingSet, cpuPercent });
|
|
259
|
-
}
|
|
260
|
-
// Prune stale history so pids that have gone away don't accumulate.
|
|
261
|
-
for (const [key, entry] of windowsCpuHistory) {
|
|
262
|
-
const pid = Number(key.slice(0, key.indexOf(":")));
|
|
263
|
-
if (!seen.has(pid) && now - entry.ts > CPU_HISTORY_MAX_AGE_MS) {
|
|
264
|
-
windowsCpuHistory.delete(key);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
while (windowsCpuHistory.size > CPU_HISTORY_MAX_ENTRIES) {
|
|
268
|
-
let oldestKey;
|
|
269
|
-
let oldestTs = Number.POSITIVE_INFINITY;
|
|
270
|
-
for (const [key, entry] of windowsCpuHistory) {
|
|
271
|
-
if (entry.ts < oldestTs) {
|
|
272
|
-
oldestKey = key;
|
|
273
|
-
oldestTs = entry.ts;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
if (oldestKey === undefined)
|
|
277
|
-
break;
|
|
278
|
-
windowsCpuHistory.delete(oldestKey);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
catch {
|
|
282
|
-
// Parsing must never throw into the caller; best-effort.
|
|
283
|
-
}
|
|
284
|
-
return samples;
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Sample CPU%/RSS for a set of pids. Best-effort: a pid that can't be resolved
|
|
288
|
-
* (already exited, permission denied, spawn failed, etc.) is simply absent
|
|
289
|
-
* from the returned map — callers MUST treat "absent" as "unsampled this
|
|
290
|
-
* tick", never as zero usage.
|
|
291
|
-
*
|
|
292
|
-
* On Windows this uses a guarded CIM query (`sampleProcessesWindows`) and
|
|
293
|
-
* never touches `pidusage`, whose unguarded internal spawn could crash the
|
|
294
|
-
* host (#620, #533). On Linux/macOS it uses `pidusage`.
|
|
295
|
-
*/
|
|
296
|
-
export async function sampleProcesses(pids) {
|
|
297
|
-
const result = new Map();
|
|
298
|
-
const valid = [...new Set(pids.filter((p) => Number.isFinite(p) && p > 0))];
|
|
299
|
-
if (valid.length === 0)
|
|
300
|
-
return result;
|
|
301
|
-
if (runningOnWindows()) {
|
|
302
|
-
// Fully guarded; cannot throw/reject.
|
|
303
|
-
return await sampleProcessesWindows(valid);
|
|
304
|
-
}
|
|
305
|
-
try {
|
|
306
|
-
const stats = await pidusage(valid);
|
|
307
|
-
for (const pid of valid) {
|
|
308
|
-
const stat = stats[String(pid)];
|
|
309
|
-
if (!stat)
|
|
310
|
-
continue; // pidusage couldn't resolve this pid — leave absent
|
|
311
|
-
if (!Number.isFinite(stat.cpu) ||
|
|
312
|
-
stat.cpu < 0 ||
|
|
313
|
-
!Number.isFinite(stat.memory) ||
|
|
314
|
-
stat.memory < 0)
|
|
315
|
-
continue;
|
|
316
|
-
result.set(pid, {
|
|
317
|
-
rssBytes: stat.memory,
|
|
318
|
-
cpuPercent: stat.cpu,
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
catch {
|
|
323
|
-
recordQueryFailure("posix-pidusage-process-table", "spawn-error");
|
|
324
|
-
// Best-effort: sampling failure loses this tick's data for every pid in
|
|
325
|
-
// the batch, but must never throw into the heartbeat/spawn path.
|
|
326
|
-
return null;
|
|
327
|
-
}
|
|
328
|
-
return result;
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* PURE peak/average accumulator over a stream of {cpuPercent, rssBytes}
|
|
332
|
-
* samples. No I/O, no timers — unit-testable by feeding it samples directly.
|
|
333
|
-
*/
|
|
334
|
-
export class UsageAccumulator {
|
|
335
|
-
sampleCount = 0;
|
|
336
|
-
cpuSum = 0;
|
|
337
|
-
rssSum = 0;
|
|
338
|
-
cpuPeak = 0;
|
|
339
|
-
rssPeak = 0;
|
|
340
|
-
addSample(usage) {
|
|
341
|
-
this.sampleCount++;
|
|
342
|
-
this.cpuSum += usage.cpuPercent;
|
|
343
|
-
this.rssSum += usage.rssBytes;
|
|
344
|
-
if (usage.cpuPercent > this.cpuPeak)
|
|
345
|
-
this.cpuPeak = usage.cpuPercent;
|
|
346
|
-
if (usage.rssBytes > this.rssPeak)
|
|
347
|
-
this.rssPeak = usage.rssBytes;
|
|
348
|
-
}
|
|
349
|
-
get count() {
|
|
350
|
-
return this.sampleCount;
|
|
351
|
-
}
|
|
352
|
-
summarize() {
|
|
353
|
-
if (this.sampleCount === 0)
|
|
354
|
-
return null;
|
|
355
|
-
return {
|
|
356
|
-
sampleCount: this.sampleCount,
|
|
357
|
-
avgCpuPercent: this.cpuSum / this.sampleCount,
|
|
358
|
-
peakCpuPercent: this.cpuPeak,
|
|
359
|
-
avgRssBytes: this.rssSum / this.sampleCount,
|
|
360
|
-
peakRssBytes: this.rssPeak,
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* #2358: sample a live process tree twice across a short window and answer
|
|
366
|
-
* whether it burned CPU above `floorPercent`.
|
|
367
|
-
*
|
|
368
|
-
* The notify-stall breaker uses this to tell a BUSY server (burning a core
|
|
369
|
-
* while it drains a burst) from a genuinely DEAD input path (flat CPU), and
|
|
370
|
-
* only tears the latter down. It reuses the same platform machinery as
|
|
371
|
-
* `startSpawnUsageSampler`: on Windows the direct child may be a `cmd`/`.cmd`
|
|
372
|
-
* shim that does no work itself, so the live descendant tree resolves once per
|
|
373
|
-
* read and CPU% is summed across it.
|
|
374
|
-
*
|
|
375
|
-
* Best-effort like every other export here: a failed query loses a data point,
|
|
376
|
-
* it never throws, and it never blocks for longer than the query timeouts plus
|
|
377
|
-
* `windowMs`. The target itself must resolve for `measured` to be true;
|
|
378
|
-
* missing descendants are partial but valid evidence. An unmeasurable target
|
|
379
|
-
* answers `{ busy: false, measured: false }` for the caller to classify.
|
|
380
|
-
*/
|
|
381
|
-
export async function sampleProcessTreeCpuPercent(pid, windowMs = 1200, floorPercent = 10) {
|
|
382
|
-
if (!Number.isFinite(pid) || pid <= 0) {
|
|
383
|
-
return { busy: false, measured: false, cpuPercent: null };
|
|
384
|
-
}
|
|
385
|
-
const targetPid = pid;
|
|
386
|
-
const readOnce = async () => {
|
|
387
|
-
try {
|
|
388
|
-
const descendants = runningOnWindows()
|
|
389
|
-
? await findDescendantPidsWindows(targetPid)
|
|
390
|
-
: [];
|
|
391
|
-
if (descendants === null)
|
|
392
|
-
return null;
|
|
393
|
-
const pids = runningOnWindows()
|
|
394
|
-
? [targetPid, ...descendants]
|
|
395
|
-
: [targetPid];
|
|
396
|
-
const usageByPid = await sampleProcesses(pids);
|
|
397
|
-
if (usageByPid === null)
|
|
398
|
-
return null;
|
|
399
|
-
const targetUsage = usageByPid.get(targetPid);
|
|
400
|
-
if (!targetUsage)
|
|
401
|
-
return { cpuPercent: 0, measured: false };
|
|
402
|
-
let cpuPercent = 0;
|
|
403
|
-
for (const usage of usageByPid.values())
|
|
404
|
-
cpuPercent += usage.cpuPercent;
|
|
405
|
-
return { cpuPercent, measured: true };
|
|
406
|
-
}
|
|
407
|
-
catch {
|
|
408
|
-
return null;
|
|
409
|
-
}
|
|
410
|
-
};
|
|
411
|
-
// The FIRST read is a BASELINE, not evidence: it re-anchors this pid's CPU
|
|
412
|
-
// history (Windows' own map, pidusage's on POSIX) so the second read is a
|
|
413
|
-
// rate over `windowMs` and nothing else. Both reads must retain the target;
|
|
414
|
-
// disappearance or query failure is explicitly unmeasured, never flat.
|
|
415
|
-
const first = await readOnce();
|
|
416
|
-
const second = await new Promise((resolve) => {
|
|
417
|
-
const timer = setTimeout(() => {
|
|
418
|
-
void readOnce().then(resolve);
|
|
419
|
-
}, windowMs);
|
|
420
|
-
timer.unref?.();
|
|
421
|
-
});
|
|
422
|
-
if (first === null && second === null) {
|
|
423
|
-
return { busy: false, measured: false, cpuPercent: null };
|
|
424
|
-
}
|
|
425
|
-
if (first === null ||
|
|
426
|
-
second === null ||
|
|
427
|
-
!first.measured ||
|
|
428
|
-
!second.measured) {
|
|
429
|
-
return { busy: false, measured: false, cpuPercent: null };
|
|
430
|
-
}
|
|
431
|
-
// #2358 (post-#2382): the verdict is the WINDOW read alone. Whatever the
|
|
432
|
-
// baseline read reports is a rate since the LAST caller's observation —
|
|
433
|
-
// clients/quiet-window.ts's heartbeat samples every recorded LSP child once
|
|
434
|
-
// per tick, and pidusage keeps 60 s of per-pid history — so folding it in
|
|
435
|
-
// (`Math.max(first, second)`) let CPU the process had already stopped
|
|
436
|
-
// burning vote "busy". A scanner that drained its burst and then wedged (the
|
|
437
|
-
// issue's own opengrep evidence) was therefore deferred as progressing and
|
|
438
|
-
// died at the hard cap, misrecorded as `cap-exceeded`, instead of being torn
|
|
439
|
-
// down on its budget as `budget-exceeded-cpu-flat`.
|
|
440
|
-
const observed = second.cpuPercent;
|
|
441
|
-
return {
|
|
442
|
-
busy: observed > floorPercent,
|
|
443
|
-
measured: true,
|
|
444
|
-
cpuPercent: observed,
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
|
-
/**
|
|
448
|
-
* Base poll cadence — inside #620's suggested 500ms-1s band, cheap enough not
|
|
449
|
-
* to become measurable overhead for the (usually sub-few-second) analyzer
|
|
450
|
-
* children this brackets.
|
|
451
|
-
*/
|
|
452
|
-
const SPAWN_SAMPLE_INTERVAL_MS = 750;
|
|
453
|
-
/**
|
|
454
|
-
* #2968: how many ticks keep the full `intervalMs` cadence before the backoff
|
|
455
|
-
* starts. 8 × 750ms = the first 6 seconds, which covers the short-lived
|
|
456
|
-
* analyzer children the short interval exists for; a child still running past
|
|
457
|
-
* that is not short-lived and does not need sub-second resolution.
|
|
458
|
-
*/
|
|
459
|
-
const SPAWN_SAMPLE_FULL_RATE_TICKS = 8;
|
|
460
|
-
/**
|
|
461
|
-
* #2968: backoff ceiling, as a multiple of `intervalMs` (16 × 750ms = 12s).
|
|
462
|
-
* Past the full-rate window the delay doubles each tick up to this, so a
|
|
463
|
-
* long-lived child costs a bounded ~5 polls/minute instead of 80.
|
|
464
|
-
*/
|
|
465
|
-
const SPAWN_SAMPLE_MAX_INTERVAL_MULTIPLIER = 16;
|
|
466
|
-
/**
|
|
467
|
-
* Brackets one transient spawn with a short-interval poll. Usage:
|
|
468
|
-
*
|
|
469
|
-
* const sampler = startSpawnUsageSampler(child.pid, interval, capMs);
|
|
470
|
-
* child.on("close", () => {
|
|
471
|
-
* const usage = sampler.stop(); // null if never got a single sample
|
|
472
|
-
* });
|
|
473
|
-
*
|
|
474
|
-
* Best-effort: a poll tick that throws (pid already gone, sampling error) is
|
|
475
|
-
* silently skipped — it never stops the polling or the spawn early, and
|
|
476
|
-
* `stop()` is always safe to call even if zero samples ever landed.
|
|
477
|
-
*
|
|
478
|
-
* Windows note: `clients/safe-spawn.ts` spawns with `shell: true` on Windows,
|
|
479
|
-
* so `pid` here is `cmd.exe`'s pid, not the real tool's — sampling it alone
|
|
480
|
-
* would report near-zero usage for the whole invocation. Each Windows tick
|
|
481
|
-
* resolves `pid`'s live descendant tree (`findDescendantPidsWindows`) and
|
|
482
|
-
* sums usage across `pid` + every descendant, so a `node`/`npx`-wrapped tool
|
|
483
|
-
* (or one that re-execs itself) is actually captured. POSIX spawns are
|
|
484
|
-
* unwrapped (`shell: false`), so `pid` there is already the real tool.
|
|
485
|
-
*
|
|
486
|
-
* ## Backpressure: three bounds, three axes (#2968, external report)
|
|
487
|
-
*
|
|
488
|
-
* A Windows tick is not free — it is TWO `powershell.exe` CIM queries (the
|
|
489
|
-
* descendant walk plus the usage read), and a query that blows
|
|
490
|
-
* `RESOURCE_SAMPLE_QUERY_TIMEOUT_MS` adds a `taskkill.exe`. With a `setInterval`
|
|
491
|
-
* that neither waited for its own tick nor ever expired, four children that
|
|
492
|
-
* hung for 5-6 hours left 234 live `powershell.exe`/`taskkill.exe` processes
|
|
493
|
-
* (~10GB) parented by the host. Each bound below closes one axis; catalog
|
|
494
|
-
* shape 9 is exactly the shape where closing only one of them is not a fix:
|
|
495
|
-
*
|
|
496
|
-
* 1. CONCURRENCY — a tick never starts while the previous one is unsettled
|
|
497
|
-
* (`inFlight`). The old `setInterval` fired regardless, so a query slower
|
|
498
|
-
* than the interval stacked one more pair of children every tick.
|
|
499
|
-
* 2. RATE — past `SPAWN_SAMPLE_FULL_RATE_TICKS` the delay doubles per tick up
|
|
500
|
-
* to `SPAWN_SAMPLE_MAX_INTERVAL_MULTIPLIER × intervalMs`. The short
|
|
501
|
-
* interval exists to catch short-lived children; a 180s runner (the
|
|
502
|
-
* longest spawn timeout in the tree) costs ~26 polls instead of 240.
|
|
503
|
-
* 3. LIFETIME — polling stops for good at `lifetimeCapMs`, measured from
|
|
504
|
-
* start. `stop()` still returns everything gathered up to that point; a
|
|
505
|
-
* capped sampler loses resolution, never the reading it already had. The
|
|
506
|
-
* cap is read at TICK granularity, so the last poll can land up to one
|
|
507
|
-
* backed-off interval (≤ 12s by default) before polling ends — the tick
|
|
508
|
-
* that discovers the cap does no sampling and arms nothing.
|
|
509
|
-
*
|
|
510
|
-
* Ticks skipped for (1) and the cap in (3) are both recorded, bounded, on the
|
|
511
|
-
* degradation ledger — a sampler that quietly stops sampling is the #1863 /
|
|
512
|
-
* #2132 shape one level up.
|
|
513
|
-
*
|
|
514
|
-
* `lifetimeCapMs` has no default ON PURPOSE: an unbounded sampler is the whole
|
|
515
|
-
* defect, so the bound is the caller's to state rather than something a future
|
|
516
|
-
* call site can forget. The cadence keeps its default, which is policy this
|
|
517
|
-
* module owns.
|
|
518
|
-
*/
|
|
519
|
-
export function startSpawnUsageSampler(pid, intervalMs = SPAWN_SAMPLE_INTERVAL_MS, lifetimeCapMs) {
|
|
520
|
-
if (!Number.isFinite(pid) || pid <= 0) {
|
|
521
|
-
return { stop: () => null };
|
|
522
|
-
}
|
|
523
|
-
const targetPid = pid;
|
|
524
|
-
const accumulator = new UsageAccumulator();
|
|
525
|
-
const startedAt = Date.now();
|
|
526
|
-
let stopped = false;
|
|
527
|
-
let inFlight = false;
|
|
528
|
-
let tickCount = 0;
|
|
529
|
-
let timer;
|
|
530
|
-
const tick = async () => {
|
|
531
|
-
if (stopped)
|
|
532
|
-
return;
|
|
533
|
-
try {
|
|
534
|
-
const descendants = runningOnWindows()
|
|
535
|
-
? await findDescendantPidsWindows(targetPid)
|
|
536
|
-
: [];
|
|
537
|
-
if (descendants === null)
|
|
538
|
-
return;
|
|
539
|
-
const pids = runningOnWindows()
|
|
540
|
-
? [targetPid, ...descendants]
|
|
541
|
-
: [targetPid];
|
|
542
|
-
const usageByPid = await sampleProcesses(pids);
|
|
543
|
-
if (usageByPid === null)
|
|
544
|
-
return;
|
|
545
|
-
if (stopped || usageByPid.size === 0)
|
|
546
|
-
return;
|
|
547
|
-
let rssBytes = 0;
|
|
548
|
-
let cpuPercent = 0;
|
|
549
|
-
for (const usage of usageByPid.values()) {
|
|
550
|
-
rssBytes += usage.rssBytes;
|
|
551
|
-
cpuPercent += usage.cpuPercent;
|
|
552
|
-
}
|
|
553
|
-
accumulator.addSample({ rssBytes, cpuPercent });
|
|
554
|
-
}
|
|
555
|
-
catch {
|
|
556
|
-
// Best-effort: a failed poll tick just misses one sample.
|
|
557
|
-
}
|
|
558
|
-
};
|
|
559
|
-
const releaseInFlight = () => {
|
|
560
|
-
inFlight = false;
|
|
561
|
-
};
|
|
562
|
-
/**
|
|
563
|
-
* Delay before the NEXT tick, given how many have already run. Full rate
|
|
564
|
-
* through the short-lived window, then doubling to the ceiling (#2968).
|
|
565
|
-
*/
|
|
566
|
-
const nextDelayMs = () => {
|
|
567
|
-
if (tickCount <= SPAWN_SAMPLE_FULL_RATE_TICKS)
|
|
568
|
-
return intervalMs;
|
|
569
|
-
const grown = intervalMs * 2 ** (tickCount - SPAWN_SAMPLE_FULL_RATE_TICKS);
|
|
570
|
-
return Math.min(grown, intervalMs * SPAWN_SAMPLE_MAX_INTERVAL_MULTIPLIER);
|
|
571
|
-
};
|
|
572
|
-
const arm = (delayMs) => {
|
|
573
|
-
timer = setTimeout(runTick, delayMs);
|
|
574
|
-
// Never let this timer keep the process alive on its own.
|
|
575
|
-
timer.unref?.();
|
|
576
|
-
};
|
|
577
|
-
function runTick() {
|
|
578
|
-
timer = undefined;
|
|
579
|
-
if (stopped)
|
|
580
|
-
return;
|
|
581
|
-
if (Date.now() - startedAt >= lifetimeCapMs) {
|
|
582
|
-
// LIFETIME bound: deliberately NOT re-armed. The accumulator is kept,
|
|
583
|
-
// so `stop()` still answers with everything gathered before the cap.
|
|
584
|
-
incrementDegradationCount({
|
|
585
|
-
kind: "resource-sampler-lifetime-capped",
|
|
586
|
-
subject: SPAWN_SAMPLER_LEDGER_SUBJECT,
|
|
587
|
-
reason: `spawn sampler stopped polling at its ${lifetimeCapMs}ms lifetime cap; the child was still running`,
|
|
588
|
-
});
|
|
589
|
-
return;
|
|
590
|
-
}
|
|
591
|
-
tickCount++;
|
|
592
|
-
if (inFlight) {
|
|
593
|
-
// CONCURRENCY bound: the previous tick's process-table queries have
|
|
594
|
-
// not settled, so starting another would stack a second set of
|
|
595
|
-
// children on top of them (#2968's Windows pile-up).
|
|
596
|
-
incrementDegradationCount({
|
|
597
|
-
kind: "resource-sampler-tick-overlapped",
|
|
598
|
-
subject: SPAWN_SAMPLER_LEDGER_SUBJECT,
|
|
599
|
-
reason: `spawn sampler skipped a poll tick: the previous sample was still in flight after ${intervalMs}ms`,
|
|
600
|
-
});
|
|
601
|
-
}
|
|
602
|
-
else {
|
|
603
|
-
inFlight = true;
|
|
604
|
-
// `tick` never rejects (it is fully guarded), but settle BOTH ways
|
|
605
|
-
// anyway: a rejection that escaped would otherwise latch `inFlight`
|
|
606
|
-
// true and silently end all sampling.
|
|
607
|
-
void tick().then(releaseInFlight, releaseInFlight);
|
|
608
|
-
}
|
|
609
|
-
arm(nextDelayMs());
|
|
610
|
-
}
|
|
611
|
-
// Fire one tick immediately (short-lived children can exit before the
|
|
612
|
-
// first interval elapses) plus a recurring poll.
|
|
613
|
-
tickCount = 1;
|
|
614
|
-
inFlight = true;
|
|
615
|
-
void tick().then(releaseInFlight, releaseInFlight);
|
|
616
|
-
arm(nextDelayMs());
|
|
617
|
-
return {
|
|
618
|
-
stop() {
|
|
619
|
-
if (stopped)
|
|
620
|
-
return accumulator.summarize();
|
|
621
|
-
stopped = true;
|
|
622
|
-
if (timer !== undefined)
|
|
623
|
-
clearTimeout(timer);
|
|
624
|
-
timer = undefined;
|
|
625
|
-
return accumulator.summarize();
|
|
626
|
-
},
|
|
627
|
-
};
|
|
628
|
-
}
|