@herbertgao/pi-extensions 2026.8.11 → 2026.8.13

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.
Files changed (476) hide show
  1. package/README.md +23 -10
  2. package/{node_modules/@herbertgao/pi-mermaid-open/LICENSE → THIRD_PARTY_NOTICES.md} +19 -1
  3. package/node_modules/@czottmann/pi-automode/CHANGELOG.md +15 -0
  4. package/node_modules/@czottmann/pi-automode/README.md +5 -3
  5. package/node_modules/@czottmann/pi-automode/docs/adr/ADR-001-permission-precedence-and-trust-boundaries.md +2 -0
  6. package/node_modules/@czottmann/pi-automode/docs/adr/ADR-002-global-config-in-extension-data-directory.md +60 -0
  7. package/node_modules/@czottmann/pi-automode/docs/adr/INDEX.md +1 -0
  8. package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +4 -4
  9. package/node_modules/@czottmann/pi-automode/docs/configuration.md +20 -4
  10. package/node_modules/@czottmann/pi-automode/docs/observability-logging.md +1 -1
  11. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/bash.ts +692 -0
  12. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +181 -3
  13. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +4 -1
  14. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +143 -36
  15. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +103 -148
  16. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +32 -6
  17. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +344 -22
  18. package/node_modules/@czottmann/pi-automode/extensions/auto-mode.ts +1 -0
  19. package/node_modules/@czottmann/pi-automode/package.json +4 -1
  20. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -1
  21. package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -1
  22. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +4 -0
  23. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +21 -1
  24. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +1 -1
  25. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +19 -19
  26. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +4 -2
  27. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +2 -1
  28. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +10 -2
  29. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  30. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +10 -0
  31. package/node_modules/@herbertgao/pi-subagents/README.md +21 -15
  32. package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
  33. package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +11 -8
  34. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +184 -106
  35. package/node_modules/@herbertgao/pi-subagents/src/cross-extension-rpc.ts +31 -11
  36. package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +9 -1
  37. package/node_modules/@herbertgao/pi-subagents/src/index.ts +156 -31
  38. package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +17 -0
  39. package/node_modules/@herbertgao/pi-subagents/src/model-resolver.ts +14 -0
  40. package/node_modules/@herbertgao/pi-subagents/src/schedule.ts +8 -0
  41. package/node_modules/@herbertgao/pi-subagents/src/settings.ts +32 -1
  42. package/node_modules/@herbertgao/pi-subagents/src/types.ts +17 -2
  43. package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +23 -2
  44. package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +259 -24
  45. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  46. package/node_modules/@luxusai/pi-hindsight/CHANGELOG.md +376 -0
  47. package/node_modules/@luxusai/pi-hindsight/README.md +92 -0
  48. package/node_modules/@luxusai/pi-hindsight/docs/adr/001-memory-lifecycle-and-scope.md +56 -0
  49. package/node_modules/@luxusai/pi-hindsight/docs/adr/002-explicit-routing-strategy-seam.md +169 -0
  50. package/node_modules/@luxusai/pi-hindsight/docs/adr/003-tui-memory-mode-vocabulary.md +107 -0
  51. package/node_modules/@luxusai/pi-hindsight/docs/adr/004-lifeos-dual-bank-design.md +89 -0
  52. package/node_modules/@luxusai/pi-hindsight/docs/adr/005-domain-banks-and-agent-first-surface.md +189 -0
  53. package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark.webp +0 -0
  54. package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark@2x.webp +0 -0
  55. package/node_modules/@luxusai/pi-hindsight/docs/coding-memory-evaluation.md +54 -0
  56. package/node_modules/@luxusai/pi-hindsight/docs/compatibility.md +75 -0
  57. package/node_modules/@luxusai/pi-hindsight/docs/hindsight-core-functions.md +300 -0
  58. package/node_modules/@luxusai/pi-hindsight/docs/mission-and-mental-model-quality.md +158 -0
  59. package/node_modules/@luxusai/pi-hindsight/docs/next-opt-out-design.md +164 -0
  60. package/node_modules/@luxusai/pi-hindsight/docs/risky-memory-modes.md +139 -0
  61. package/node_modules/@luxusai/pi-hindsight/docs/starter-mental-model-suggestions.md +74 -0
  62. package/node_modules/@luxusai/pi-hindsight/docs/surface-reference.md +261 -0
  63. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-operations.ts +151 -0
  64. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-selection.ts +18 -0
  65. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-settings-presenter.ts +46 -0
  66. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-templates.ts +383 -0
  67. package/node_modules/@luxusai/pi-hindsight/extensions/banks/banking.ts +240 -0
  68. package/node_modules/@luxusai/pi-hindsight/extensions/banks/knowledge-page-seed.ts +176 -0
  69. package/node_modules/@luxusai/pi-hindsight/extensions/banks/retain-strategies.ts +178 -0
  70. package/node_modules/@luxusai/pi-hindsight/extensions/client/client-retry.ts +41 -0
  71. package/node_modules/@luxusai/pi-hindsight/extensions/client/client.ts +386 -0
  72. package/node_modules/@luxusai/pi-hindsight/extensions/client/fetch-compat.ts +39 -0
  73. package/node_modules/@luxusai/pi-hindsight/extensions/client/timeout.ts +34 -0
  74. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-defaults.ts +140 -0
  75. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-model.ts +61 -0
  76. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-registry.ts +925 -0
  77. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-field-paths.ts +247 -0
  78. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-normalize.ts +547 -0
  79. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-writer.ts +480 -0
  80. package/node_modules/@luxusai/pi-hindsight/extensions/config/config.ts +182 -0
  81. package/node_modules/@luxusai/pi-hindsight/extensions/config/setup-gate.ts +86 -0
  82. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-execute.ts +1010 -0
  83. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-parse.ts +175 -0
  84. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-plan.ts +425 -0
  85. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-presentation.ts +210 -0
  86. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-sessions.ts +817 -0
  87. package/node_modules/@luxusai/pi-hindsight/extensions/index.ts +25 -0
  88. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/git-seed.ts +319 -0
  89. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-recall.ts +196 -0
  90. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-retain.ts +189 -0
  91. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-runtime.ts +65 -0
  92. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle.ts +260 -0
  93. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/mental-models.ts +244 -0
  94. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/observation-scopes.ts +59 -0
  95. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-cleanup.ts +82 -0
  96. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-visibility.ts +45 -0
  97. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall.ts +331 -0
  98. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-cursor.ts +354 -0
  99. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-job-builder.ts +66 -0
  100. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-receipts.ts +132 -0
  101. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain.ts +228 -0
  102. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-bank-template-operations.ts +74 -0
  103. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-config-operations.ts +16 -0
  104. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-control-operations.ts +648 -0
  105. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-diagnostics-operations.ts +105 -0
  106. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-identity.ts +68 -0
  107. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-service.ts +71 -0
  108. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-types.ts +13 -0
  109. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-recall-operations.ts +162 -0
  110. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-retain-operations.ts +131 -0
  111. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-scope.ts +104 -0
  112. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-session-operations.ts +37 -0
  113. package/node_modules/@luxusai/pi-hindsight/extensions/operations/operation-catalog.ts +893 -0
  114. package/node_modules/@luxusai/pi-hindsight/extensions/operations/reflect-presenter.ts +35 -0
  115. package/node_modules/@luxusai/pi-hindsight/extensions/operations/scope-migrate.ts +177 -0
  116. package/node_modules/@luxusai/pi-hindsight/extensions/operations/tools.ts +7 -0
  117. package/node_modules/@luxusai/pi-hindsight/extensions/queue/flush-presenter.ts +21 -0
  118. package/node_modules/@luxusai/pi-hindsight/extensions/queue/jsonl-queue-store.ts +112 -0
  119. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-delivery.ts +111 -0
  120. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-lock.ts +214 -0
  121. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-operations.ts +70 -0
  122. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue.ts +392 -0
  123. package/node_modules/@luxusai/pi-hindsight/extensions/tui/bank-template-presentation.ts +45 -0
  124. package/node_modules/@luxusai/pi-hindsight/extensions/tui/commands.ts +9 -0
  125. package/node_modules/@luxusai/pi-hindsight/extensions/tui/guided-setup.ts +860 -0
  126. package/node_modules/@luxusai/pi-hindsight/extensions/tui/prefill-input.ts +105 -0
  127. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-flow.ts +189 -0
  128. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-server-probe.ts +299 -0
  129. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-actions.ts +201 -0
  130. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-facts.ts +47 -0
  131. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-render.ts +239 -0
  132. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-types.ts +50 -0
  133. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui.ts +259 -0
  134. package/node_modules/@luxusai/pi-hindsight/extensions/tui/tool-presenters.ts +77 -0
  135. package/node_modules/@luxusai/pi-hindsight/extensions/types.ts +534 -0
  136. package/node_modules/@luxusai/pi-hindsight/extensions/utils/diagnostics.ts +319 -0
  137. package/node_modules/@luxusai/pi-hindsight/extensions/utils/messages.ts +325 -0
  138. package/node_modules/@luxusai/pi-hindsight/extensions/utils/sanitize.ts +42 -0
  139. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-memory-meta.ts +244 -0
  140. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-operations.ts +56 -0
  141. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session.ts +50 -0
  142. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-fields.ts +167 -0
  143. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-health.ts +207 -0
  144. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status.ts +120 -0
  145. package/node_modules/@luxusai/pi-hindsight/extensions/version.ts +8 -0
  146. package/node_modules/@luxusai/pi-hindsight/package.json +118 -0
  147. package/node_modules/@luxusai/pi-hindsight/skills/hindsight-memory-doctor/SKILL.md +75 -0
  148. package/node_modules/@narumitw/pi-btw/dist/index.ts +143 -46
  149. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
  150. package/node_modules/@narumitw/pi-btw/package.json +6 -6
  151. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +136 -22
  152. package/node_modules/{@herbertgao → @tifan}/pi-copy-response/README.md +2 -4
  153. package/node_modules/{@herbertgao → @tifan}/pi-copy-response/package.json +5 -15
  154. package/node_modules/{@herbertgao → @tifan}/pi-handoff/README.md +4 -6
  155. package/node_modules/@tifan/pi-handoff/package.json +43 -0
  156. package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/index.ts +1 -1
  157. package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/README.md +2 -4
  158. package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/package.json +5 -15
  159. package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/README.md +5 -7
  160. package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/package.json +5 -19
  161. package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/README.md +4 -6
  162. package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/package.json +6 -16
  163. package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/src/index.ts +1 -6
  164. package/node_modules/{@herbertgao → @tifan}/pi-recap/README.md +4 -6
  165. package/node_modules/@tifan/pi-recap/package.json +42 -0
  166. package/node_modules/{@herbertgao → @tifan}/pi-recap/src/models.ts +1 -6
  167. package/node_modules/{@herbertgao → @tifan}/pi-rename/README.md +13 -8
  168. package/node_modules/@tifan/pi-rename/package.json +47 -0
  169. package/node_modules/@tifan/pi-rename/src/herdr-label.ts +4 -0
  170. package/node_modules/{@herbertgao → @tifan}/pi-rename/src/index.ts +4 -16
  171. package/node_modules/{@herbertgao → @tifan}/pi-rename/src/models.ts +1 -6
  172. package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/README.md +2 -4
  173. package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/package.json +5 -15
  174. package/node_modules/pi-lens/CHANGELOG.md +96 -1
  175. package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -1
  176. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +14 -5
  177. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +48 -18
  178. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +1 -3
  179. package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +16 -4
  180. package/node_modules/pi-lens/dist/clients/bash-file-access.js +3 -1
  181. package/node_modules/pi-lens/dist/clients/biome-client.js +1 -3
  182. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +21 -8
  183. package/node_modules/pi-lens/dist/clients/bounded-cache.js +24 -8
  184. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +4 -3
  185. package/node_modules/pi-lens/dist/clients/cache-manager.js +6 -7
  186. package/node_modules/pi-lens/dist/clients/cache-observability.js +461 -66
  187. package/node_modules/pi-lens/dist/clients/call-graph.js +238 -63
  188. package/node_modules/pi-lens/dist/clients/codebase-model.js +13 -5
  189. package/node_modules/pi-lens/dist/clients/complexity-client.js +1 -3
  190. package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -8
  191. package/node_modules/pi-lens/dist/clients/dead-code-logger.js +1 -2
  192. package/node_modules/pi-lens/dist/clients/deadline-utils.js +3 -1
  193. package/node_modules/pi-lens/dist/clients/debug-heap.js +8 -1
  194. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +1 -1
  195. package/node_modules/pi-lens/dist/clients/dependency-checker.js +11 -7
  196. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +39 -2
  197. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +5 -1
  198. package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +2 -3
  199. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +13 -1
  200. package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +3 -1
  201. package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +2 -1
  202. package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +1 -1
  203. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +9 -4
  204. package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +3 -1
  205. package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +6 -2
  206. package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +31 -7
  207. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +5 -2
  208. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +10 -14
  209. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +5 -1
  210. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +1 -1
  211. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +3 -1
  212. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +25 -6
  213. package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +1 -1
  214. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +1 -1
  215. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +3 -1
  216. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +13 -8
  217. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +4 -1
  218. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +25 -10
  219. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +1 -1
  220. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +1 -1
  221. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +1 -1
  222. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +28 -4
  223. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +6 -8
  224. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +212 -11
  225. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +1 -1
  226. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +8 -4
  227. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +10 -6
  228. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +23 -14
  229. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -1
  230. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +7 -9
  231. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +5 -2
  232. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +7 -7
  233. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +6 -8
  234. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +13 -8
  235. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +13 -8
  236. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +17 -3
  237. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +7 -1
  238. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +24 -1
  239. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +35 -0
  240. package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +1 -3
  241. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +6 -8
  242. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +1 -1
  243. package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +2 -1
  244. package/node_modules/pi-lens/dist/clients/dispatch/types.js +6 -1
  245. package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +6 -2
  246. package/node_modules/pi-lens/dist/clients/extension-log.js +5 -3
  247. package/node_modules/pi-lens/dist/clients/feature-hints.js +8 -1
  248. package/node_modules/pi-lens/dist/clients/file-kinds.js +34 -129
  249. package/node_modules/pi-lens/dist/clients/file-utils.js +17 -1
  250. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +57 -2
  251. package/node_modules/pi-lens/dist/clients/formatters.js +144 -27
  252. package/node_modules/pi-lens/dist/clients/freshness.js +38 -0
  253. package/node_modules/pi-lens/dist/clients/git-guard.js +43 -13
  254. package/node_modules/pi-lens/dist/clients/go-client.js +1 -3
  255. package/node_modules/pi-lens/dist/clients/grammar-source.js +1 -1
  256. package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +30 -4
  257. package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +1 -3
  258. package/node_modules/pi-lens/dist/clients/install-diagnostics.js +4 -2
  259. package/node_modules/pi-lens/dist/clients/installer/index.js +86 -77
  260. package/node_modules/pi-lens/dist/clients/instance-reaper.js +5 -2
  261. package/node_modules/pi-lens/dist/clients/instance-registry.js +4 -2
  262. package/node_modules/pi-lens/dist/clients/jscpd-client.js +6 -1
  263. package/node_modules/pi-lens/dist/clients/knip-client.js +29 -15
  264. package/node_modules/pi-lens/dist/clients/language-profile.js +4 -1
  265. package/node_modules/pi-lens/dist/clients/latency-logger.js +13 -2
  266. package/node_modules/pi-lens/dist/clients/lens-config.js +1 -1
  267. package/node_modules/pi-lens/dist/clients/lens-map.js +8 -3
  268. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +1 -1
  269. package/node_modules/pi-lens/dist/clients/lsp/config.js +4 -6
  270. package/node_modules/pi-lens/dist/clients/lsp/edits.js +119 -32
  271. package/node_modules/pi-lens/dist/clients/lsp/index.js +94 -35
  272. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +2 -1
  273. package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +4 -1
  274. package/node_modules/pi-lens/dist/clients/lsp/launch.js +11 -3
  275. package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +152 -0
  276. package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -7
  277. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +10 -2
  278. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +9 -4
  279. package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -3
  280. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +10 -20
  281. package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +1 -1
  282. package/node_modules/pi-lens/dist/clients/memory-sampler.js +73 -7
  283. package/node_modules/pi-lens/dist/clients/metrics-client.js +1 -3
  284. package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +8 -3
  285. package/node_modules/pi-lens/dist/clients/module-report-lsp.js +7 -1
  286. package/node_modules/pi-lens/dist/clients/module-report.js +14 -17
  287. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +3 -5
  288. package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +220 -0
  289. package/node_modules/pi-lens/dist/clients/package-manager.js +6 -1
  290. package/node_modules/pi-lens/dist/clients/pipeline.js +57 -9
  291. package/node_modules/pi-lens/dist/clients/project-conventions.js +2 -8
  292. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +10 -7
  293. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +2 -1
  294. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +3 -1
  295. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +13 -9
  296. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +3 -1
  297. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -2
  298. package/node_modules/pi-lens/dist/clients/project-lens-config.js +12 -5
  299. package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +48 -0
  300. package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +15 -1
  301. package/node_modules/pi-lens/dist/clients/project-snapshot.js +472 -66
  302. package/node_modules/pi-lens/dist/clients/read-expansion.js +12 -2
  303. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +5 -4
  304. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +5 -2
  305. package/node_modules/pi-lens/dist/clients/read-guard.js +1 -1
  306. package/node_modules/pi-lens/dist/clients/resource-sampler.js +1 -1
  307. package/node_modules/pi-lens/dist/clients/reverse-deps.js +6 -5
  308. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +42 -17
  309. package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +8 -2
  310. package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +10 -1
  311. package/node_modules/pi-lens/dist/clients/review-graph/query.js +2 -1
  312. package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +4 -2
  313. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +2 -2
  314. package/node_modules/pi-lens/dist/clients/ruff-client.js +6 -5
  315. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +63 -31
  316. package/node_modules/pi-lens/dist/clients/runtime-context.js +12 -4
  317. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +83 -4
  318. package/node_modules/pi-lens/dist/clients/runtime-session.js +14 -0
  319. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +59 -3
  320. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +148 -34
  321. package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -6
  322. package/node_modules/pi-lens/dist/clients/rust-client.js +1 -3
  323. package/node_modules/pi-lens/dist/clients/safe-spawn.js +150 -11
  324. package/node_modules/pi-lens/dist/clients/security-scan-client.js +1 -3
  325. package/node_modules/pi-lens/dist/clients/session-summary.js +3 -1
  326. package/node_modules/pi-lens/dist/clients/sg-runner.js +1 -3
  327. package/node_modules/pi-lens/dist/clients/source-filter.js +10 -6
  328. package/node_modules/pi-lens/dist/clients/source-walker.js +1 -1
  329. package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +96 -0
  330. package/node_modules/pi-lens/dist/clients/startup-scan.js +4 -1
  331. package/node_modules/pi-lens/dist/clients/tool-definition.js +7 -0
  332. package/node_modules/pi-lens/dist/clients/tool-policy.js +26 -11
  333. package/node_modules/pi-lens/dist/clients/tool-render.js +2 -1
  334. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +10 -4
  335. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
  336. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +12 -5
  337. package/node_modules/pi-lens/dist/clients/warm-attach.js +12 -5
  338. package/node_modules/pi-lens/dist/clients/widget-state.js +27 -11
  339. package/node_modules/pi-lens/dist/clients/word-index.js +3 -1
  340. package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -2
  341. package/node_modules/pi-lens/dist/clients/zizmor-config.js +9 -1
  342. package/node_modules/pi-lens/dist/i18n.js +13 -5
  343. package/node_modules/pi-lens/dist/index.js +10797 -8627
  344. package/node_modules/pi-lens/dist/mcp/server.js +3 -1
  345. package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +68 -12
  346. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +21 -7
  347. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +164 -35
  348. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +24 -7
  349. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +3 -1
  350. package/node_modules/pi-lens/dist/tools/module-report.js +1 -1
  351. package/node_modules/pi-lens/dist/tools/project-report.js +1 -1
  352. package/node_modules/pi-lens/dist/tools/symbol-search.js +5 -2
  353. package/node_modules/pi-lens/docs/durable-store-audit-1202.md +1 -1
  354. package/node_modules/pi-lens/docs/servercapabilities.md +1 -1
  355. package/node_modules/pi-lens/package.json +160 -156
  356. package/node_modules/pi-lens/rules/typos/_typos.toml +2 -2
  357. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +31 -13
  358. package/node_modules/pi-lens/scripts/download-grammars.js +9 -3
  359. package/node_modules/pi-lens/scripts/rpc-load-check.mjs +30 -9
  360. package/node_modules/pi-mcp-adapter/CHANGELOG.md +47 -0
  361. package/node_modules/pi-mcp-adapter/README.md +42 -13
  362. package/node_modules/pi-mcp-adapter/commands.ts +4 -2
  363. package/node_modules/pi-mcp-adapter/config.ts +45 -5
  364. package/node_modules/pi-mcp-adapter/direct-tools.ts +103 -92
  365. package/node_modules/pi-mcp-adapter/dist/agent-dir.d.ts +10 -0
  366. package/node_modules/pi-mcp-adapter/dist/agent-dir.js +63 -0
  367. package/node_modules/pi-mcp-adapter/dist/agent-dir.js.map +1 -0
  368. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.d.ts +8 -0
  369. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js +356 -0
  370. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js.map +1 -0
  371. package/node_modules/pi-mcp-adapter/dist/config.d.ts +123 -0
  372. package/node_modules/pi-mcp-adapter/dist/config.js +1087 -0
  373. package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -0
  374. package/node_modules/pi-mcp-adapter/dist/metadata-cache.d.ts +19 -0
  375. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +319 -0
  376. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +1 -0
  377. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.d.ts +2 -0
  378. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js +156 -0
  379. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js.map +1 -0
  380. package/node_modules/pi-mcp-adapter/dist/resource-tools.d.ts +1 -0
  381. package/node_modules/pi-mcp-adapter/dist/resource-tools.js +15 -0
  382. package/node_modules/pi-mcp-adapter/dist/resource-tools.js.map +1 -0
  383. package/node_modules/pi-mcp-adapter/dist/types.d.ts +564 -0
  384. package/node_modules/pi-mcp-adapter/dist/types.js +287 -0
  385. package/node_modules/pi-mcp-adapter/dist/types.js.map +1 -0
  386. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.d.ts +6 -0
  387. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js +37 -0
  388. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js.map +1 -0
  389. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.d.ts +104 -0
  390. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js +59 -0
  391. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js.map +1 -0
  392. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.d.ts +4 -0
  393. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js +27 -0
  394. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js.map +1 -0
  395. package/node_modules/pi-mcp-adapter/dist/utils.d.ts +32 -0
  396. package/node_modules/pi-mcp-adapter/dist/utils.js +338 -0
  397. package/node_modules/pi-mcp-adapter/dist/utils.js.map +1 -0
  398. package/node_modules/pi-mcp-adapter/failure-backoff.ts +23 -0
  399. package/node_modules/pi-mcp-adapter/index.ts +204 -82
  400. package/node_modules/pi-mcp-adapter/init.ts +41 -30
  401. package/node_modules/pi-mcp-adapter/lifecycle.ts +16 -8
  402. package/node_modules/pi-mcp-adapter/mcp-code.ts +2 -0
  403. package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +66 -16
  404. package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +95 -7
  405. package/node_modules/pi-mcp-adapter/mcp-probe.ts +18 -4
  406. package/node_modules/pi-mcp-adapter/mcp-references.ts +368 -0
  407. package/node_modules/pi-mcp-adapter/mcp-status.ts +8 -19
  408. package/node_modules/pi-mcp-adapter/metadata-cache.ts +20 -12
  409. package/node_modules/pi-mcp-adapter/namespace-tools.ts +276 -0
  410. package/node_modules/pi-mcp-adapter/package.json +24 -6
  411. package/node_modules/pi-mcp-adapter/proxy-modes.ts +66 -10
  412. package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -0
  413. package/node_modules/pi-mcp-adapter/server-manager.ts +63 -12
  414. package/node_modules/pi-mcp-adapter/state.ts +1 -3
  415. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +16 -2
  416. package/node_modules/pi-mcp-adapter/types.ts +48 -1
  417. package/node_modules/pi-mcp-adapter/ui-server.ts +3 -19
  418. package/node_modules/pi-mcp-adapter/ui-session.ts +2 -1
  419. package/node_modules/pi-mcp-adapter/utils.ts +21 -19
  420. package/node_modules/pi-web-access/CHANGELOG.md +26 -0
  421. package/node_modules/pi-web-access/README.md +71 -14
  422. package/node_modules/pi-web-access/chrome-cookies.ts +115 -35
  423. package/node_modules/pi-web-access/credential-source.ts +6 -2
  424. package/node_modules/pi-web-access/curator-page.ts +5 -3
  425. package/node_modules/pi-web-access/curator-server.ts +2 -1
  426. package/node_modules/pi-web-access/extract.ts +89 -9
  427. package/node_modules/pi-web-access/fetch-params.ts +13 -0
  428. package/node_modules/pi-web-access/gemini-adc.ts +298 -0
  429. package/node_modules/pi-web-access/gemini-api.ts +59 -15
  430. package/node_modules/pi-web-access/gemini-search.ts +58 -18
  431. package/node_modules/pi-web-access/gemini-url-context.ts +3 -2
  432. package/node_modules/pi-web-access/gemini-web-config.ts +57 -7
  433. package/node_modules/pi-web-access/gemini-web.ts +9 -3
  434. package/node_modules/pi-web-access/github-api.ts +5 -4
  435. package/node_modules/pi-web-access/github-issue-pr.ts +700 -0
  436. package/node_modules/pi-web-access/index.ts +403 -297
  437. package/node_modules/pi-web-access/kimi-search.ts +234 -0
  438. package/node_modules/pi-web-access/openai-search.ts +118 -21
  439. package/node_modules/pi-web-access/package.json +3 -2
  440. package/node_modules/pi-web-access/ssrf-protection.ts +4 -1
  441. package/node_modules/pi-web-access/utils.ts +307 -1
  442. package/node_modules/pi-web-access/youtube-extract.ts +2 -2
  443. package/package.json +46 -37
  444. package/node_modules/@herbertgao/pi-copy-response/CHANGELOG.md +0 -49
  445. package/node_modules/@herbertgao/pi-copy-response/LICENSE +0 -22
  446. package/node_modules/@herbertgao/pi-handoff/CHANGELOG.md +0 -83
  447. package/node_modules/@herbertgao/pi-handoff/LICENSE +0 -22
  448. package/node_modules/@herbertgao/pi-handoff/package.json +0 -60
  449. package/node_modules/@herbertgao/pi-inline-skills/CHANGELOG.md +0 -57
  450. package/node_modules/@herbertgao/pi-inline-skills/LICENSE +0 -22
  451. package/node_modules/@herbertgao/pi-mermaid-open/CHANGELOG.md +0 -39
  452. package/node_modules/@herbertgao/pi-preferred-thinking/CHANGELOG.md +0 -63
  453. package/node_modules/@herbertgao/pi-preferred-thinking/LICENSE +0 -22
  454. package/node_modules/@herbertgao/pi-recap/CHANGELOG.md +0 -101
  455. package/node_modules/@herbertgao/pi-recap/LICENSE +0 -22
  456. package/node_modules/@herbertgao/pi-recap/package.json +0 -55
  457. package/node_modules/@herbertgao/pi-rename/CHANGELOG.md +0 -49
  458. package/node_modules/@herbertgao/pi-rename/LICENSE +0 -22
  459. package/node_modules/@herbertgao/pi-rename/package.json +0 -63
  460. package/node_modules/@herbertgao/pi-titlebar-spinner/CHANGELOG.md +0 -25
  461. package/node_modules/@herbertgao/pi-titlebar-spinner/LICENSE +0 -22
  462. /package/node_modules/{@herbertgao → @tifan}/pi-copy-response/src/index.ts +0 -0
  463. /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/complete-text.ts +0 -0
  464. /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/session-query.ts +0 -0
  465. /package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/src/index.ts +0 -0
  466. /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/herdr-plugin.toml +0 -0
  467. /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/viewer.mjs +0 -0
  468. /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/src/index.ts +0 -0
  469. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/index.ts +0 -0
  470. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/model-picker.ts +0 -0
  471. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/sanitize.ts +0 -0
  472. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/tui.ts +0 -0
  473. /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/model-picker.ts +0 -0
  474. /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/naming.ts +0 -0
  475. /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/sanitize.ts +0 -0
  476. /package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/src/index.ts +0 -0
@@ -38,7 +38,9 @@ function severityForDepth(depth) {
38
38
  export function impact(graph, startKey, maxDepth = 3, minWeight = 0.1) {
39
39
  const results = [];
40
40
  const visited = new Set([startKey]);
41
- const queue = [{ key: startKey, depth: 0 }];
41
+ const queue = [
42
+ { key: startKey, depth: 0 },
43
+ ];
42
44
  // Build a weight lookup from edges for filtering
43
45
  const edgeWeightMap = new Map();
44
46
  for (const edge of graph.edges) {
@@ -63,7 +65,11 @@ export function impact(graph, startKey, maxDepth = 3, minWeight = 0.1) {
63
65
  continue;
64
66
  visited.add(callerKey);
65
67
  const depth = item.depth + 1;
66
- results.push({ symbolKey: callerKey, depth, severity: severityForDepth(depth) });
68
+ results.push({
69
+ symbolKey: callerKey,
70
+ depth,
71
+ severity: severityForDepth(depth),
72
+ });
67
73
  queue.push({ key: callerKey, depth });
68
74
  }
69
75
  }
@@ -101,10 +107,16 @@ export function formatImpact(results, projectRoot) {
101
107
  return file ? `${name} (${file})` : name;
102
108
  };
103
109
  if (willBreak.length > 0) {
104
- parts.push(willBreak.slice(0, 3).map((r) => `${label(r)} ⚠ WillBreak`).join(", "));
110
+ parts.push(willBreak
111
+ .slice(0, 3)
112
+ .map((r) => `${label(r)} ⚠ WillBreak`)
113
+ .join(", "));
105
114
  }
106
115
  if (mayBreak.length > 0) {
107
- parts.push(mayBreak.slice(0, 2).map((r) => `${label(r)} MayBreak`).join(", "));
116
+ parts.push(mayBreak
117
+ .slice(0, 2)
118
+ .map((r) => `${label(r)} MayBreak`)
119
+ .join(", "));
108
120
  }
109
121
  if (review.length > 0) {
110
122
  parts.push(`${review.length} Review caller${review.length === 1 ? "" : "s"}`);
@@ -118,25 +130,106 @@ export function formatImpact(results, projectRoot) {
118
130
  */
119
131
  const STDLIB_NAMES = new Set([
120
132
  // JS/TS
121
- "console", "Math", "Object", "Array", "String", "Number", "Boolean",
122
- "Promise", "Error", "Map", "Set", "WeakMap", "WeakSet", "JSON", "Date",
123
- "RegExp", "Symbol", "BigInt", "parseInt", "parseFloat", "isNaN",
124
- "isFinite", "setTimeout", "clearTimeout", "setInterval", "clearInterval",
125
- "fetch", "URL", "URLSearchParams", "Buffer", "process", "require",
133
+ "console",
134
+ "Math",
135
+ "Object",
136
+ "Array",
137
+ "String",
138
+ "Number",
139
+ "Boolean",
140
+ "Promise",
141
+ "Error",
142
+ "Map",
143
+ "Set",
144
+ "WeakMap",
145
+ "WeakSet",
146
+ "JSON",
147
+ "Date",
148
+ "RegExp",
149
+ "Symbol",
150
+ "BigInt",
151
+ "parseInt",
152
+ "parseFloat",
153
+ "isNaN",
154
+ "isFinite",
155
+ "setTimeout",
156
+ "clearTimeout",
157
+ "setInterval",
158
+ "clearInterval",
159
+ "fetch",
160
+ "URL",
161
+ "URLSearchParams",
162
+ "Buffer",
163
+ "process",
164
+ "require",
126
165
  // Python
127
- "print", "len", "range", "list", "dict", "str", "int", "float", "bool",
128
- "open", "isinstance", "issubclass", "type", "super", "hasattr", "getattr",
129
- "setattr", "enumerate", "zip", "map", "filter", "sorted", "reversed",
166
+ "print",
167
+ "len",
168
+ "range",
169
+ "list",
170
+ "dict",
171
+ "str",
172
+ "int",
173
+ "float",
174
+ "bool",
175
+ "open",
176
+ "isinstance",
177
+ "issubclass",
178
+ "type",
179
+ "super",
180
+ "hasattr",
181
+ "getattr",
182
+ "setattr",
183
+ "enumerate",
184
+ "zip",
185
+ "map",
186
+ "filter",
187
+ "sorted",
188
+ "reversed",
130
189
  // Go
131
- "fmt", "log", "os", "io", "err", "make", "append", "cap", "copy",
132
- "close", "delete", "panic", "recover", "new",
190
+ "fmt",
191
+ "log",
192
+ "os",
193
+ "io",
194
+ "err",
195
+ "make",
196
+ "append",
197
+ "cap",
198
+ "copy",
199
+ "close",
200
+ "delete",
201
+ "panic",
202
+ "recover",
203
+ "new",
133
204
  // Rust
134
- "eprintln", "eprint", "vec", "Some", "None", "Ok", "Err",
135
- "Box", "Rc", "Arc", "Vec", "HashMap", "HashSet", "format",
205
+ "eprintln",
206
+ "eprint",
207
+ "vec",
208
+ "Some",
209
+ "None",
210
+ "Ok",
211
+ "Err",
212
+ "Box",
213
+ "Rc",
214
+ "Arc",
215
+ "Vec",
216
+ "HashMap",
217
+ "HashSet",
218
+ "format",
136
219
  // Java/Kotlin
137
- "System", "toString", "equals", "hashCode", "Objects",
220
+ "System",
221
+ "toString",
222
+ "equals",
223
+ "hashCode",
224
+ "Objects",
138
225
  // Generic
139
- "this", "self", "nil", "null", "undefined", "true", "false",
226
+ "this",
227
+ "self",
228
+ "nil",
229
+ "null",
230
+ "undefined",
231
+ "true",
232
+ "false",
140
233
  ]);
141
234
  // ── Core resolution ────────────────────────────────────────────────────────────
142
235
  /**
@@ -253,7 +346,9 @@ allRefs, inputCoverage) {
253
346
  // Canonical graph identity is authoritative. Never recover a name by
254
347
  // splitting an id: symbol ids contain kind and line components.
255
348
  const callee = defIndex.byId.get(ref.targetId);
256
- if (!callee || ref.resolution === "name-only" || ref.resolution === "unresolved") {
349
+ if (!callee ||
350
+ ref.resolution === "name-only" ||
351
+ ref.resolution === "unresolved") {
257
352
  if (!hasInputCoverage) {
258
353
  unresolvedRefs++;
259
354
  coverage.unresolvedEvidence++;
@@ -271,7 +366,9 @@ allRefs, inputCoverage) {
271
366
  // There is no typed/import evidence to select one definition, so retain
272
367
  // every cross-file candidate and discount each edge. Picking [0] made
273
368
  // graph iteration order decide which caller was reported.
274
- const refName = ref.symbolName ?? parseSymbolKey(ref.symbolId, callerFile).symbolName ?? "";
369
+ const refName = ref.symbolName ??
370
+ parseSymbolKey(ref.symbolId, callerFile).symbolName ??
371
+ "";
275
372
  if (STDLIB_NAMES.has(refName) || !refName) {
276
373
  if (!hasInputCoverage)
277
374
  coverage.unsupportedEvidence++;
@@ -287,7 +384,8 @@ allRefs, inputCoverage) {
287
384
  }
288
385
  const crossFileDefs = defs
289
386
  .map((id) => defIndex.byId.get(id))
290
- .filter((candidate) => candidate !== undefined && normalizeMapKey(candidate.filePath) !== callerFileKey);
387
+ .filter((candidate) => candidate !== undefined &&
388
+ normalizeMapKey(candidate.filePath) !== callerFileKey);
291
389
  if (crossFileDefs.length === 0) {
292
390
  if (!hasInputCoverage)
293
391
  coverage.unsupportedEvidence++;
@@ -295,10 +393,15 @@ allRefs, inputCoverage) {
295
393
  }
296
394
  const resolution = crossFileDefs.length === 1 ? "exact" : "name-only";
297
395
  for (const callee of crossFileDefs) {
298
- candidates.push({ callee, resolution, candidateCount: crossFileDefs.length });
396
+ candidates.push({
397
+ callee,
398
+ resolution,
399
+ candidateCount: crossFileDefs.length,
400
+ });
299
401
  }
300
402
  }
301
- if (ref.evidenceKind && candidates.some(({ resolution }) => resolution === "name-only")) {
403
+ if (ref.evidenceKind &&
404
+ candidates.some(({ resolution }) => resolution === "name-only")) {
302
405
  if (!hasInputCoverage) {
303
406
  unresolvedRefs++;
304
407
  coverage.unresolvedEvidence++;
@@ -331,9 +434,10 @@ allRefs, inputCoverage) {
331
434
  const existing = edgeByPair.get(pairKey);
332
435
  if (existing) {
333
436
  existing.evidenceCount = (existing.evidenceCount ?? 1) + 1;
334
- existing.evidenceKind = existing.evidenceKind === ref.evidenceKind
335
- ? existing.evidenceKind
336
- : "mixed";
437
+ existing.evidenceKind =
438
+ existing.evidenceKind === ref.evidenceKind
439
+ ? existing.evidenceKind
440
+ : "mixed";
337
441
  // Duplicate evidence is a property of the logical pair, not of
338
442
  // whether the producer happened to tag the record. Keep the edge,
339
443
  // coverage, and centrality views consistent for legacy refs too.
@@ -388,15 +492,20 @@ allRefs, inputCoverage) {
388
492
  if (hasInputCoverage)
389
493
  totalRefs = coverage.totalEvidence;
390
494
  const languagesKnownComplete = Object.values(coverage.languages ?? {}).every((status) => status === "complete");
391
- coverage.complete = coverage.complete && hasInputCoverage &&
392
- coverage.unsupportedEvidence === 0 && languagesKnownComplete &&
393
- (allSymbols.size > 0 || coverage.totalEvidence > 0);
495
+ coverage.complete =
496
+ coverage.complete &&
497
+ hasInputCoverage &&
498
+ coverage.unsupportedEvidence === 0 &&
499
+ languagesKnownComplete &&
500
+ (allSymbols.size > 0 || coverage.totalEvidence > 0);
394
501
  return {
395
502
  callees,
396
503
  callers,
397
504
  inDegree,
398
505
  edges: [...edgeByPair.values()],
399
- unresolvedRefs: hasInputCoverage ? coverage.unresolvedEvidence : unresolvedRefs,
506
+ unresolvedRefs: hasInputCoverage
507
+ ? coverage.unresolvedEvidence
508
+ : unresolvedRefs,
400
509
  totalRefs,
401
510
  coverage,
402
511
  builtAt: new Date().toISOString(),
@@ -433,7 +542,10 @@ export function saveCallGraph(cwd, graph, identity) {
433
542
  coverage: graph.coverage,
434
543
  };
435
544
  writeFileAtomic(cacheFile, JSON.stringify(persisted));
436
- writeFileAtomic(metaFile, JSON.stringify({ savedAt: new Date().toISOString(), edgeCount: graph.edges.length }));
545
+ writeFileAtomic(metaFile, JSON.stringify({
546
+ savedAt: new Date().toISOString(),
547
+ edgeCount: graph.edges.length,
548
+ }));
437
549
  }
438
550
  catch {
439
551
  // Non-fatal — next session rebuilds from scratch.
@@ -485,21 +597,36 @@ function finiteCount(value) {
485
597
  return typeof value === "number" && Number.isInteger(value) && value >= 0;
486
598
  }
487
599
  function countsMatch(left, right) {
488
- return Math.abs(left - right) <= 1e-9 * Math.max(1, Math.abs(left), Math.abs(right));
600
+ return (Math.abs(left - right) <=
601
+ 1e-9 * Math.max(1, Math.abs(left), Math.abs(right)));
489
602
  }
490
603
  function validatePersistedCallGraph(raw, coverage) {
491
604
  const nonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
492
605
  const enumValue = (value, values) => typeof value === "string" && values.includes(value);
493
606
  const edgeKinds = ["calls", "references", "mixed"];
494
- const resolutions = ["exact", "import", "receiver-type", "name-only", "unresolved"];
495
- if (!raw || raw.version !== CALL_GRAPH_CACHE_VERSION || !nonEmptyString(raw.builtAt))
607
+ const resolutions = [
608
+ "exact",
609
+ "import",
610
+ "receiver-type",
611
+ "name-only",
612
+ "unresolved",
613
+ ];
614
+ if (!raw ||
615
+ raw.version !== CALL_GRAPH_CACHE_VERSION ||
616
+ !nonEmptyString(raw.builtAt))
496
617
  return false;
497
- if (!nonEmptyString(raw.reviewGraphVersion) || !nonEmptyString(raw.reviewGraphSignature))
618
+ if (!nonEmptyString(raw.reviewGraphVersion) ||
619
+ !nonEmptyString(raw.reviewGraphSignature))
498
620
  return false;
499
621
  if (raw.coverage !== undefined &&
500
- (!raw.coverage || typeof raw.coverage !== "object" || Array.isArray(raw.coverage)))
622
+ (!raw.coverage ||
623
+ typeof raw.coverage !== "object" ||
624
+ Array.isArray(raw.coverage)))
501
625
  return false;
502
- if (!Array.isArray(raw.edges) || !Array.isArray(raw.callees) || !Array.isArray(raw.callers) || !Array.isArray(raw.inDegree))
626
+ if (!Array.isArray(raw.edges) ||
627
+ !Array.isArray(raw.callees) ||
628
+ !Array.isArray(raw.callers) ||
629
+ !Array.isArray(raw.inDegree))
503
630
  return false;
504
631
  const coverageValues = [
505
632
  coverage.totalEvidence,
@@ -513,23 +640,34 @@ function validatePersistedCallGraph(raw, coverage) {
513
640
  coverage.sameFileEvidence,
514
641
  coverage.duplicateEvidence,
515
642
  ];
516
- if (typeof coverage.complete !== "boolean" || coverageValues.some((value) => !finiteCount(value)))
643
+ if (typeof coverage.complete !== "boolean" ||
644
+ coverageValues.some((value) => !finiteCount(value)))
517
645
  return false;
518
646
  if (coverage.languages !== undefined &&
519
- (!coverage.languages || typeof coverage.languages !== "object" || Array.isArray(coverage.languages) ||
520
- Object.entries(coverage.languages).some(([language, status]) => !nonEmptyString(language) || !enumValue(status, ["complete", "partial", "unavailable"]))))
647
+ (!coverage.languages ||
648
+ typeof coverage.languages !== "object" ||
649
+ Array.isArray(coverage.languages) ||
650
+ Object.entries(coverage.languages).some(([language, status]) => !nonEmptyString(language) ||
651
+ !enumValue(status, ["complete", "partial", "unavailable"]))))
521
652
  return false;
522
- if (coverage.callsEvidence + coverage.referencesEvidence !== coverage.totalEvidence)
653
+ if (coverage.callsEvidence + coverage.referencesEvidence !==
654
+ coverage.totalEvidence)
523
655
  return false;
524
656
  if (coverage.resolvedEvidence > coverage.eligibleEvidence)
525
657
  return false;
526
658
  if (coverage.eligibleEvidence !== coverage.resolvedEvidence)
527
659
  return false;
528
- if (coverage.resolvedEvidence + coverage.unresolvedEvidence + coverage.typeOnlyEvidence + coverage.unsupportedEvidence + coverage.sameFileEvidence !== coverage.totalEvidence)
660
+ if (coverage.resolvedEvidence +
661
+ coverage.unresolvedEvidence +
662
+ coverage.typeOnlyEvidence +
663
+ coverage.unsupportedEvidence +
664
+ coverage.sameFileEvidence !==
665
+ coverage.totalEvidence)
529
666
  return false;
530
667
  if (coverage.complete && coverage.unsupportedEvidence > 0)
531
668
  return false;
532
- if (coverage.complete && Object.values(coverage.languages ?? {}).some((status) => status !== "complete"))
669
+ if (coverage.complete &&
670
+ Object.values(coverage.languages ?? {}).some((status) => status !== "complete"))
533
671
  return false;
534
672
  const expectedCallees = new Map();
535
673
  const expectedCallers = new Map();
@@ -538,9 +676,17 @@ function validatePersistedCallGraph(raw, coverage) {
538
676
  let weightedEdgeEvidence = 0;
539
677
  let weightedDuplicateEvidence = 0;
540
678
  for (const edge of raw.edges) {
541
- if (!edge || typeof edge !== "object" || !nonEmptyString(edge.callerKey) || !nonEmptyString(edge.calleeKey) ||
542
- !nonEmptyString(edge.callerFile) || !nonEmptyString(edge.calleeFile) ||
543
- !nonEmptyString(edge.calleeSymbol) || typeof edge.weight !== "number" || !Number.isFinite(edge.weight) || edge.weight <= 0 || edge.weight > 1)
679
+ if (!edge ||
680
+ typeof edge !== "object" ||
681
+ !nonEmptyString(edge.callerKey) ||
682
+ !nonEmptyString(edge.calleeKey) ||
683
+ !nonEmptyString(edge.callerFile) ||
684
+ !nonEmptyString(edge.calleeFile) ||
685
+ !nonEmptyString(edge.calleeSymbol) ||
686
+ typeof edge.weight !== "number" ||
687
+ !Number.isFinite(edge.weight) ||
688
+ edge.weight <= 0 ||
689
+ edge.weight > 1)
544
690
  return false;
545
691
  if (edge.callerSymbol !== undefined && !nonEmptyString(edge.callerSymbol))
546
692
  return false;
@@ -548,19 +694,27 @@ function validatePersistedCallGraph(raw, coverage) {
548
694
  return false;
549
695
  if (edge.calleeKind !== undefined && !nonEmptyString(edge.calleeKind))
550
696
  return false;
551
- if (edge.evidenceKind !== undefined && !enumValue(edge.evidenceKind, edgeKinds))
697
+ if (edge.evidenceKind !== undefined &&
698
+ !enumValue(edge.evidenceKind, edgeKinds))
552
699
  return false;
553
- if (edge.resolution !== undefined && !enumValue(edge.resolution, resolutions))
700
+ if (edge.resolution !== undefined &&
701
+ !enumValue(edge.resolution, resolutions))
554
702
  return false;
555
- if (edge.evidenceCount !== undefined && (!finiteCount(edge.evidenceCount) || edge.evidenceCount < 1))
703
+ if (edge.evidenceCount !== undefined &&
704
+ (!finiteCount(edge.evidenceCount) || edge.evidenceCount < 1))
556
705
  return false;
557
706
  const evidenceCount = edge.evidenceCount ?? 1;
558
707
  const callerIdentity = parseCanonicalSymbolKey(edge.callerKey, edge.callerFile);
559
708
  const calleeIdentity = parseCanonicalSymbolKey(edge.calleeKey, edge.calleeFile);
560
- if (normalizeMapKey(callerIdentity.filePath) !== normalizeMapKey(edge.callerFile) ||
561
- normalizeMapKey(calleeIdentity.filePath) !== normalizeMapKey(edge.calleeFile) ||
562
- (calleeIdentity.symbolName !== undefined && calleeIdentity.symbolName !== edge.calleeSymbol) ||
563
- (callerIdentity.symbolName !== undefined && edge.callerSymbol !== undefined && callerIdentity.symbolName !== edge.callerSymbol))
709
+ if (normalizeMapKey(callerIdentity.filePath) !==
710
+ normalizeMapKey(edge.callerFile) ||
711
+ normalizeMapKey(calleeIdentity.filePath) !==
712
+ normalizeMapKey(edge.calleeFile) ||
713
+ (calleeIdentity.symbolName !== undefined &&
714
+ calleeIdentity.symbolName !== edge.calleeSymbol) ||
715
+ (callerIdentity.symbolName !== undefined &&
716
+ edge.callerSymbol !== undefined &&
717
+ callerIdentity.symbolName !== edge.callerSymbol))
564
718
  return false;
565
719
  const pair = `${edge.callerKey}\u0000${edge.calleeKey}`;
566
720
  if (pairKeys.has(pair))
@@ -583,7 +737,11 @@ function validatePersistedCallGraph(raw, coverage) {
583
737
  return false;
584
738
  if (!countsMatch(weightedDuplicateEvidence, coverage.duplicateEvidence))
585
739
  return false;
586
- if (!countsMatch(coverage.totalEvidence, weightedEdgeEvidence + coverage.unresolvedEvidence + coverage.typeOnlyEvidence + coverage.unsupportedEvidence + coverage.sameFileEvidence))
740
+ if (!countsMatch(coverage.totalEvidence, weightedEdgeEvidence +
741
+ coverage.unresolvedEvidence +
742
+ coverage.typeOnlyEvidence +
743
+ coverage.unsupportedEvidence +
744
+ coverage.sameFileEvidence))
587
745
  return false;
588
746
  if (raw.totalRefs !== undefined && !finiteCount(raw.totalRefs))
589
747
  return false;
@@ -591,14 +749,18 @@ function validatePersistedCallGraph(raw, coverage) {
591
749
  return false;
592
750
  if (raw.totalRefs !== undefined && raw.totalRefs !== coverage.totalEvidence)
593
751
  return false;
594
- if (raw.unresolvedRefs !== undefined && raw.unresolvedRefs !== coverage.unresolvedEvidence)
752
+ if (raw.unresolvedRefs !== undefined &&
753
+ raw.unresolvedRefs !== coverage.unresolvedEvidence)
595
754
  return false;
596
755
  const readAdjacency = (entries) => {
597
756
  const result = new Map();
598
757
  if (!Array.isArray(entries))
599
758
  return undefined;
600
759
  for (const entry of entries) {
601
- if (!Array.isArray(entry) || !nonEmptyString(entry[0]) || !Array.isArray(entry[1]) || entry[1].some((key) => !nonEmptyString(key)))
760
+ if (!Array.isArray(entry) ||
761
+ !nonEmptyString(entry[0]) ||
762
+ !Array.isArray(entry[1]) ||
763
+ entry[1].some((key) => !nonEmptyString(key)))
602
764
  return undefined;
603
765
  const keys = entry[1];
604
766
  if (new Set(keys).size !== keys.length || result.has(entry[0]))
@@ -609,21 +771,32 @@ function validatePersistedCallGraph(raw, coverage) {
609
771
  };
610
772
  const actualCallees = readAdjacency(raw.callees);
611
773
  const actualCallers = readAdjacency(raw.callers);
612
- if (!actualCallees || !actualCallers || actualCallees.size !== expectedCallees.size || actualCallers.size !== expectedCallers.size)
774
+ if (!actualCallees ||
775
+ !actualCallers ||
776
+ actualCallees.size !== expectedCallees.size ||
777
+ actualCallers.size !== expectedCallers.size)
613
778
  return false;
614
779
  const sameSets = (actual, expected) => {
615
780
  for (const [key, values] of expected) {
616
781
  const got = actual.get(key);
617
- if (!got || got.size !== values.size || [...values].some((value) => !got.has(value)))
782
+ if (!got ||
783
+ got.size !== values.size ||
784
+ [...values].some((value) => !got.has(value)))
618
785
  return false;
619
786
  }
620
787
  return true;
621
788
  };
622
- if (!sameSets(actualCallees, expectedCallees) || !sameSets(actualCallers, expectedCallers))
789
+ if (!sameSets(actualCallees, expectedCallees) ||
790
+ !sameSets(actualCallers, expectedCallers))
623
791
  return false;
624
792
  const actualInDegree = new Map();
625
793
  for (const entry of raw.inDegree) {
626
- if (!Array.isArray(entry) || !nonEmptyString(entry[0]) || typeof entry[1] !== "number" || !Number.isFinite(entry[1]) || entry[1] < 0 || actualInDegree.has(entry[0]))
794
+ if (!Array.isArray(entry) ||
795
+ !nonEmptyString(entry[0]) ||
796
+ typeof entry[1] !== "number" ||
797
+ !Number.isFinite(entry[1]) ||
798
+ entry[1] < 0 ||
799
+ actualInDegree.has(entry[0]))
627
800
  return false;
628
801
  actualInDegree.set(entry[0], entry[1]);
629
802
  }
@@ -645,14 +818,16 @@ export function loadCallGraph(cwd, expectedIdentity) {
645
818
  const raw = JSON.parse(fs.readFileSync(cacheFile, "utf-8"));
646
819
  if (raw.version !== CALL_GRAPH_CACHE_VERSION)
647
820
  return undefined;
648
- if (typeof raw.reviewGraphVersion !== "string" || typeof raw.reviewGraphSignature !== "string")
821
+ if (typeof raw.reviewGraphVersion !== "string" ||
822
+ typeof raw.reviewGraphSignature !== "string")
649
823
  return undefined;
650
824
  const identity = {
651
825
  reviewGraphVersion: raw.reviewGraphVersion,
652
826
  reviewGraphSignature: raw.reviewGraphSignature,
653
827
  };
654
- if (expectedIdentity && (identity.reviewGraphVersion !== expectedIdentity.reviewGraphVersion ||
655
- identity.reviewGraphSignature !== expectedIdentity.reviewGraphSignature))
828
+ if (expectedIdentity &&
829
+ (identity.reviewGraphVersion !== expectedIdentity.reviewGraphVersion ||
830
+ identity.reviewGraphSignature !== expectedIdentity.reviewGraphSignature))
656
831
  return undefined;
657
832
  const coverage = loadCoverage(raw.coverage, raw.edges);
658
833
  if (!validatePersistedCallGraph(raw, coverage))
@@ -79,8 +79,10 @@ export function buildCodebaseModel(graph, cwd, budget = DEFAULT_CODEBASE_MODEL_T
79
79
  // carries that graph's identity rather than inventing a second freshness
80
80
  // policy.
81
81
  const fileRole = detectFileRole(filePath);
82
- if (fileRole === "test" || fileRole === "generated" ||
83
- isExternalOrVendorFile(filePath, cwd) || isBuildArtifact(filePath)) {
82
+ if (fileRole === "test" ||
83
+ fileRole === "generated" ||
84
+ isExternalOrVendorFile(filePath, cwd) ||
85
+ isBuildArtifact(filePath)) {
84
86
  continue;
85
87
  }
86
88
  // Deduplicate by name when the same function appears in multiple files
@@ -138,7 +140,11 @@ export function saveCodebaseModel(cwd, model) {
138
140
  try {
139
141
  fs.mkdirSync(path.dirname(cacheFile), { recursive: true });
140
142
  writeFileAtomic(cacheFile, JSON.stringify(model));
141
- writeFileAtomic(metaFilePath(cwd), JSON.stringify({ savedAt: new Date().toISOString(), entryCount: model.entries.length, totalTokens: model.totalTokens }));
143
+ writeFileAtomic(metaFilePath(cwd), JSON.stringify({
144
+ savedAt: new Date().toISOString(),
145
+ entryCount: model.entries.length,
146
+ totalTokens: model.totalTokens,
147
+ }));
142
148
  }
143
149
  catch {
144
150
  // Non-fatal — next session rebuilds.
@@ -149,8 +155,10 @@ export function loadCodebaseModel(cwd, expectedIdentity) {
149
155
  try {
150
156
  const raw = JSON.parse(fs.readFileSync(cacheFilePath(cwd), "utf-8"));
151
157
  if (raw.version !== CODEBASE_MODEL_VERSION ||
152
- typeof raw.reviewGraphVersion !== "string" || raw.reviewGraphVersion.length === 0 ||
153
- typeof raw.reviewGraphSignature !== "string" || raw.reviewGraphSignature.length === 0 ||
158
+ typeof raw.reviewGraphVersion !== "string" ||
159
+ raw.reviewGraphVersion.length === 0 ||
160
+ typeof raw.reviewGraphSignature !== "string" ||
161
+ raw.reviewGraphSignature.length === 0 ||
154
162
  typeof raw.generatedAt !== "string" ||
155
163
  !Array.isArray(raw.entries))
156
164
  return undefined;
@@ -371,9 +371,7 @@ function countSingleUseFunctions(functions) {
371
371
  export class ComplexityClient {
372
372
  log;
373
373
  constructor(verbose = false) {
374
- this.log = verbose
375
- ? createSubsystemLogger("complexity")
376
- : () => { };
374
+ this.log = verbose ? createSubsystemLogger("complexity") : () => { };
377
375
  }
378
376
  /** True if the file's grammar has a complexity node mapping. */
379
377
  isSupportedFile(filePath) {
@@ -119,9 +119,7 @@ export class PythonDeadCodeClient {
119
119
  inFlight = new Map();
120
120
  log;
121
121
  constructor(verbose = false) {
122
- this.log = verbose
123
- ? createSubsystemLogger("dead-code:python")
124
- : () => { };
122
+ this.log = verbose ? createSubsystemLogger("dead-code:python") : () => { };
125
123
  }
126
124
  get minConfidence() {
127
125
  const raw = Number.parseInt(process.env.PI_LENS_VULTURE_MIN_CONFIDENCE ?? "60", 10);
@@ -181,7 +179,10 @@ export class PythonDeadCodeClient {
181
179
  path.join(".venv", "Scripts", "vulture.exe"),
182
180
  path.join("venv", "Scripts", "vulture.exe"),
183
181
  ]
184
- : [path.join(".venv", "bin", "vulture"), path.join("venv", "bin", "vulture")];
182
+ : [
183
+ path.join(".venv", "bin", "vulture"),
184
+ path.join("venv", "bin", "vulture"),
185
+ ];
185
186
  return relPaths
186
187
  .map((rel) => path.join(root, rel))
187
188
  .filter((full) => fs.existsSync(full))
@@ -312,9 +313,17 @@ export class PythonDeadCodeClient {
312
313
  const existing = this.inFlight.get(key);
313
314
  if (existing)
314
315
  return existing;
315
- const promise = this.runAnalyze(key).finally(() => this.inFlight.delete(key));
316
- this.inFlight.set(key, promise);
317
- return promise;
316
+ const promise = this.runAnalyze(key);
317
+ const wrapped = promise.finally(() => {
318
+ // Identity-guarded release (#1968, #1967's pattern): delete only if
319
+ // THIS build is still the registered one. A bare delete-by-key lets
320
+ // a late-settling build A evict a live build B that replaced the
321
+ // entry mid-flight, and the next caller starts a duplicate.
322
+ if (this.inFlight.get(key) === wrapped)
323
+ this.inFlight.delete(key);
324
+ });
325
+ this.inFlight.set(key, wrapped);
326
+ return wrapped;
318
327
  }
319
328
  /**
320
329
  * True when `<root>/pyproject.toml` carries a `[tool.vulture]` table.
@@ -392,7 +401,9 @@ export class PythonDeadCodeClient {
392
401
  });
393
402
  return {
394
403
  ...emptyResult(this.language),
395
- summary: stderr ? `vulture error: ${firstOutputLine(stderr)}` : reason,
404
+ summary: stderr
405
+ ? `vulture error: ${firstOutputLine(stderr)}`
406
+ : reason,
396
407
  durationMs,
397
408
  };
398
409
  }
@@ -12,8 +12,7 @@ import { createNdjsonLogger } from "./ndjson-logger.js";
12
12
  const LOG_DIR = getGlobalPiLensDir();
13
13
  const LOG_FILE = path.join(LOG_DIR, "dead-code.log");
14
14
  const LOG_BACKUP_FILE = path.join(LOG_DIR, "dead-code.log.1");
15
- const MAX_LOG_BYTES = Math.max(128 * 1024, Number.parseInt(process.env.PI_LENS_DEAD_CODE_LOG_MAX_BYTES ?? "1048576", 10) ||
16
- 1048576);
15
+ const MAX_LOG_BYTES = Math.max(128 * 1024, Number.parseInt(process.env.PI_LENS_DEAD_CODE_LOG_MAX_BYTES ?? "1048576", 10) || 1048576);
17
16
  const writer = createNdjsonLogger({
18
17
  filePath: LOG_FILE,
19
18
  maxBytes: MAX_LOG_BYTES,
@@ -29,7 +29,9 @@ export function combineAbortSignals(...signals) {
29
29
  controller.abort(s.reason);
30
30
  break;
31
31
  }
32
- s.addEventListener("abort", () => controller.abort(s.reason), { once: true });
32
+ s.addEventListener("abort", () => controller.abort(s.reason), {
33
+ once: true,
34
+ });
33
35
  }
34
36
  return controller.signal;
35
37
  }
@@ -162,6 +162,13 @@ export function writeHeapSnapshotNow(label) {
162
162
  }
163
163
  const durationMs = Date.now() - start;
164
164
  pruneOldSnapshots(dir);
165
- writer?.log({ ts, label, path: written, pid: process.pid, rssBytes, durationMs });
165
+ writer?.log({
166
+ ts,
167
+ label,
168
+ path: written,
169
+ pid: process.pid,
170
+ rssBytes,
171
+ durationMs,
172
+ });
166
173
  return { path: written, rssBytes, durationMs };
167
174
  }
@@ -2,7 +2,7 @@
2
2
  import { logExtension } from "./extension-log.js";
3
3
  import { LEDGER_FIELD_MAX, truncateForLedger } from "./ledger-bounds.js";
4
4
  import { logLatency } from "./latency-logger.js";
5
- import { getSinkWriteFailures, resetSinkWriteFailures } from "./ndjson-logger.js";
5
+ import { getSinkWriteFailures, resetSinkWriteFailures, } from "./ndjson-logger.js";
6
6
  // Re-exported so existing importers keep one name for the ledger's bound.
7
7
  export { LEDGER_FIELD_MAX, truncateForLedger };
8
8
  const ENTRIES_PER_KIND = 20;