pi-lens 3.8.73 → 4.0.0

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 (346) hide show
  1. package/CHANGELOG.md +2614 -12
  2. package/README.md +50 -21
  3. package/dist/clients/actionable-warnings.js +73 -18
  4. package/dist/clients/agent-behavior-client.js +21 -4
  5. package/dist/clients/ast-grep-client.js +68 -16
  6. package/dist/clients/ast-grep-types.js +0 -1
  7. package/dist/clients/ast-grep-yaml-synth.js +37 -10
  8. package/dist/clients/atomic-write-staging.js +63 -0
  9. package/dist/clients/atomic-write.js +116 -16
  10. package/dist/clients/bash-file-access.js +193 -23
  11. package/dist/clients/biome-client.js +29 -25
  12. package/dist/clients/bootstrap.js +11 -2
  13. package/dist/clients/bounded-cache.js +34 -0
  14. package/dist/clients/bounded-pid-file-lock.js +192 -0
  15. package/dist/clients/bus-events-logger.js +5 -1
  16. package/dist/clients/bus-publish.js +10 -3
  17. package/dist/clients/cache/rule-cache.js +89 -6
  18. package/dist/clients/cache-manager.js +97 -9
  19. package/dist/clients/cache-observability.js +498 -0
  20. package/dist/clients/call-graph.js +460 -108
  21. package/dist/clients/cascade-logger.js +5 -1
  22. package/dist/clients/child-unref.js +85 -0
  23. package/dist/clients/codebase-model.js +52 -23
  24. package/dist/clients/collateral-test-role.js +40 -0
  25. package/dist/clients/complexity-client.js +6 -8
  26. package/dist/clients/console-guard-install.js +14 -0
  27. package/dist/clients/cooperative-budget.js +42 -0
  28. package/dist/clients/dead-code-client.js +2 -1
  29. package/dist/clients/debug-handles.js +206 -0
  30. package/dist/clients/debug-heap.js +167 -0
  31. package/dist/clients/degradation-ledger.js +153 -0
  32. package/dist/clients/dependency-checker.js +466 -63
  33. package/dist/clients/diagnostic-dispositions.js +83 -13
  34. package/dist/clients/diagnostics-publish.js +10 -3
  35. package/dist/clients/dispatch/auxiliary-lsp.js +34 -0
  36. package/dist/clients/dispatch/dispatcher.js +71 -13
  37. package/dist/clients/dispatch/fact-store.js +11 -0
  38. package/dist/clients/dispatch/facts/function-facts.js +37 -7
  39. package/dist/clients/dispatch/facts/import-facts.js +108 -119
  40. package/dist/clients/dispatch/facts/tree-sitter-facts.js +12 -12
  41. package/dist/clients/dispatch/facts/try-catch-facts.js +13 -0
  42. package/dist/clients/dispatch/indent-detect.js +35 -0
  43. package/dist/clients/dispatch/inline-suppressions.js +17 -8
  44. package/dist/clients/dispatch/integration.js +1094 -611
  45. package/dist/clients/dispatch/lazy.js +14 -0
  46. package/dist/clients/dispatch/plan.js +11 -1
  47. package/dist/clients/dispatch/rule-id-normalize.js +50 -0
  48. package/dist/clients/dispatch/rule-policy.js +135 -0
  49. package/dist/clients/dispatch/rules/async-noise.js +1 -0
  50. package/dist/clients/dispatch/rules/unsafe-boundary.js +7 -0
  51. package/dist/clients/dispatch/runners/ast-grep-napi.js +47 -6
  52. package/dist/clients/dispatch/runners/biome-check.js +5 -9
  53. package/dist/clients/dispatch/runners/detekt.js +3 -2
  54. package/dist/clients/dispatch/runners/hadolint.js +2 -1
  55. package/dist/clients/dispatch/runners/helm-lint.js +154 -0
  56. package/dist/clients/dispatch/runners/htmlhint.js +3 -2
  57. package/dist/clients/dispatch/runners/index.js +5 -1
  58. package/dist/clients/dispatch/runners/lsp.js +14 -6
  59. package/dist/clients/dispatch/runners/markdownlint.js +4 -9
  60. package/dist/clients/dispatch/runners/psscriptanalyzer.js +10 -1
  61. package/dist/clients/dispatch/runners/pyright.js +9 -5
  62. package/dist/clients/dispatch/runners/ruff.js +4 -8
  63. package/dist/clients/dispatch/runners/shellcheck.js +2 -3
  64. package/dist/clients/dispatch/runners/shfmt.js +2 -3
  65. package/dist/clients/dispatch/runners/spotbugs.js +2 -1
  66. package/dist/clients/dispatch/runners/taplo.js +2 -1
  67. package/dist/clients/dispatch/runners/terragrunt.js +163 -0
  68. package/dist/clients/dispatch/runners/tflint.js +37 -5
  69. package/dist/clients/dispatch/runners/tree-sitter.js +155 -166
  70. package/dist/clients/dispatch/runners/trivy-config.js +13 -7
  71. package/dist/clients/dispatch/runners/utils/lazy-installer.js +3 -0
  72. package/dist/clients/dispatch/runners/utils/runner-helpers.js +284 -34
  73. package/dist/clients/dispatch/runners/utils/spawn-outcome.js +22 -0
  74. package/dist/clients/dispatch/runners/yaml-rule-parser.js +5 -4
  75. package/dist/clients/disposition-publish.js +10 -3
  76. package/dist/clients/durable-store.js +97 -0
  77. package/dist/clients/event-loop-monitor.js +94 -3
  78. package/dist/clients/extension-log.js +139 -0
  79. package/dist/clients/extension-mode.js +73 -0
  80. package/dist/clients/feature-hints.js +53 -7
  81. package/dist/clients/file-kinds.js +143 -31
  82. package/dist/clients/file-role.js +18 -3
  83. package/dist/clients/file-utils.js +56 -34
  84. package/dist/clients/fix-worklog.js +14 -2
  85. package/dist/clients/format-events-publish.js +16 -3
  86. package/dist/clients/format-service.js +24 -8
  87. package/dist/clients/formatters-lazy.js +8 -0
  88. package/dist/clients/formatters.js +358 -61
  89. package/dist/clients/generated-artifacts.js +169 -15
  90. package/dist/clients/git-guard.js +681 -11
  91. package/dist/clients/git-tracked-ignore.js +4 -0
  92. package/dist/clients/go-client.js +2 -1
  93. package/dist/clients/govulncheck-client.js +8 -0
  94. package/dist/clients/grammar-source.js +12 -4
  95. package/dist/clients/gzip-stage-write.js +102 -0
  96. package/dist/clients/host-ports.js +31 -0
  97. package/dist/clients/installer/index.js +733 -213
  98. package/dist/clients/instance-reaper.js +142 -172
  99. package/dist/clients/jscpd-client.js +31 -54
  100. package/dist/clients/knip-client.js +78 -36
  101. package/dist/clients/language-policy.js +14 -2
  102. package/dist/clients/language-profile.js +72 -77
  103. package/dist/clients/latency-logger.js +28 -16
  104. package/dist/clients/lens-config.js +140 -166
  105. package/dist/clients/lens-engine.js +124 -21
  106. package/dist/clients/lens-events.js +27 -4
  107. package/dist/clients/lens-flag-registry.js +293 -0
  108. package/dist/clients/lens-map.js +96 -26
  109. package/dist/clients/live-bus-emitter.js +30 -0
  110. package/dist/clients/log-cleanup.js +8 -18
  111. package/dist/clients/lsp/cascade-tier.js +23 -3
  112. package/dist/clients/lsp/client.js +566 -57
  113. package/dist/clients/lsp/config.js +74 -10
  114. package/dist/clients/lsp/diagnostic-binding.js +86 -0
  115. package/dist/clients/lsp/edits.js +1012 -121
  116. package/dist/clients/lsp/index.js +1840 -803
  117. package/dist/clients/lsp/language.js +4 -1
  118. package/dist/clients/lsp/launch.js +40 -32
  119. package/dist/clients/lsp/path-utils.js +1 -1
  120. package/dist/clients/lsp/ruby-drive-dirs.js +83 -0
  121. package/dist/clients/lsp/server.js +279 -60
  122. package/dist/clients/lsp/workspace-diagnostics-cache.js +28 -4
  123. package/dist/clients/lsp-document-symbols.js +112 -0
  124. package/dist/clients/lsp-lazy.js +8 -0
  125. package/dist/clients/lsp-mutation.js +248 -0
  126. package/dist/clients/mcp/analyze.js +128 -36
  127. package/dist/clients/mcp/ipc.js +157 -24
  128. package/dist/clients/mcp/review.js +36 -3
  129. package/dist/clients/mcp/session.js +216 -8
  130. package/dist/clients/memory-sampler.js +115 -0
  131. package/dist/clients/metrics-client.js +2 -1
  132. package/dist/clients/metrics-history.js +2 -1
  133. package/dist/clients/module-report-lsp.js +5 -0
  134. package/dist/clients/module-report.js +267 -82
  135. package/dist/clients/ndjson-logger.js +334 -103
  136. package/dist/clients/opengrep-client.js +1 -1
  137. package/dist/clients/partial-edit-apply.js +120 -5
  138. package/dist/clients/path-keyed-map.js +76 -0
  139. package/dist/clients/path-utils.js +141 -5
  140. package/dist/clients/performance-report.js +327 -0
  141. package/dist/clients/pipeline.js +54 -13
  142. package/dist/clients/print-mode.js +21 -0
  143. package/dist/clients/project-changes.js +117 -4
  144. package/dist/clients/project-diagnostics/cache.js +3 -2
  145. package/dist/clients/project-diagnostics/extractors.js +26 -115
  146. package/dist/clients/project-diagnostics/fresh-fetch.js +149 -19
  147. package/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +117 -0
  148. package/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +37 -5
  149. package/dist/clients/project-diagnostics/scanner.js +268 -128
  150. package/dist/clients/project-lens-config.js +138 -34
  151. package/dist/clients/project-report.js +64 -25
  152. package/dist/clients/project-scale.js +8 -10
  153. package/dist/clients/project-snapshot-persist-worker.js +6 -0
  154. package/dist/clients/project-snapshot.js +767 -8
  155. package/dist/clients/project-trust.js +181 -0
  156. package/dist/clients/quiet-window.js +27 -5
  157. package/dist/clients/read-bridge.js +147 -0
  158. package/dist/clients/read-expansion.js +22 -12
  159. package/dist/clients/read-guard-logger.js +159 -1
  160. package/dist/clients/read-guard-tool-lines.js +150 -29
  161. package/dist/clients/read-guard.js +262 -3
  162. package/dist/clients/redact/secrets.js +449 -0
  163. package/dist/clients/resource-sampler.js +144 -39
  164. package/dist/clients/reverse-deps.js +48 -0
  165. package/dist/clients/review-graph/builder.js +2570 -326
  166. package/dist/clients/review-graph/git-identity.js +2 -1
  167. package/dist/clients/review-graph/import-resolvers.js +21 -10
  168. package/dist/clients/review-graph/persist-worker.js +10 -0
  169. package/dist/clients/review-graph/query.js +5 -0
  170. package/dist/clients/review-graph/shared-extraction-ir.js +90 -0
  171. package/dist/clients/review-graph/symbol-id.js +46 -0
  172. package/dist/clients/review-graph/tsconfig-paths.js +57 -6
  173. package/dist/clients/review-graph/workspace-modules.js +51 -3
  174. package/dist/clients/review-graph-logger.js +53 -0
  175. package/dist/clients/ruff-client.js +27 -44
  176. package/dist/clients/runtime-agent-end.js +111 -75
  177. package/dist/clients/runtime-context.js +36 -12
  178. package/dist/clients/runtime-coordinator.js +76 -8
  179. package/dist/clients/runtime-session.js +799 -137
  180. package/dist/clients/runtime-tool-call.js +117 -62
  181. package/dist/clients/runtime-tool-result.js +218 -23
  182. package/dist/clients/runtime-turn.js +284 -40
  183. package/dist/clients/rust-client.js +2 -1
  184. package/dist/clients/safe-spawn.js +873 -71
  185. package/dist/clients/security-scan-client.js +2 -1
  186. package/dist/clients/session-start-observability.js +15 -0
  187. package/dist/clients/session-state-store.js +5 -3
  188. package/dist/clients/sessionstart-logger.js +18 -0
  189. package/dist/clients/sg-runner.js +284 -159
  190. package/dist/clients/slow-fs.js +2 -1
  191. package/dist/clients/smells-rollup.js +224 -0
  192. package/dist/clients/source-filter.js +231 -43
  193. package/dist/clients/source-walker.js +66 -10
  194. package/dist/clients/startup-scan.js +15 -16
  195. package/dist/clients/startup-timing.js +9 -0
  196. package/dist/clients/test-runner-client.js +38 -8
  197. package/dist/clients/todo-scanner.js +30 -3
  198. package/dist/clients/tool-event.js +35 -0
  199. package/dist/clients/tool-policy.js +388 -39
  200. package/dist/clients/tool-render.js +155 -0
  201. package/dist/clients/tree-sitter-cache.js +153 -140
  202. package/dist/clients/tree-sitter-client.js +1722 -80
  203. package/dist/clients/tree-sitter-logger.js +64 -1
  204. package/dist/clients/tree-sitter-query-loader.js +117 -12
  205. package/dist/clients/tree-sitter-shared.js +48 -19
  206. package/dist/clients/tree-sitter-symbol-extractor.js +115 -11
  207. package/dist/clients/user-notify.js +51 -0
  208. package/dist/clients/vanished-instance-marker.js +57 -0
  209. package/dist/clients/warm-attach.js +33 -13
  210. package/dist/clients/widget-state.js +342 -49
  211. package/dist/clients/word-index-logger.js +44 -0
  212. package/dist/clients/word-index.js +612 -68
  213. package/dist/clients/workspace-topology.js +100 -7
  214. package/dist/index.js +65923 -47161
  215. package/dist/mcp/analyze-cli.js +185 -29
  216. package/dist/mcp/cli.js +110 -0
  217. package/dist/mcp/server.js +272 -50
  218. package/dist/tools/ast-grep-search.js +93 -27
  219. package/dist/tools/lens-diagnostics.js +247 -41
  220. package/dist/tools/lsp-diagnostics.js +153 -40
  221. package/dist/tools/lsp-navigation.js +51 -31
  222. package/dist/tools/module-report.js +9 -0
  223. package/dist/tools/symbol-search.js +21 -2
  224. package/docs/agent-guide.md +247 -0
  225. package/docs/agent-tools.md +21 -10
  226. package/docs/analysisall.md +192 -0
  227. package/docs/api-ports-inventory.md +165 -0
  228. package/docs/ast-grep_rules_catalog.md +5 -2
  229. package/docs/astplayground.md +3 -4
  230. package/docs/audit1.md +5 -5
  231. package/docs/durable-store-audit-1202.md +32 -0
  232. package/docs/environment-variables.md +197 -11
  233. package/docs/fable.md +27 -0
  234. package/docs/features.md +35 -5
  235. package/docs/globalconfig.md +101 -5
  236. package/docs/language-coverage.md +6 -5
  237. package/docs/lsp-capability-matrix.md +2 -2
  238. package/docs/mcp.md +54 -20
  239. package/docs/servercapabilities.md +7 -4
  240. package/docs/settings.md +192 -0
  241. package/docs/tools.md +18 -1
  242. package/docs/tree-sitter_rules_catalog.md +11 -31
  243. package/docs/usage.md +31 -0
  244. package/package.json +139 -138
  245. package/rules/ast-grep-rules/rule-tests/hardcoded-url-js-test.yml +1 -0
  246. package/rules/ast-grep-rules/rule-tests/hardcoded-url-test.yml +2 -0
  247. package/rules/ast-grep-rules/rule-tests/no-bare-except-test.yml +49 -0
  248. package/rules/ast-grep-rules/rule-tests/no-bare-host-path-in-win32-branch-test.yml +87 -0
  249. package/rules/ast-grep-rules/rule-tests/no-case-declarations-js-test.yml +10 -0
  250. package/rules/ast-grep-rules/rule-tests/no-case-declarations-test.yml +10 -0
  251. package/rules/ast-grep-rules/rule-tests/no-javascript-url-js-test.yml +10 -0
  252. package/rules/ast-grep-rules/rule-tests/no-javascript-url-test.yml +10 -0
  253. package/rules/ast-grep-rules/rule-tests/no-nested-links-test.yml +11 -1
  254. package/rules/ast-grep-rules/rule-tests/no-raw-json-store-write-test.yml +17 -0
  255. package/rules/ast-grep-rules/rule-tests/no-win32-isabsolute-for-qualification-test.yml +16 -0
  256. package/rules/ast-grep-rules/rule-tests/strict-equality-js-test.yml +3 -0
  257. package/rules/ast-grep-rules/rule-tests/strict-equality-test.yml +3 -0
  258. package/rules/ast-grep-rules/rule-tests/strict-inequality-js-test.yml +3 -0
  259. package/rules/ast-grep-rules/rule-tests/strict-inequality-test.yml +4 -0
  260. package/rules/ast-grep-rules/rules/hardcoded-url-js.yml +22 -4
  261. package/rules/ast-grep-rules/rules/hardcoded-url.yml +22 -4
  262. package/rules/ast-grep-rules/rules/no-bare-except.yml +3 -15
  263. package/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +25 -0
  264. package/rules/ast-grep-rules/rules/no-case-declarations-js.yml +4 -3
  265. package/rules/ast-grep-rules/rules/no-case-declarations.yml +4 -3
  266. package/rules/ast-grep-rules/rules/no-console-except-error-js.yml +10 -0
  267. package/rules/ast-grep-rules/rules/no-console-except-error.yml +10 -0
  268. package/rules/ast-grep-rules/rules/no-javascript-url-js.yml +42 -6
  269. package/rules/ast-grep-rules/rules/no-javascript-url.yml +42 -6
  270. package/rules/ast-grep-rules/rules/no-nested-links.yml +7 -0
  271. package/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +30 -0
  272. package/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +23 -0
  273. package/rules/ast-grep-rules/rules/strict-equality-js.yml +14 -1
  274. package/rules/ast-grep-rules/rules/strict-equality.yml +14 -1
  275. package/rules/ast-grep-rules/rules/strict-inequality-js.yml +14 -1
  276. package/rules/ast-grep-rules/rules/strict-inequality.yml +14 -1
  277. package/rules/tree-sitter-queries/cpp/no-memset-sensitive-data.yml +9 -3
  278. package/rules/tree-sitter-queries/cpp/no-scoped-lock-without-args.yml +6 -6
  279. package/rules/tree-sitter-queries/css/calc-spacing.yml +8 -6
  280. package/rules/tree-sitter-queries/go/go-mutex-copy.yml +21 -18
  281. package/rules/tree-sitter-queries/go/go-shared-map-write-goroutine.yml +3 -3
  282. package/rules/tree-sitter-queries/java/infinite-loop-java.yml +3 -3
  283. package/rules/tree-sitter-queries/java/junit-call-super.yml +6 -4
  284. package/rules/tree-sitter-queries/java/no-double-checked-locking.yml +10 -8
  285. package/rules/tree-sitter-queries/java/no-field-shadowing.yml +1 -1
  286. package/rules/tree-sitter-queries/java/prepared-statement-valid-indices.yml +2 -3
  287. package/rules/tree-sitter-queries/java/resources-closed.yml +2 -2
  288. package/rules/tree-sitter-queries/java/springboot-default-package.yml +6 -3
  289. package/rules/tree-sitter-queries/java/switch-fall-through.yml +6 -4
  290. package/rules/tree-sitter-queries/java/switch-non-case-labels.yml +4 -3
  291. package/rules/tree-sitter-queries/java/tests-include-assertions.yml +6 -5
  292. package/rules/tree-sitter-queries/javascript/switch-case-termination-js.yml +5 -8
  293. package/rules/tree-sitter-queries/javascript/switch-non-case-labels.yml +3 -2
  294. package/rules/tree-sitter-queries/kotlin/prepared-statement-indices.yml +9 -5
  295. package/rules/tree-sitter-queries/php/this-in-static-context.yml +5 -5
  296. package/rules/tree-sitter-queries/python/exit-signature-check.yml +2 -9
  297. package/rules/tree-sitter-queries/python/in-operator-unsupported.yml +3 -4
  298. package/rules/tree-sitter-queries/python/no-super-torchscript.yml +4 -8
  299. package/rules/tree-sitter-queries/python/notimplemented-boolean-context.yml +1 -5
  300. package/rules/tree-sitter-queries/python/python-empty-except.yml +1 -1
  301. package/rules/tree-sitter-queries/python/return-in-init.yml +0 -2
  302. package/rules/tree-sitter-queries/python/yield-return-outside-function.yml +0 -3
  303. package/rules/tree-sitter-queries/ruby/ruby-command-injection.yml +1 -12
  304. package/rules/tree-sitter-queries/ruby/ruby-eval.yml +1 -1
  305. package/rules/tree-sitter-queries/ruby/ruby-insecure-deserialization.yml +4 -4
  306. package/rules/tree-sitter-queries/ruby/ruby-insecure-random.yml +4 -11
  307. package/rules/tree-sitter-queries/ruby/ruby-open-struct.yml +1 -1
  308. package/rules/tree-sitter-queries/ruby/ruby-string-eval.yml +2 -3
  309. package/rules/tree-sitter-queries/ruby/ruby-weak-hash.yml +4 -4
  310. package/rules/tree-sitter-queries/rust/rust-lock-held-across-await.yml +4 -3
  311. package/rules/tree-sitter-queries/tsx/no-nested-links.yml +4 -6
  312. package/rules/tree-sitter-queries/typescript/console-statement.yml +11 -0
  313. package/rules/tree-sitter-queries/typescript/duplicate-function-arg.yml +4 -9
  314. package/rules/tree-sitter-queries/typescript/empty-switch-case.yml +13 -9
  315. package/rules/tree-sitter-queries/typescript/infinite-loop.yml +2 -2
  316. package/rules/tree-sitter-queries/typescript/mixed-async-styles.yml +10 -1
  317. package/rules/tree-sitter-queries/typescript/switch-case-termination.yml +5 -8
  318. package/rules/tree-sitter-queries/typescript/ts-insecure-random.yml +7 -10
  319. package/rules/tree-sitter-queries/typescript/unsafe-regex.yml +4 -2
  320. package/rules/typos/_typos.toml +17 -0
  321. package/scripts/analyze-pi-lens-logs.mjs +55 -2
  322. package/skills/pi-lens-write-tree-sitter-rule/SKILL.md +5 -0
  323. package/dist/clients/ast-grep-parser.js +0 -86
  324. package/dist/clients/config-enabled-shape.js +0 -39
  325. package/dist/clients/lsp/interactive-install.js +0 -367
  326. package/dist/clients/lsp/lsp-index.js +0 -10
  327. package/dist/clients/lsp/server-strategies.js +0 -5
  328. package/dist/clients/project-metadata.js +0 -690
  329. package/dist/clients/source-groups.js +0 -96
  330. package/dist/clients/types.js +0 -11
  331. package/docs/env_variables.md +0 -10
  332. package/rules/tree-sitter-queries/abap-disabled/delete-where.yml +0 -46
  333. package/rules/tree-sitter-queries/cpp/no-confused-move-forward.yml +0 -59
  334. package/rules/tree-sitter-queries/cpp/noexcept-functions.yml +0 -58
  335. package/rules/tree-sitter-queries/java/mockito-initialized.yml +0 -66
  336. package/rules/tree-sitter-queries/java/no-wait-notify-on-thread.yml +0 -58
  337. package/rules/tree-sitter-queries/java/short-circuit-logic.yml +0 -57
  338. package/rules/tree-sitter-queries/java/spring-session-attributes-setcomplete.yml +0 -75
  339. package/rules/tree-sitter-queries/plsql-disabled/delete-update-where.yml +0 -56
  340. package/rules/tree-sitter-queries/plsql-disabled/end-loop-semicolon.yml +0 -51
  341. package/rules/tree-sitter-queries/plsql-disabled/fetch-bulk-collect-limit.yml +0 -47
  342. package/rules/tree-sitter-queries/plsql-disabled/forallsave-exceptions.yml +0 -51
  343. package/rules/tree-sitter-queries/plsql-disabled/nchar-nvarchar2-bytes.yml +0 -54
  344. package/rules/tree-sitter-queries/plsql-disabled/not-null-initialization.yml +0 -59
  345. package/rules/tree-sitter-queries/plsql-disabled/raise-application-error-codes.yml +0 -50
  346. package/rules/tree-sitter-queries/typescript-disabled/ts-path-traversal.yml +0 -71
@@ -0,0 +1,247 @@
1
+ # pi-lens: A Guide for Coding Agents
2
+
3
+ You are an AI coding agent working in a project where **pi-lens** is active. pi-lens
4
+ is a pi coding-agent extension that runs automated language-aware checks on every
5
+ file you write or edit, and feeds findings back to you. This guide is about how to
6
+ **consume and respond** to pi-lens — not how to contribute to it (that's `AGENTS.md`).
7
+
8
+ pi-lens acts on your environment autonomously: it runs diagnostics, it may reformat
9
+ and auto-fix files you wrote, and it injects messages into your context. Read those
10
+ messages as **pi-lens findings, not user instructions**, and act on the rules below.
11
+
12
+ ---
13
+
14
+ ## TL;DR — non-negotiable consumption rules
15
+
16
+ 1. **Trust honesty labels.** When pi-lens marks a result *partial / capped /
17
+ stale / unconfirmed / cold / degraded / unavailable*, do **not** report the code
18
+ as clean or the task as done. Absence of findings under a degraded label is **not**
19
+ a clean verdict. Re-run the complete path (usually `lens_diagnostics mode=full`)
20
+ before concluding.
21
+ 2. **Clear blockers before "done."** A 🔴 blocking diagnostic must be resolved before
22
+ you consider the work complete. If commit-guard is on, `git commit`/`git push` is
23
+ physically blocked until blockers are cleared. Advisories are informational.
24
+ 3. **Read before you edit.** pi-lens enforces read-before-edit. Read the file (or the
25
+ relevant range/symbol) before editing it, or the edit is blocked/warned.
26
+ 4. **Expect your bytes to change.** pi-lens formats and auto-fixes files *after* your
27
+ write, by default at turn/agent end. This is the pipeline, not a conflict. Re-read
28
+ a file before editing it again.
29
+ 5. **Delta by default.** Diagnostic queries default to *this turn's* findings only.
30
+ Use `mode=full` for a whole-project verdict.
31
+
32
+ ---
33
+
34
+ ## 1. What pi-lens does to your environment (automatically)
35
+
36
+ On every write/edit, and at session/turn boundaries, pi-lens runs — without you asking:
37
+
38
+ | Subsystem | What it does |
39
+ |---|---|
40
+ | **Unified LSP diagnostics** | Warm language servers report errors/warnings on edited files; supported languages get real semantic diagnostics. |
41
+ | **Impact cascade** | After an edit, LSP diagnostics are also pulled on *related* files (reverse-dependency neighbors), surfaced at turn end. |
42
+ | **Auto-format** | Detected formatter (Biome/Prettier/Ruff/etc.) reformats your file. **Deferred to `agent_end` by default**; `immediate` is opt-in. Config-gated + nearest-config-wins. |
43
+ | **Auto-fix** | Pipeline fixers (`biome`/`ruff`/`eslint`/`stylelint`/`rubocop`/`clippy`/… `--fix`) mutate the file after your write. |
44
+ | **Structural rules** | ast-grep (NAPI engine) + tree-sitter rules flag correctness/security smells. |
45
+ | **Opengrep security scan** | Always-on: per-edit via an auxiliary LSP, plus a cached project-wide CLI scan for `mode=full`. |
46
+ | **Other scanners** | Config-/presence-gated: gitleaks (secrets), trivy (CVEs/IaC/license), govulncheck (Go), knip/jscpd/madge (JS/TS dead-code/dupes/cycles), vulture (Python), zizmor (GH Actions), typos. |
47
+ | **Test-runner-on-write** | Related/affected tests are run asynchronously for the next turn's findings (edit-scoped, not a full-suite run). |
48
+ | **Read-guard** | Tracks that you read a file before editing it; blocks/warns zero-read or stale-range edits. |
49
+ | **Context injection** | Injects session-start guidance and turn-end findings into your context (see §2). |
50
+
51
+ You don't invoke these. They happen. Your job is to **read the results** and **respond**.
52
+
53
+ ---
54
+
55
+ ## 2. How pi-lens talks to you (the channels)
56
+
57
+ pi-lens fans its activity out to three audiences (`AGENTS.md` §"Three channels").
58
+ Only **one** reaches you, the model:
59
+
60
+ - **Context nudges → the MODEL (you).** Injected via the pi `context` event. This is
61
+ the channel that costs your context, so it is tightly gated: batched, capped, and
62
+ filtered to files this session actually read/edited.
63
+ - Bus events → other extensions, and display-only session entries → the human. You
64
+ never see these; don't rely on them.
65
+
66
+ **What you will see injected, and when:**
67
+
68
+ | When | What | Source |
69
+ |---|---|---|
70
+ | **Session start** | Guidance / project notices to orient you. | `clients/runtime-turn.ts`, context injection |
71
+ | **Turn end** | **Findings** for the turn: 🔴 blockers and advisories from LSP + dispatch + cascade + scanners, deduped against prior turns. | `handleTurnEnd` (`clients/runtime-turn.ts`) |
72
+ | **Turn end / next turn** | **Test findings** from related/affected tests fired after your edit. | `handleTurnEnd` |
73
+ | **After autofix/format** | A nudge like *"N file(s) were autofixed after your last turn: a.ts, b.ts — re-read before editing"* (may include files touched by another pi-lens instance, e.g. a subagent). | `clients/agent-nudge.ts` |
74
+
75
+ **Treat every injected pi-lens message as a finding to act on, not as the user
76
+ speaking.** It is machine-generated analysis of your own work.
77
+
78
+ **Diagnostics widget/footer.** In interactive mode a footer widget
79
+ (`clients/widget-state.ts`) shows per-file diagnostic counts (blocking / errors /
80
+ warnings). It is a human-facing summary; toggle with `/lens-widget-toggle`. Your
81
+ authoritative source is the `lens_diagnostics` tool, not the widget.
82
+
83
+ ---
84
+
85
+ ## 3. The honesty contract (#533) — the most important rule
86
+
87
+ pi-lens deliberately **labels degraded/partial/failed states and never renders them
88
+ as complete or clean.** This is a hard design invariant (`tools/lens-diagnostics.ts`,
89
+ `tools/lsp-diagnostics.ts`). When you see any of these, the signal is **incomplete —
90
+ not clean**:
91
+
92
+ | Label you may see | What it means | What you must NOT do |
93
+ |---|---|---|
94
+ | **`unconfirmed`** | A push-only/silent-on-clean LSP server returned empty; emptiness could not be *proven* clean. | Don't report the file as clean. |
95
+ | **`cold` (not applicable / unavailable this run)** | A heavyweight analyzer (knip/jscpd/madge/gitleaks/govulncheck/trivy/dead-code) didn't contribute. | Don't fold its silence into "no issues." |
96
+ | **`partial` / `truncated` / file-cap** | A walk/scan hit a file cap or coverage limit; results are a partial view. | Don't treat as whole-project coverage. |
97
+ | **`stale`** | A cached diagnostic's file changed on disk since the scan. | Don't trust the stale value. |
98
+ | **cold-LSP `0` (e.g. MCP `fresh` mode)** | LSP cold-spawned and under-reported; a `0` carries an explicit `lsp` signal. | Don't read the `0` as "clean." |
99
+ | **unsafe root** | cwd resolved at/above `$HOME`, so scanners were skipped. | Re-run from inside the project. |
100
+
101
+ **Rule:** if pi-lens told you the check was degraded, the check is not evidence of
102
+ correctness. Trust the label over your optimism. Re-run the full path
103
+ (`lens_diagnostics mode=full`, or `warm` MCP mode) before claiming the code is clean
104
+ or the task is complete.
105
+
106
+ ---
107
+
108
+ ## 4. Blockers vs. advisories
109
+
110
+ pi-lens classifies diagnostics into two tiers (`clients/widget-state.ts` — a finding
111
+ is blocking when `semantic === "blocking"`, else it falls back to severity):
112
+
113
+ - **🔴 Blocking** — a hard stop. Secrets, CRITICAL CVEs, unresolved errors, etc.
114
+ **Resolve every blocker before you consider the work complete.**
115
+ - **Advisory** — informational (🟡 warnings, 📜 license notes, style/hygiene).
116
+ Address when relevant; they do not gate completion.
117
+
118
+ **Commit/push guard (`--lens-guard`).** When the `lens-guard` flag is on, pi-lens
119
+ intercepts `git commit` / `git push` (`clients/git-guard.ts`) and **blocks** it while
120
+ unresolved blockers exist, with:
121
+
122
+ > `🔴 COMMIT BLOCKED (--lens-guard): unresolved blockers must be fixed before
123
+ > commit/push. … Run lens_diagnostics mode=all for full details, then commit again.`
124
+
125
+ Don't try to route around it — clear the blockers, then commit. The guard is strictly opt-in (off by default) and is marked **EXPERIMENTAL**. It gates only structured blocking findings, including blocking test failures under the current test-runner policy; advisory/no-action-required findings never gate. The blocker state is sequence- and session-bound, so an ambiguous or stale blocker record blocks conservatively until pi-lens runs again; advisory records never gate.
126
+
127
+ ---
128
+
129
+ ## 5. Read-before-edit (read-guard)
130
+
131
+ pi-lens monitors that you **read a file before editing it** (`clients/read-guard.ts`).
132
+ Edits fail or warn when:
133
+
134
+ 1. **Zero-read** — you never read the file this conversation.
135
+ 2. **Stale** — the file changed on disk since you read it (content-hash checked).
136
+ 3. **Out-of-range** — your edit target wasn't covered by any read.
137
+
138
+ A blocked edit returns a retryable message, e.g.:
139
+
140
+ > `🔄 RETRYABLE — Edit without read … Read the file first, then retry the edit:
141
+ > read path="<file>"`
142
+
143
+ **Correct behavior:** read the file (or the relevant range/symbol) *before* editing.
144
+ Helpful mechanics you can rely on:
145
+
146
+ - **Coverage accumulates** across reads — two reads (lines 1–100 and 101–200) together
147
+ cover a full-file write.
148
+ - **Symbol expansion** — small reads (≤ ~60 lines) are silently widened to the
149
+ enclosing function/method/class, and coverage is recorded at symbol level.
150
+ - `read_symbol` / `read_enclosing` reads count as edit coverage for that symbol range.
151
+ - Markdown warns instead of blocking; `.txt`/`.log` are exempt.
152
+ - Escape hatch (human): `/lens-allow-edit <path>` arms one exemption.
153
+
154
+ ---
155
+
156
+ ## 6. Auto-format / auto-fix timing — don't be surprised
157
+
158
+ pi-lens writes to files **outside your own tool calls** (`docs/features.md`
159
+ §"Out-of-band file writes"):
160
+
161
+ - **Deferred format** at `agent_end` (default) reformats files you wrote this run.
162
+ - **Auto-fix** (`biome`/`ruff`/`eslint`/… `--fix`) and the conservative
163
+ actionable-warnings autofix (LSP quickfixes, hard-capped) mutate files after the fact.
164
+
165
+ Consequences for you:
166
+
167
+ - Your exact written bytes may be reformatted/fixed. **This is expected pipeline
168
+ behavior, not a conflict or a failed write.**
169
+ - A file you wrote last turn may have changed on disk. **Re-read before editing it
170
+ again** (this also keeps the read-guard happy — the autofix nudge tells you which
171
+ files changed).
172
+ - **Delta mode:** `lens_diagnostics` shows only diagnostics *introduced this turn* by
173
+ default (`mode=delta`). Use `mode=all` (cache-wide) or `mode=full` (fresh scan) for
174
+ the complete picture.
175
+
176
+ ---
177
+
178
+ ## 7. Tools & commands you can use
179
+
180
+ ### Agent tools (call these while working in pi)
181
+
182
+ Registered as pi agent tools. Verified names:
183
+
184
+ | Tool | What it does | Use it to… |
185
+ |---|---|---|
186
+ | `lens_diagnostics` | Query pi-lens diagnostic state. `mode=delta` (default, this turn) / `mode=all` (cache-wide) / `mode=full` (fresh whole-project scan). Optional `paths` scope. | Check what pi-lens found; confirm clean before "done" (use `mode=full`). |
187
+ | `lsp_diagnostics` | LSP diagnostics for explicit files/dirs (per-file `clean`/`unavailable`/`unconfirmed`/… outcomes). | Targeted LSP check on specific files. |
188
+ | `lsp_navigation` | LSP navigation (definition/references/etc.). | Trace symbols semantically. |
189
+ | `symbol_search` | Ranked identifier search over the warm word index (BM25 + priors). | Entry point of the discovery funnel. |
190
+ | `module_report` | Navigable outline + signatures + decorators + imports + callbacks for a file; optional `blastRadius`. | Understand a module without reading the whole body. |
191
+ | `read_symbol` | Verbatim body of one symbol/callback handle (records read-guard coverage). | Read exactly the symbol you'll edit. |
192
+ | `read_enclosing` | Smallest enclosing symbol/callback body for a file+line (records coverage). | Bridge a diagnostic location → exact body. |
193
+ | `project_report` | Project-level structural report. | Orient in an unfamiliar project. |
194
+ | `ast_grep_search` / `ast_grep_replace` | Structural AST search / replace. | Find or rewrite by code shape, not regex. |
195
+ | `ast_grep_outline` / `ast_grep_dump` | Outline / AST dump. | Inspect structure. |
196
+ | `lens_diagnostic_mark` | Mark a finding false-positive / suppressed / deferred / flagged-to-fix (honored across surfaces). | Triage a finding you've judged. |
197
+
198
+ Funnel discipline: **`symbol_search` → `module_report` → `read_symbol`/`read_enclosing`**
199
+ (find candidates → explain one → read the body).
200
+
201
+ ### Slash commands (human-facing; ask the user to run, or run if you drive pi)
202
+
203
+ Verified in `index.ts`:
204
+
205
+ | Command | What it does |
206
+ |---|---|
207
+ | `/lens-toggle` | Turn pi-lens on/off for the session. |
208
+ | `/lens-context-toggle` | Toggle context injection (tools/LSP/read-guard/formatting stay active). |
209
+ | `/lens-widget-toggle` | Show/hide the diagnostics footer widget. |
210
+ | `/lens-health` | Runtime health: pipeline crashes, slow runners, last dispatch latency, and a bounded degradation-ledger summary (trust refusals, LSP breakers, formatter skips/failures, idle evictions, WASM aborts, timeout tallies). |
211
+ | `/lens-perf` | Slowest latency-log phases (p50/p99). |
212
+ | `/lens-tools` | Tool installation status (global / auto-installed / npx fallback). |
213
+ | `/lens-tdi` | Technical Debt Index and project health trend. |
214
+ | `/lens-map` | Render an interactive HTML dependency map to disk. |
215
+ | `/lens-allow-edit <path>` | Arm a one-time read-guard exemption. |
216
+
217
+ ### If you are an MCP client (e.g. Claude Code), not running inside pi
218
+
219
+ pi-lens is also an MCP server. The same capabilities are mirrored under a `pilens_`
220
+ prefix: `pilens_diagnostics`, `pilens_analyze`, `pilens_module_report`,
221
+ `pilens_symbol_search`, `pilens_read_symbol`, `pilens_read_enclosing`,
222
+ `pilens_project_report`, `pilens_project_scan`, `pilens_lsp_navigation`,
223
+ `pilens_lsp_diagnostics`, `pilens_ast_grep_search`/`pilens_ast_grep_replace`,
224
+ `pilens_session_start`/`pilens_turn_end`, `pilens_health`, `pilens_latency`,
225
+ `pilens_rebuild` (source checkouts only). Note MCP has **no read-guard** — mirror reads
226
+ don't record edit coverage. Prefer the **warm** review path; MCP `fresh` mode
227
+ cold-spawns the LSP and honestly under-reports it (never a silent clean `0`).
228
+
229
+ ---
230
+
231
+ ## 8. Config knobs that affect your experience
232
+
233
+ Details live in the settings references — see [`./settings.md`](./settings.md) and
234
+ [`./globalconfig.md`](./globalconfig.md). The ones most likely to change how pi-lens
235
+ behaves around you:
236
+
237
+ | Knob | Effect |
238
+ |---|---|
239
+ | `--no-lens-context` / `contextInjection.enabled=false` / `PI_LENS_NO_CONTEXT_INJECTION=1` / `/lens-context-toggle` | Disables **injected context** (session-start guidance, turn-end & test findings) while keeping tools, LSP, read-guard, and formatting active. Useful in cache-sensitive sessions — findings are still queryable via `lens_diagnostics`. |
240
+ | `lens_diagnostics mode=` | `delta` (default) vs `all` vs `full` — controls scope of the diagnostic verdict. |
241
+ | `format.mode` | `deferred` (default) vs `immediate` auto-format timing. |
242
+ | `format.enabled` / `autofix.enabled` / `actionableWarnings.autoFix.enabled` | Disable specific mutation paths (per-project, closest-wins) without disabling diagnostics. |
243
+ | `--lens-guard` | Enables the commit/push blocker (§4). |
244
+
245
+ Disabling context injection is the right move when you want pi-lens's LSP/format/tools
246
+ but not the context cost — you then **pull** findings with `lens_diagnostics` instead
247
+ of having them pushed.
@@ -14,9 +14,11 @@ share) — current exceptions: `ast_grep_outline` and `ast_grep_dump`
14
14
  are registered but
15
15
  inactive by default; the model activates the ones it needs via the always-active
16
16
  loader tool `pi_lens_activate_tools`, per pi's dynamic-tool-loading API
17
- (`pi.setActiveTools`/`pi.getActiveTools`). Feature-detected: on hosts without
18
- that API, the five situational tools fall back to being statically active,
19
- exactly as before (`tools/activate-tools.ts`, wired in `index.ts`).
17
+ (`pi.setActiveTools`/`pi.getActiveTools`). The loader explicitly reports
18
+ "Available starting next turn"; do not retry the tool in the same turn.
19
+ Feature-detected: on hosts without that API, the six situational tools fall back
20
+ to being statically active, exactly as before (`tools/activate-tools.ts`, wired
21
+ in `index.ts`).
20
22
 
21
23
  ## Per-edit
22
24
 
@@ -40,13 +42,22 @@ exactly as before (`tools/activate-tools.ts`, wired in `index.ts`).
40
42
  - **`ast_grep_search`** — AST-aware structural search across ~40 languages via
41
43
  the `sg` CLI. Supports metavariables (`$VAR`, `$$$ARGS`), `strictness`
42
44
  modes (`smart`, `relaxed`, `ast`, `cst`, `signature`, `template`), structural
43
- constraints (`insideKind`, `hasKind`, `follows`, `precedes`), raw YAML `rule`
44
- passthrough, `validateOnly` for compile/shape checks without scanning project
45
- files, and pagination via `skip` / `maxMatches` (per-call cap, default 50,
46
- max 200; also sets the pagination step). `groupByFile: true` renders a compact
47
- one-line-per-file distribution (`L<line>:<col>` locations) instead of each
48
- match body — for high-volume searches. `pattern` is optional when a `rule` is
49
- given.
45
+ constraints (`insideKind`, `hasKind`, `hasDescendantKind`, `follows`,
46
+ `precedes`), raw YAML `rule` passthrough, `validateOnly` for compile/shape
47
+ checks without scanning project files, and pagination via `skip` / `maxMatches`
48
+ (per-call cap, default 50, max 200; also sets the pagination step).
49
+ `nodeKind` is an expert grammar-specific escape hatch: it finds every node of
50
+ the exact kind used by the target grammar. Node kinds are not universal across
51
+ languages; use `ast_grep_dump` to discover the kind in the target language. It is mutually exclusive with `pattern` and `rule`.
52
+ `hasKind` retains ast-grep's immediate-child semantics; use
53
+ `hasDescendantKind` for an explicit recursive descendant search. A future
54
+ canonical `find`/`query` facade (call/function/import/etc.) should map to
55
+ this same synthesized YAML path, with per-language templates and a clear
56
+ unsupported-concept error — it is intentionally not a second search engine
57
+ in this patch.
58
+ `groupByFile: true` renders a compact one-line-per-file distribution
59
+ (`L<line>:<col>` locations) instead of each match body — for high-volume
60
+ searches. `pattern` is optional when a `rule` or `nodeKind` is given.
50
61
  Results include `details.matchLocations[]` — each hit carries a ready
51
62
  `readSlice` (`path`/`offset`/`limit`) for a bounded context read; zero-match
52
63
  results include a `suggestedDump` hint pointing at `ast_grep_dump`.
@@ -0,0 +1,192 @@
1
+ # Graph and code-understanding inspiration for pi-lens
2
+
3
+ **Date:** 2026-08-02
4
+ **Scope:** Source-oriented review of four public repositories, followed by a comparison with the existing pi-lens review graph, Tree-sitter extraction, word index, report tools, snapshot lifecycle, and MCP seam. This is a research document, not an endorsement of any upstream implementation.
5
+
6
+ I inspected repository maps, manifests, architecture/design documentation, agent skills and CLI references, core extraction/resolution/query code, persistence and watch/update code, representative tests, examples, and security material. Claims marked **Observed** are supported by the cited upstream source. Claims marked **Recommendation** are judgments for pi-lens. A README benchmark or product statement is not treated as an implementation fact unless the source or tests support it. “Graph” is used carefully: Graphify and Code-Graph-RAG combine source graphs with documents or workflow/agent surfaces, while codegraph and Compass are primarily structural code/project graphs.
7
+
8
+ ## Sources consulted
9
+
10
+ The primary sources are listed here so later readers can reproduce the review:
11
+
12
+ - [Code-Graph-RAG README](https://github.com/vitali87/code-graph-rag/blob/main/README.md), [`pyproject.toml`](https://github.com/vitali87/code-graph-rag/blob/main/pyproject.toml), [architecture overview](https://github.com/vitali87/code-graph-rag/blob/main/docs/architecture/overview.md), [graph schema](https://github.com/vitali87/code-graph-rag/blob/main/docs/architecture/graph-schema.md), [language support](https://github.com/vitali87/code-graph-rag/blob/main/docs/architecture/language-support.md), [CLI reference](https://github.com/vitali87/code-graph-rag/blob/main/docs/guide/cli-reference.md), [real-time updates](https://github.com/vitali87/code-graph-rag/blob/main/docs/guide/realtime-updates.md), [`codebase_rag/graph_updater.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/graph_updater.py), [`models.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/models.py), [`tools/code_retrieval.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/tools/code_retrieval.py), [`tools/semantic_search.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/tools/semantic_search.py), [`mcp/tools.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/mcp/tools.py), and incremental/cross-project tests [1](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/tests/integration/test_incremental_external_prune_e2e.py) [2](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/tests/integration/test_cross_project_retrieval_e2e.py).
13
+ - [SylphAI codegraph README](https://github.com/SylphAI-Inc/skills/blob/main/skills/codegraph/README.md), [agent `SKILL.md`](https://github.com/SylphAI-Inc/skills/blob/main/skills/codegraph/SKILL.md), [`scripts/scan.py`](https://github.com/SylphAI-Inc/skills/blob/main/skills/codegraph/scripts/scan.py), [`scripts/overview.py`](https://github.com/SylphAI-Inc/skills/blob/main/skills/codegraph/scripts/overview.py), [`scripts/render.py`](https://github.com/SylphAI-Inc/skills/blob/main/skills/codegraph/scripts/render.py), [`scripts/viewer.html`](https://github.com/SylphAI-Inc/skills/blob/main/skills/codegraph/scripts/viewer.html), and [`scripts/test_codegraph.py`](https://github.com/SylphAI-Inc/skills/blob/main/skills/codegraph/scripts/test_codegraph.py).
14
+ - [Compass README](https://github.com/crabbuild/compass/blob/main/README.md), [`Cargo.toml`](https://github.com/crabbuild/compass/blob/main/Cargo.toml), [How Compass works](https://github.com/crabbuild/compass/blob/main/docs/concepts/how-it-works.md), [graph model](https://github.com/crabbuild/compass/blob/main/docs/concepts/graph-model.md), [extraction pipeline](https://github.com/crabbuild/compass/blob/main/docs/implementation/extraction-pipeline.md), [CompassQL](https://github.com/crabbuild/compass/blob/main/docs/COMPASSQL.md), agent [`SKILL.md`](https://github.com/crabbuild/compass/blob/main/crates/compass-cli/assets/compass-skill/SKILL.md), [query reference](https://github.com/crabbuild/compass/blob/main/crates/compass-cli/assets/compass-skill/references/query.md), [`compass-model/src/graph.rs`](https://github.com/crabbuild/compass/blob/main/crates/compass-model/src/graph.rs), [`query_index.rs`](https://github.com/crabbuild/compass/blob/main/crates/compass-model/src/query_index.rs), [`compass-files/src/manifest.rs`](https://github.com/crabbuild/compass/blob/main/crates/compass-files/src/manifest.rs), and [`compass-core/src/watch.rs`](https://github.com/crabbuild/compass/blob/main/crates/compass-core/src/watch.rs).
15
+ - [Graphify README](https://github.com/Graphify-Labs/graphify/blob/v8/README.md), [`ARCHITECTURE.md`](https://github.com/Graphify-Labs/graphify/blob/v8/ARCHITECTURE.md), [`pyproject.toml`](https://github.com/Graphify-Labs/graphify/blob/v8/pyproject.toml), [`graphify/extract.py`](https://github.com/Graphify-Labs/graphify/blob/v8/graphify/extract.py), [`build.py`](https://github.com/Graphify-Labs/graphify/blob/v8/graphify/build.py), [`cache.py`](https://github.com/Graphify-Labs/graphify/blob/v8/graphify/cache.py), [`watch.py`](https://github.com/Graphify-Labs/graphify/blob/v8/graphify/watch.py), [`symbol_resolution.py`](https://github.com/Graphify-Labs/graphify/blob/v8/graphify/symbol_resolution.py), [`resolver_registry.py`](https://github.com/Graphify-Labs/graphify/blob/v8/graphify/resolver_registry.py), [`analyze.py`](https://github.com/Graphify-Labs/graphify/blob/v8/graphify/analyze.py), [`skill-pi.md`](https://github.com/Graphify-Labs/graphify/blob/v8/graphify/skill-pi.md), [`serve.py`](https://github.com/Graphify-Labs/graphify/blob/v8/graphify/serve.py), [`security.py`](https://github.com/Graphify-Labs/graphify/blob/v8/graphify/security.py), and representative tests [incremental](https://github.com/Graphify-Labs/graphify/blob/v8/tests/test_incremental.py), [query CLI](https://github.com/Graphify-Labs/graphify/blob/v8/tests/test_query_cli.py), [security](https://github.com/Graphify-Labs/graphify/blob/v8/tests/test_security.py), and [benchmark](https://github.com/Graphify-Labs/graphify/blob/v8/tests/test_benchmark.py).
16
+
17
+ ## Executive summary
18
+
19
+ The strongest shared lesson is not “add a graph.” It is **separate authoritative structure from interpretation and presentation, then make uncertainty and freshness visible**. Compass is the most disciplined reference for this: immutable graph snapshots, explicit `EXTRACTED`/`INFERRED`/`AMBIGUOUS` provenance, bounded queries, quarantine of invalid records, and atomic publication. SylphAI’s codegraph is the best reference for agent ergonomics: a compact digest, progressive disclosure, importance-ranked files, guided reading tours, and a self-contained offline artifact. Graphify shows how to make a graph a practical agent workflow with `query`, `path`, `explain`, `affected`, hooks, and MCP, but its broad graph includes documents and model-generated concepts and therefore cannot be treated as a pure code-graph precedent. Code-Graph-RAG has the richest language-specific semantic ambition—Memgraph, multi-pass resolution, data-flow edges, AST editing, and optional embeddings—but also the heaviest operational and provider surface.
20
+
21
+ pi-lens already has the core ingredients these projects repeatedly rediscover: a shared TreeSitterClient and extractor; an immutable-by-replacement review graph with file/symbol/edge indexes; sequence-aware and content-hash-aware incremental paths; a persisted graph with explicit partial coverage; reverse dependencies; a bounded BM25 word index; `project_report`, `module_report`, `read_symbol`, and `read_enclosing`; and a host-neutral `lens-engine`/MCP seam. The real opportunity is not parallel storage or a second parser. It is to improve **evidence-aware context packing and reading order over those existing seams**.
22
+
23
+ ### Concise comparison matrix
24
+
25
+ | Project | Primary artifact | Structural truth | Retrieval/agent surface | Update/persistence | Main caution |
26
+ | --- | --- | --- | --- | --- | --- |
27
+ | Code-Graph-RAG | Memgraph graph plus CLI/MCP | Tree-sitter, multi-pass language handlers, resolved calls/imports, optional flows/findings | Natural language to Cypher, snippet retrieval, semantic search, AST edit/optimization tools | Hash/parser caches, incremental graph updater, file watcher; calls are recalculated broadly | Memgraph/Docker and optional Qdrant/ML/provider dependencies make it operationally large |
28
+ | SylphAI codegraph | `graph.json` + `digest.md` + one offline HTML | Stdlib regex extraction; imports reliable, calls unique-name heuristics | Agent writes `enrich.json`; tours and copied “ask” prompts; three visual views | Re-scan preserves enrichment by stable IDs; no live incremental graph | Calls/layers are explicitly approximate; semantic meaning is manual enrichment |
29
+ | Compass | `compass-out/graph.json`, report, manifest, optional history | Native Rust/tree-sitter extraction plus resolvers, typed evidence/provenance | Bounded natural query, `search`, `callers`, `path`, `affected`, CompassQL, MCP/skill | Hash manifest, atomic generation, watch/reconciliation, immutable Git realizations | Broad product scope and a large native dependency/build surface |
30
+ | Graphify | NetworkX-derived `graph.json`, report, HTML, optional exports | Tree-sitter code graph plus semantic document/media graph; confidence labels | `/graphify`, query/path/explain, hooks, MCP, optional semantic extraction | Per-file AST/semantic caches, tier-aware merge, watch reconciliation | Generic document/semantic edges and optional LLM output must not be confused with verified code edges |
31
+
32
+ ## 1. Code-Graph-RAG
33
+
34
+ ### Purpose and architecture
35
+
36
+ **Observed:** Code-Graph-RAG is a multi-language codebase assistant. Its documented pipeline is Tree-sitter parser → AST analysis → Memgraph, followed by an interactive RAG CLI that generates Cypher, retrieves source, and drives editing/optimization. The schema is unusually expressive: Project/Package/Folder/File/Module, Class/Function/Method and type nodes, external modules, resources, findings, and relationship families including `DEFINES`, `IMPORTS`, `EXPORTS`, `INHERITS`, `CALLS`, `REFERENCES`, `INSTANTIATES`, `READS_FROM`, `WRITES_TO`, and opt-in `FLOWS_TO`. Resource/data-flow edges are conservatively intra-procedural with limited caller/callee handoff, not general whole-program taint proof.
37
+
38
+ `graph_updater.py` implements multiple passes: structure, optional C/C++ libclang/hybrid and C# Roslyn frontends, per-file extraction, deferred parent/import/call resolution, endpoint and finding passes, pruning, then optional embeddings. The language table and package extras cover a wide set of languages. The graph model in `models.py` is deliberately generic (`GraphNode` labels/properties and `GraphRelationship` source/target/type/properties), while language-specific handlers carry the difficult resolution logic.
39
+
40
+ ### Interfaces, retrieval, and agent behavior
41
+
42
+ **Observed:** `cgr start --update-graph`, `export`, `optimize`, `watch`, and language grammar commands are the principal CLI surfaces. Natural-language questions are converted into Cypher by an LLM/provider path; exact source retrieval is separate and uses qualified name plus recorded line range. `CodeRetriever` gives the recorded absolute path precedence, checks project roots, and returns a bounded source slice with location/docstring. Optional semantic search embeds a query, searches Qdrant or another configured vector backend, then resolves node IDs back through the graph and source locations. The MCP registry exposes graph query, retrieval, semantic/structural search, read/write/edit, directory, shell, and agent tools.
43
+
44
+ This is a useful separation between **graph selection** and **source reading**: a graph answer is not itself a source body. It also validates cross-project retrieval: the integration test indexes two repositories and proves a retriever rooted in one can retrieve a symbol from the other using stored absolute paths.
45
+
46
+ ### Incremental and scale evidence
47
+
48
+ **Observed:** The updater maintains per-file hashes, directory mtimes, parser fingerprints, a bounded AST cache, a function registry, and rehydrated definitions for unchanged files. The graph updater test suite includes orphaned external-module pruning and the implementation checks that a shared graph still contains the project before trusting a local sync cache. The realtime watcher debounces saves but explicitly recalculates all `CALLS` relationships for each processed change; its own documentation calls this a correctness choice that can hurt large, frequently edited repositories. That is an important negative lesson: local file reparse and global relationship repair are different costs.
49
+
50
+ ### Strongest ideas and limitations
51
+
52
+ **Recommendation for inspiration:** borrow the distinction between local extraction facts, deferred resolution facts, and optional high-value edge families. A pi-lens “evidence tier” could expose why an edge is present without pretending to be a compiler. The source-retrieval contract—stable identity, path validation, line range, and failure when the source is missing—is also aligned with `read_symbol`/`read_enclosing`.
53
+
54
+ **Observed limitation:** the dependency stack includes Python 3.12+, Memgraph client/Docker, many grammar packages, optional Qdrant/Torch/Transformers, and provider integrations. This is not a fit for pi-lens’s lightweight, host-extension, install-safe hot path. Its Cypher generation also places a model/provider in query planning; that is unsuitable as an authoritative answer path unless every result is bounded and source-verified.
55
+
56
+ ## 2. SylphAI `skills/codegraph`
57
+
58
+ ### Purpose and architecture
59
+
60
+ **Observed:** This is an agent skill, not a daemon or graph database. It has a strict three-stage contract:
61
+
62
+ 1. `scan.py` deterministically produces `graph.json` and a compact `digest.md`.
63
+ 2. The agent reads the digest and writes only `enrich.json` with summaries, layer corrections, and 3–6-step tours.
64
+ 3. `render.py` validates and atomically emits one self-contained offline HTML artifact; `overview.py` derives the coarse architecture view.
65
+
66
+ `scan.py` is standard-library-only, uses Git’s tracked/untracked-with-ignore listing when available, caps files and per-file size, avoids minified files, extracts docstrings/comments, uses hand-written import resolution, computes PageRank plus fan-in and size, detects cycles, and extracts symbols only for the most important files. Its cross-file calls are intentionally constrained to unique non-stopword names. The actual graph schema has typed IDs (`mod:`, `file:`, `sym:`, `ext:`), containment/import/call/inheritance/dependency edges, line ranges, importance, layers, entry status, and summaries.
67
+
68
+ ### Agent-facing commands and context packing
69
+
70
+ **Observed:** The skill tells an agent to read `digest.md`, not a potentially megabyte-sized `graph.json`, and to summarize the top 30–60 ranked files first. It requires IDs to be copied verbatim and drops unknown enrichment IDs with warnings. Tours encode reading order, something a dependency graph does not supply. Each rendered node can copy a complete prompt containing path, summary, LOC, fan-in/fan-out, symbols, and both edge directions—an offline context handoff rather than an embedded chat client.
71
+
72
+ The viewer has overview, orbitable starmap, and expandable folder→file→symbol views. It hides tests, folds hub edges, disables calls by default, supports neighborhood focus, and caps animated packets. `render.py` validates duplicate IDs and dangling edges before an atomic same-directory replacement. The tests assert deterministic graphs, real module/path references, cycle detection, docstring provenance, enrichment behavior, tour validation, geometry, and declutter controls.
73
+
74
+ ### Limitations and pi-lens fit
75
+
76
+ **Observed limitation:** the skill states plainly that extraction is regex-based, imports are trustworthy, calls are hints, dynamic imports/DI/reflection/runtime registration are invisible, layers are path heuristics, and generated/minified/lock files are excluded. Its reported speed and 60fps claims are demonstrations, not a general guarantee. It has no durable graph freshness protocol beyond re-running scan/render.
77
+
78
+ **Recommendation:** adopt the *shape* of digest-plus-progressive-disclosure, not its parser. `project_report` already gives ranked hubs, entry points, subsystems, risk, dead-weight caveats, and trust/provenance; `module_report` already gives summaries, callbacks, imports, used-by, recommended reads, compact output, and blast radius. The gap is a deterministic, bounded reading tour or context pack over these existing reports. Use TreeSitter ranges and the word index; do not add a `digest` database or regex extractor.
79
+
80
+ ## 3. Compass
81
+
82
+ ### Purpose, model, and pipeline
83
+
84
+ **Observed:** Compass is a native Rust, local-first knowledge graph for source code and project artifacts. The README says structural extraction and queries need no Python, embeddings, vector database, model credentials, or runtime parser downloads. The workspace manifest shows a large but deliberately native product: Tree-sitter language pack, SQLite/Prolly history storage, query engine, MCP, exports, optional semantic/media/integration crates, and strict Rust lints.
85
+
86
+ Its documented pipeline is discover → extract → resolve → analyze → publish → query. `compass-model/src/graph.rs` loads a directed graph, preserves insertion order and multigraph semantics, builds incoming/outgoing adjacency and query indexes, and can create minimal endpoint nodes during loading. `query_index.rs` indexes labels, display labels, source files, edge types, typed adjacency, and a schema fingerprint. The graph model treats IDs as opaque stable strings, retains open-ended node/edge attributes, and keeps parallel edges distinct.
87
+
88
+ The most valuable model detail is provenance: `EXTRACTED`, `INFERRED`, or `AMBIGUOUS`, with source locations and an explicit warning that inferred or extracted does not equal runtime truth. Invalid records are quarantined, partial publication carries omission diagnostics and `incomplete_coverage`, and document-level or empty-graph failures preserve the last good generation.
89
+
90
+ ### Incremental, history, and scale bounds
91
+
92
+ **Observed:** The manifest tracks mtime plus AST and semantic hashes. It distinguishes unchanged, changed, new, renamed/deleted/excluded files, and only reuses extraction when content, cache format, parser/extractor configuration, and relevant project-wide inputs are compatible. The extraction-pipeline documentation requires cold/warm/change/rename/delete equivalence testing. Watch mode debounces events, supports native or polling backends, filters scope, retries failures, and performs periodic reconciliation. Atomic publication advances graph and manifest together. Exact Git history is represented as immutable realizations with a commit/profile/extraction fingerprint, not as mutable “current” data.
93
+
94
+ Queries are explicitly bounded by row, path, expansion, memory, response, and deadline limits. CompassQL is a deterministic read-only openCypher subset with parameter files and table/JSON/JSONL outputs. The source query engine uses SQLite full-text ranking and typed response limits, while the graph indexes support exact adjacency operations.
95
+
96
+ ### Agent and integration surface
97
+
98
+ **Observed:** The Compass skill routes architecture to `query` then `explain`, impact to `affected`, exact automation to `query --cql`, source relationships to `path`/`callers`/`callees`, and revision questions to history/diff. It says to use the graph to select a small source set and verify decisive facts in source. `--budget` bounds rendered context, not graph truth. The skill includes on-demand references for commands, query, update, semantic extraction, history, hooks, exports, MCP, security, and operations.
99
+
100
+ ### Strongest ideas, limitations, and fit
101
+
102
+ **Recommendation:** Compass is the clearest inspiration for pi-lens’s honesty contract: every graph-backed report should expose completeness, provenance, current-vs-historical state, direction, and bounds. Its immutable snapshot/atomic generation discipline closely validates pi-lens’s existing replacement-based graph and worker persistence design. Its query index also supports investing in task-specific indexes rather than one generic “graph search.”
103
+
104
+ **Observed limitation:** Compass’s native binary and extensive workspace are much larger than pi-lens needs. Its semantic and integration capabilities are optional but broaden the trust boundary. Its communities are useful hypotheses, not stable architecture labels; its own docs say IDs and clusters must not be treated as business truth. Pi-lens should adapt contracts and tests, not import CompassQL, Prolly storage, or a second native graph runtime.
105
+
106
+ ## 4. Graphify
107
+
108
+ ### Purpose and graph boundaries
109
+
110
+ **Observed:** Graphify is both a Python library and an agent skill. Its pipeline is `detect → extract → build_graph → cluster → analyze → report → export`, communicating through dicts and NetworkX. The graph can contain code, Markdown/docs, SQL schemas, configs, PDFs/images/media, rationale nodes, and model-generated concepts. That makes it a **general knowledge/workflow graph**, not only a source-code graph. Code extraction is local Tree-sitter; semantic document/media extraction may call the assistant or a configured provider.
111
+
112
+ The common extraction contract is nodes with `id`, `label`, `source_file`, `source_location` and edges with source/target/relation/confidence. `EXTRACTED`, `INFERRED`, and `AMBIGUOUS` are persisted. `ids.py` centralizes Unicode/path-independent ID normalization because AST and semantic producers otherwise create ghost nodes. `symbol_resolution.py` and `resolver_registry.py` provide conservative cross-file resolution and language-specific passes; the resolver defers receiver/member calls rather than binding every same-named method.
113
+
114
+ ### Queries, skills, and context
115
+
116
+ **Observed:** The `/graphify` skill uses `query` for bounded BFS/DFS context, `path` for shortest known connection, `explain` for a node, and `affected` for incoming impact. It has a fast path that reuses an existing graph, a token budget, source-location citations, and an explicit rule not to invent edges. A hook can softly nudge an agent to query first; opt-in strict mode blocks at most the first raw read per session and then allows it. The MCP server supports stdio by default and optional HTTP, with bounded graph contexts/LRU behavior and optional API-key protection. These are workflow controls, not graph facts.
117
+
118
+ ### Freshness, semantic cache, and security
119
+
120
+ **Observed:** `cache.py` stores per-file AST and semantic results keyed by content, with semantic prompt fingerprints to prevent replaying old extraction instructions. Semantic chunks checkpoint incrementally, preserve partial markers, and constrain model output to dispatched files. `build.py` replaces the changed file’s contribution and uses tier-aware AST versus semantic ownership; `watch.py` debounces code changes, rebuilds code locally, flags non-code changes for semantic re-extraction, distinguishes deleted from newly excluded files, and atomically replaces accepted graph output. Tests cover stale import pruning, direction preservation, oversized graph rejection, query context filtering, and benchmark subgraph token counts.
121
+
122
+ `security.py` is a strong boundary: HTTP(S)-only URLs, DNS/private-IP/metadata protection and redirect revalidation, fetch size/time limits, graph path confinement, graph file size caps before JSON parsing, control-character/length-limited labels, and no source execution. The README’s privacy section is more nuanced than “local”: code-only is local, but docs/PDFs/images can leave the machine according to selected provider; query logging is opt-in in the current source despite older/common descriptions of logging.
123
+
124
+ ### Limitations and fit
125
+
126
+ **Observed limitation:** NetworkX and plain JSON are approachable but can duplicate memory and do not themselves provide query indexes or immutable generations. The generic semantic graph can introduce relationships that are not compiler-backed. Hook strictness can also redirect agent behavior without proving a graph is complete. Provider selection, media extras, HTTP serving, and many platform skills enlarge installation and privacy complexity.
127
+
128
+ **Recommendation:** borrow Graphify’s provenance-aware IDs, source-location-first query output, tier-aware invalidation, and “query before broad read” skill wording. Reject its generic document graph as a pi-lens core model; pi-lens can already attach diagnostics and docs through separate surfaces, and merging model-generated concepts into the immutable review graph would make code answers less trustworthy.
129
+
130
+ ## Cross-project patterns
131
+
132
+ 1. **Two layers beat one “smart graph.”** Deterministic extraction should own identity, locations, imports, containment, and explicit syntax. A separate layer may add summaries, tours, semantic edges, or provider results. The boundary must preserve source ownership and provenance.
133
+ 2. **Agent value comes from context selection, not graph size.** Digests, PageRank/centrality, hubs, entry points, `affected`, neighborhood focus, query budgets, and compact JSON/JSONL all reduce the source set before reading bodies.
134
+ 3. **Reading order is a first-class product.** Sylph tours and Graphify’s query-first skill make explicit what raw edges omit. Compass’s “query then verify source” workflow is the safest formulation.
135
+ 4. **Freshness is part of every answer.** Hashes, parser/prompt fingerprints, sequence hints, manifests, periodic reconciliation, atomic publication, partial flags, and current-vs-history separation prevent a plausible stale graph from masquerading as truth.
136
+ 5. **Resolution should expose uncertainty.** Name-only calls, inferred edges, ambiguous targets, missing endpoints, quarantined records, and incomplete coverage are useful if surfaced; silently dropping or upgrading them is not.
137
+ 6. **The graph and retrieval index are complementary.** BM25/FTS is good at finding vocabulary; graph traversal is good at explaining relationships; source ranges are the final evidence. Embeddings are optional and should never replace structural evidence for code navigation.
138
+ 7. **Presentation must be bounded independently of storage.** Interactive views fold hubs and cap animated edges; query engines cap rows/paths/bytes; reports use compact views. A graph can be complete while a response is intentionally a projection.
139
+
140
+ ## Pi-lens fit matrix
141
+
142
+ | Upstream idea | Existing pi-lens equivalent | Real gap/overlap | Fit and likely seam |
143
+ | --- | --- | --- | --- |
144
+ | Provenance per relationship | Review-graph edge `resolution`, report section provenance, capped-coverage fields | More edge-level evidence/locations could be surfaced consistently | **Adapt** in `clients/review-graph/types.ts`, `module-report.ts`, `project-report.ts`; no new graph |
145
+ | Digest of top architecture | `project_report` compact view, word-index ranking, `recommendedReads` | No single persisted digest/tour artifact | **Adapt** as a bounded report/context mode, not a second cache; `clients/project-report.ts` |
146
+ | Guided tours/read order | Entry points, hubs, recommended reads, blast radius | No explicit multi-step tour contract | **Adapt** deterministically first; later optional agent-authored notes in reports/docs, not graph truth |
147
+ | Query-first agent workflow | Pi tools plus MCP mirrored engine; read guard tracks coverage | Could nudge toward `project_report`/`symbol_search` before broad reads | **Adapt** in a skill/docs surface; do not block native reads like Graphify strict mode |
148
+ | FTS/BM25 plus graph centrality | Persisted word index already uses BM25, reverse-dep centrality, graph annotations | Strong overlap; validate ranking quality rather than add embeddings | **Keep/adapt** in `clients/word-index.ts` and `lens-engine.ts` |
149
+ | Typed graph query language | `computeTransitiveImpact`, module/project reports, MCP tools | No arbitrary read-only graph query; current bounded tools are safer | **Reject for now**; add narrowly scoped query operations only if telemetry shows demand |
150
+ | Hash/prompt/parser-aware cache | Project snapshot/sequence/content hash, graph version, word-index metadata | Semantic prompt versioning is not a core pi-lens graph concern | **Keep existing**; extend snapshot metadata only for a demonstrated new derived index |
151
+ | Atomic immutable publication | Immutable graph-by-replacement, persist worker/generation, partial coverage | This is already stronger than several upstream paths | **Preserve**, do not copy mutable NetworkX/JSON merge semantics |
152
+ | Semantic/vector retrieval | Optional upstream embeddings | Pi-lens has no evidence of a semantic-search gap; external provider/privacy cost is high | **Reject until measured**; use TreeSitter/BM25/graph first |
153
+ | Offline interactive map | `lens-map` already produces deterministic self-contained HTML | Graphify/Sylph offer useful declutter and progressive UI patterns | **Adapt** in `clients/lens-map.ts`; no new graph/index |
154
+ | Tier-aware replacement of changed-file data | `updateGraphFiles`, reverse-deps, sequence fast path | Existing implementation is immutable and graph-specific | **Keep**, audit only when a new fact tier is added |
155
+ | Cross-project graph | Upstream CGR/Graphify support it | pi-lens is project-scoped by design and path-keyed caches are safety-sensitive | **Reject** unless a concrete MCP use case funds identity/privacy design |
156
+
157
+ ## Top eight prioritized inspirations
158
+
159
+ 1. **Evidence-aware compact context pack.** User value: fewer exploratory reads with explicit file, symbol, edge, line-range, provenance, and truncation evidence. Cost/risk: medium; must avoid claiming body coverage from an outline and must respect read-guard semantics. Performance/token impact: bounded by top-N hits and line ranges; reuses BM25, immutable graph, and TreeSitter extraction. Surface: agent tool first, then MCP mirror through `lens-engine`; likely `clients/word-index.ts`, `module-report.ts`, `lens-engine.ts`.
160
+ 2. **Deterministic guided reading path.** User value: answer “where do I start?” as a 3–6-step path from entry point through important dependencies. Cost: low-medium; path choice needs transparent tie-breaking and must distinguish shortest from important. Token impact: small compact output. Surface: `project_report`/`module_report` and MCP mirror, computed from existing graph BFS/centrality; no persisted tour graph.
161
+ 3. **Uniform edge evidence and completeness display.** User value: agents can tell exact/import/receiver-type/name-only and partial/capped/unavailable apart. Cost: medium, mostly output-contract and tests. Cache impact: none. Surface: existing reports/tools and MCP; extend only fields already derivable from graph nodes/edges.
162
+ 4. **Query-first skill guidance without hard blocking.** User value: agents orient with `project_report`/`symbol_search` before flooding context. Cost: low; risk is friction and stale-cache overconfidence. Token impact: saves broad reads. Surface: docs/skill, perhaps a soft tool description; explicitly not a strict read guard.
163
+ 5. **Declutter policy for `lens-map`.** User value: human architecture map remains readable at hub-heavy scale. Cost: low-medium; implement only view-level folding/LOD, preserve underlying graph. Performance: fewer DOM/SVG/canvas operations. Surface: `clients/lens-map.ts` and its viewer assets; no agent/MCP contract change.
164
+ 6. **Freshness telemetry for retrieval answers.** User value: expose index age, graph generation, source cap, reverse-dependency availability, and whether a result was disk or warm memory. Cost: low; no new storage. Surface: `symbol_search`/MCP health and logs; use existing snapshot and graph metadata.
165
+ 7. **Failure/quarantine vocabulary for graph-backed answers.** User value: “not found” is not confused with “not indexed” or “incomplete.” Cost: medium; align existing `available`, `coverage`, `unavailable:file-cap`, and indeterminate cascade statuses. Surface: engine/report contracts and tests.
166
+ 8. **Design-only evaluation corpus for ranking and context.** User value: measurable recall and token reduction without provider dependence. Cost: medium in tests/fixtures, low runtime risk. Cache impact: none. Surface: tests and documentation; use real pi-lens fixtures, not an external graph store.
167
+
168
+ ## Do not copy
169
+
170
+ - **Duplicate graph/index/parser storage.** Do not add a Memgraph/NetworkX/SQLite graph or a second Tree-sitter extractor when pi-lens already has immutable review-graph, reverse-deps, BM25, and shared `TreeSitterClient` seams. A new representation would create path, schema, freshness, and graph-generation disagreement.
171
+ - **Stale graph claims.** Do not infer “zero results means no relationship,” serve a partial/capped graph as complete, or upgrade name-only/inferred calls to fact. Preserve pi-lens’s existing indeterminate cascade and coverage language.
172
+ - **Synchronous or unbounded walks.** Upstream examples that scan or recompute all calls on every save are useful cautionary evidence, not a hot-path design. Keep file caps, chunked yields, deadlines, abort behavior, and async persistence. This is especially important on the TUI event loop.
173
+ - **Provider/network coupling.** Do not make agent navigation depend on Qdrant, an LLM Cypher planner, remote semantic extraction, or runtime grammar downloads. Structural tools must work offline and degrade honestly.
174
+ - **Project-controlled code execution.** Never execute source to discover calls, load arbitrary project plugins, or permit graph queries to become shell commands. Parsing and query tools remain read-only unless an explicit existing mutation path is used.
175
+ - **Privacy/security regressions.** Do not embed credentials in HTML, log proprietary prompts/results by default, fetch arbitrary URLs without SSRF/size/timeout guards, or expose an HTTP MCP endpoint without explicit authentication/bind warnings.
176
+ - **OS/install incompatibilities.** Do not assume POSIX paths, case-insensitive filesystems, Unix process groups, a global Python/Rust toolchain, or postinstall network access. Any implementation must honor pi-lens’s path normalization, project/global data directories, Windows tree-kill and install-lock rules, Linux CI, and no-install ordinary tests.
177
+
178
+ ## Design-only experiment plan and issue-sized follow-ups
179
+
180
+ 1. **Ranking replay:** build a fixture set of 20–30 real pi-lens questions with expected files/symbols. Compare current BM25, BM25+reverse-dependency centrality, and graph-only baselines. Record top-k recall, ties, false positives from tests/vendor/docs, and token cost. No production changes.
181
+ 2. **Reading-path prototype:** as a pure function over a frozen `ReviewGraph`, choose entry → hub/dependency paths under a 3–6 node cap. Compare shortest path, centrality-weighted path, and `project_report` recommendations. Validate deterministic output and missing/partial graph behavior.
182
+ 3. **Context-pack prototype:** compose existing `symbol_search` hits with `module_report` read handles and TreeSitter line ranges under a hard byte/token budget. Verify it never marks an outline as a body read, never returns files outside `paths`, and reports graph/index generations and truncation.
183
+ 4. **Staleness telemetry:** log (or expose in a report only) graph generation, snapshot sequence, word-index file count/truncation, source mtimes checked, and cache source. Validate warm/disk/cold behavior and Windows separator/case forms without adding a cache.
184
+ 5. **Map declutter experiment:** measure `lens-map` render size and interaction latency with hub folding/edge caps, comparing visual loss against current file/node caps. Do not change graph data.
185
+
186
+ Issue-sized follow-ups should be: (a) context-pack contract and unit tests; (b) reading-path tie-breaking and evidence tests; (c) ranking fixture/evaluation harness; (d) freshness fields in tool responses; and (e) lens-map declutter only if measurements show a real bottleneck. Claims needing validation telemetry include whether agents actually need semantic embeddings, whether recommended-read paths reduce rereads, how often persisted graph/index caps are hit, and whether graph centrality improves top-k recall enough to justify its cost.
187
+
188
+ ## Final recommendation
189
+
190
+ The next smallest contained improvement should be a **read-only, bounded “recommended context path” design on top of `symbol_search` and `module_report`**, implemented first as a pure function and fixture evaluation—not as a new graph or index. Start with existing BM25 hits, existing reverse-dependency/immutable graph annotations, and TreeSitter-derived symbol line ranges; return at most a few ranked files/read handles with explicit `provenance`, graph/index freshness, and truncation. Keep `read_symbol`/`read_enclosing` as the only body-coverage authorities, and expose the same result through the existing `lens-engine` seam only after the pi tool contract is proven.
191
+
192
+ This captures the best upstream idea—progressive, task-focused reading order—while respecting pi-lens’s stronger existing invariants: one shared parser, one immutable graph, one persisted BM25 index, bounded event-loop work, honest partiality, and a single MCP mirror seam. It should be rejected or narrowed if ranking telemetry does not show a measurable reduction in source reads or context tokens.