pi-lens 4.2.0 → 4.3.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 (157) hide show
  1. package/CHANGELOG.md +543 -0
  2. package/README.md +45 -2
  3. package/dist/clients/actionable-warnings.js +44 -16
  4. package/dist/clients/advisory-provenance.js +187 -51
  5. package/dist/clients/cache-manager.js +64 -5
  6. package/dist/clients/cascade-format.js +24 -0
  7. package/dist/clients/child-unref.js +17 -8
  8. package/dist/clients/config-diagnostic-codes.js +2 -0
  9. package/dist/clients/config-locations.js +237 -9
  10. package/dist/clients/config-resolve.js +7 -1
  11. package/dist/clients/degradation-ledger.js +33 -3
  12. package/dist/clients/dependency-checker.js +87 -64
  13. package/dist/clients/diagnostic-dispositions.js +39 -3
  14. package/dist/clients/dispatch/finding-policy.js +118 -1
  15. package/dist/clients/dispatch/indent-detect.js +8 -2
  16. package/dist/clients/dispatch/inline-suppressions.js +23 -4
  17. package/dist/clients/dispatch/rule-ignores.js +14 -7
  18. package/dist/clients/dispatch/runners/actionlint.js +26 -28
  19. package/dist/clients/dispatch/runners/biome-check.js +38 -25
  20. package/dist/clients/dispatch/runners/cpp-check.js +32 -49
  21. package/dist/clients/dispatch/runners/credo.js +16 -14
  22. package/dist/clients/dispatch/runners/cue-vet.js +25 -7
  23. package/dist/clients/dispatch/runners/dart-analyze.js +28 -47
  24. package/dist/clients/dispatch/runners/detekt.js +11 -4
  25. package/dist/clients/dispatch/runners/dotnet-build.js +27 -22
  26. package/dist/clients/dispatch/runners/elixir-check.js +31 -46
  27. package/dist/clients/dispatch/runners/eslint.js +29 -46
  28. package/dist/clients/dispatch/runners/gleam-check.js +91 -11
  29. package/dist/clients/dispatch/runners/go-vet.js +16 -2
  30. package/dist/clients/dispatch/runners/golangci-lint.js +38 -23
  31. package/dist/clients/dispatch/runners/hadolint.js +27 -15
  32. package/dist/clients/dispatch/runners/htmlhint.js +17 -8
  33. package/dist/clients/dispatch/runners/javac.js +31 -21
  34. package/dist/clients/dispatch/runners/ktlint.js +34 -60
  35. package/dist/clients/dispatch/runners/lsp.js +6 -5
  36. package/dist/clients/dispatch/runners/markdownlint.js +12 -5
  37. package/dist/clients/dispatch/runners/mypy.js +2 -1
  38. package/dist/clients/dispatch/runners/oxlint.js +22 -6
  39. package/dist/clients/dispatch/runners/php-lint.js +39 -16
  40. package/dist/clients/dispatch/runners/phpstan.js +1 -1
  41. package/dist/clients/dispatch/runners/rubocop.js +27 -18
  42. package/dist/clients/dispatch/runners/ruff.js +18 -19
  43. package/dist/clients/dispatch/runners/rust-clippy.js +6 -1
  44. package/dist/clients/dispatch/runners/shellcheck.js +6 -2
  45. package/dist/clients/dispatch/runners/spellcheck.js +10 -3
  46. package/dist/clients/dispatch/runners/sqlfluff.js +11 -2
  47. package/dist/clients/dispatch/runners/stylelint.js +10 -2
  48. package/dist/clients/dispatch/runners/swiftlint.js +11 -2
  49. package/dist/clients/dispatch/runners/taplo.js +12 -6
  50. package/dist/clients/dispatch/runners/tflint.js +30 -15
  51. package/dist/clients/dispatch/runners/tree-sitter.js +23 -0
  52. package/dist/clients/dispatch/runners/trivy-config.js +8 -2
  53. package/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +11 -1
  54. package/dist/clients/dispatch/runners/vale.js +15 -3
  55. package/dist/clients/dispatch/runners/yamllint.js +12 -2
  56. package/dist/clients/dispatch/runners/zig-check.js +27 -39
  57. package/dist/clients/dispatch/suppress-writer.js +13 -3
  58. package/dist/clients/effective-config.js +3 -1
  59. package/dist/clients/extension-log.js +48 -1
  60. package/dist/clients/finding-delivery-gate.js +53 -23
  61. package/dist/clients/formatters.js +49 -11
  62. package/dist/clients/git-guard.js +247 -34
  63. package/dist/clients/gradle-ktfmt-style.js +121 -25
  64. package/dist/clients/inline-blocker-dispositions.js +186 -0
  65. package/dist/clients/install-diagnostics.js +19 -6
  66. package/dist/clients/installer/index.js +281 -32
  67. package/dist/clients/jscpd-client.js +8 -0
  68. package/dist/clients/latency-logger.js +8 -0
  69. package/dist/clients/lens-config.js +66 -8
  70. package/dist/clients/lsp/cascade-tier.js +3 -0
  71. package/dist/clients/lsp/client.js +139 -11
  72. package/dist/clients/lsp/config.js +9 -7
  73. package/dist/clients/lsp/content-limits.js +41 -0
  74. package/dist/clients/lsp/index.js +42 -8
  75. package/dist/clients/lsp/launch.js +23 -2
  76. package/dist/clients/lsp/server.js +106 -25
  77. package/dist/clients/lsp/sync-kind.js +14 -0
  78. package/dist/clients/lsp/wait-policy/strategies.js +105 -16
  79. package/dist/clients/mcp/analyze.js +9 -2
  80. package/dist/clients/mcp/ipc.js +232 -44
  81. package/dist/clients/mcp/review.js +53 -7
  82. package/dist/clients/opengrep-client.js +11 -6
  83. package/dist/clients/path-utils.js +51 -9
  84. package/dist/clients/persistent-reverify.js +271 -0
  85. package/dist/clients/pipeline.js +136 -67
  86. package/dist/clients/project-diagnostics/fresh-fetch.js +21 -3
  87. package/dist/clients/project-lens-config.js +11 -3
  88. package/dist/clients/review-graph/builder.js +34 -26
  89. package/dist/clients/review-graph/git-identity.js +16 -10
  90. package/dist/clients/ruff-client.js +31 -4
  91. package/dist/clients/runtime-coordinator.js +38 -4
  92. package/dist/clients/runtime-tool-call.js +16 -5
  93. package/dist/clients/runtime-tool-result.js +27 -12
  94. package/dist/clients/runtime-turn.js +571 -287
  95. package/dist/clients/safe-spawn.js +256 -65
  96. package/dist/clients/skills-resolver.js +38 -2
  97. package/dist/clients/spawn-output-cap.js +84 -1
  98. package/dist/clients/tree-sitter-client.js +119 -58
  99. package/dist/clients/turn-end/lane.js +51 -0
  100. package/dist/clients/turn-end/lanes/govulncheck.js +112 -0
  101. package/dist/clients/turn-end/lanes/secrets.js +204 -0
  102. package/dist/clients/warm-attach.js +59 -0
  103. package/dist/clients/widget-state.js +294 -17
  104. package/dist/clients/workspace-topology.js +57 -3
  105. package/dist/clients/zizmor-config.js +26 -13
  106. package/dist/index.js +6342 -3995
  107. package/dist/mcp/analyze-cli.js +4 -0
  108. package/dist/mcp/server.js +33 -21
  109. package/dist/scripts/lib/web-tree-sitter-dir.mjs +123 -0
  110. package/dist/tools/lens-diagnostic-mark.js +14 -2
  111. package/dist/tools/lens-diagnostics.js +127 -33
  112. package/dist/tools/lsp-diagnostics.js +150 -12
  113. package/docs/adr/0001-stale-advisory-live-arm.md +29 -0
  114. package/docs/adr/0002-workspace-hash-rendezvous.md +30 -0
  115. package/docs/adr/0003-git-guard-latch-writer.md +203 -0
  116. package/docs/adr/0004-disposition-policy-seam.md +38 -0
  117. package/docs/adr/0005-tool-availability-enforcement-seam.md +29 -0
  118. package/docs/adr/0006-derived-state-benchmark-first.md +31 -0
  119. package/docs/adr/0007-end-to-end-witness-per-seam-slice.md +38 -0
  120. package/docs/adr/0008-turn-end-lane-interface.md +165 -0
  121. package/docs/adr/0009-reported-path-attribution.md +114 -0
  122. package/docs/adr/README.md +26 -0
  123. package/docs/agent-tools.md +18 -1
  124. package/docs/ast-grep_rules_catalog.md +4 -3
  125. package/docs/configuration.md +55 -1
  126. package/docs/engineering-principles.md +202 -0
  127. package/docs/environment-variables.md +61 -4
  128. package/docs/features.md +2 -2
  129. package/docs/globalconfig.md +6 -1
  130. package/docs/language-coverage.md +17 -0
  131. package/docs/lsp-capability-matrix.md +98 -31
  132. package/docs/pi-lens-fixer.md +57 -3
  133. package/docs/pi-lens-investigator.md +9 -0
  134. package/docs/pi-lens-reviewer.md +16 -0
  135. package/docs/pi-lens-subagent.md +9 -0
  136. package/docs/public-api-stability.md +1 -0
  137. package/docs/release-qa-baseline.md +2 -0
  138. package/docs/servercapabilities.md +21 -11
  139. package/docs/settings.md +12 -3
  140. package/docs/subagent-compat.md +1 -1
  141. package/package.json +5 -3
  142. package/rules/ast-grep-rules/rule-tests/no-assert-tuple-test.yml +13 -0
  143. package/rules/ast-grep-rules/rule-tests/no-boolean-in-except-test.yml +26 -0
  144. package/rules/ast-grep-rules/rule-tests/no-http-headers-bracket-access-test.yml +10 -0
  145. package/rules/ast-grep-rules/rule-tests/unchecked-numeric-parse-python-test.yml +18 -0
  146. package/rules/ast-grep-rules/rule-tests/unchecked-throwing-call-python-test.yml +4 -3
  147. package/rules/ast-grep-rules/rules/go-no-fmt-println.yml +2 -2
  148. package/rules/ast-grep-rules/rules/no-assert-tuple.yml +23 -13
  149. package/rules/ast-grep-rules/rules/no-boolean-in-except.yml +7 -3
  150. package/rules/ast-grep-rules/rules/no-console-except-error-js.yml +2 -2
  151. package/rules/ast-grep-rules/rules/no-console-except-error.yml +2 -2
  152. package/rules/ast-grep-rules/rules/no-http-headers-bracket-access.yml +12 -7
  153. package/rules/ast-grep-rules/rules/unchecked-numeric-parse-python.yml +44 -0
  154. package/rules/ast-grep-rules/rules/unchecked-throwing-call-python.yml +5 -3
  155. package/rules/tree-sitter-queries/typescript/console-statement.yml +2 -2
  156. package/scripts/install-selftest.mjs +21 -17
  157. package/scripts/lib/web-tree-sitter-dir.mjs +123 -0
@@ -484,7 +484,7 @@ function refreshCachedExports(runtime, filePath) {
484
484
  * pipeline AND record" block could not express.
485
485
  */
486
486
  async function dispatchPipelineAnalysis(args) {
487
- const { deps, runtime, filePath, dispatchCwd, turnStateCwd, autofixMode, modifiedRanges, writeIndex, initialStateHash, readGuardCorrelationId, requestedEditIndexes, requestedEditTotal, isPartialApplyResult, toolResultStart, nativeAppliedPairs, allowReadGuardWrites, } = args;
487
+ const { deps, runtime, filePath, dispatchCwd, turnStateCwd, autofixMode, modifiedRanges, writeIndex, initialStateHash, readGuardCorrelationId, requestedEditIndexes, requestedEditTotal, isPartialApplyResult, toolResultStart, nativeAppliedPairs, allowAutonomousWriters, } = args;
488
488
  const { event, getFlag, getFlagSource, dbg, biomeClient, ruffClient, metricsClient, resetLSPService, } = deps;
489
489
  const pipelinePromise = runPipeline({
490
490
  signal: deps.signal,
@@ -493,6 +493,7 @@ async function dispatchPipelineAnalysis(args) {
493
493
  projectRoot: turnStateCwd,
494
494
  toolName: event.toolName,
495
495
  autofixMode,
496
+ allowAutonomousWriters,
496
497
  modifiedRanges,
497
498
  telemetry: {
498
499
  model: runtime.telemetryModel,
@@ -693,7 +694,7 @@ async function dispatchPipelineAnalysis(args) {
693
694
  // The model's write/edit and pi-lens' own immediate format/autofix are now
694
695
  // reflected on disk. Refresh read-guard staleness stamps so a follow-up edit
695
696
  // is judged by read-range coverage, not by our own previous write.
696
- if (!getFlag("no-read-guard") && allowReadGuardWrites) {
697
+ if (!getFlag("no-read-guard") && allowAutonomousWriters) {
697
698
  const changedForReadGuard = new Set([
698
699
  path.resolve(filePath),
699
700
  ...(result.changedFiles ?? []).map((changedFile) => path.resolve(changedFile)),
@@ -710,7 +711,9 @@ export async function handleToolResult(deps) {
710
711
  const { event, getFlag, dbg, runtime, cacheManager, agentBehaviorRecord, formatBehaviorWarnings, } = deps;
711
712
  const rawFilePath = event.input.path;
712
713
  const workspaceRoot = runtime.projectRoot || process.cwd();
713
- let bashAuthorshipConfirmed = deps._readGuardAuthorship ?? event.toolName !== "bash";
714
+ let bashAuthorshipConfirmed = deps._allowAutonomousWriters ??
715
+ deps._readGuardAuthorship ??
716
+ event.toolName !== "bash";
714
717
  // #1642: a gitignored worktree edit got re-attributed onto a
715
718
  // same-relative-path file in the parent checkout because this handler
716
719
  // used to always resolve a relative path against `workspaceRoot`
@@ -975,11 +978,9 @@ export async function handleToolResult(deps) {
975
978
  const opaqueSet = new Set(opaquePaths);
976
979
  const written = [...recognizedWritten, ...opaquePaths];
977
980
  const recognizedAuthoredSet = new Set(recognizedAuthored);
978
- bashAuthorshipConfirmed =
979
- recognizedAuthored.length > 0 || opaquePaths.length > 0;
981
+ bashAuthorshipConfirmed = recognizedAuthored.length > 0;
980
982
  for (const wp of written) {
981
- if (!getFlag("no-read-guard") &&
982
- (opaqueSet.has(wp) || recognizedAuthoredSet.has(wp)))
983
+ if (!getFlag("no-read-guard") && recognizedAuthoredSet.has(wp))
983
984
  deps.readGuard?.recordWritten(wp);
984
985
  else if (!getFlag("no-read-guard") && recognizedWritten.includes(wp))
985
986
  deps.readGuard?.recordUnchanged?.(wp);
@@ -1013,7 +1014,11 @@ export async function handleToolResult(deps) {
1013
1014
  _autofixMode: autofixMode,
1014
1015
  _attachmentBudget: syntheticAttachmentBudget,
1015
1016
  _mutationSourceOverride: isOpaque ? "opaque-script" : undefined,
1016
- _readGuardAuthorship: opaqueSet.has(wp) || recognizedAuthoredSet.has(wp),
1017
+ _readGuardAuthorship: recognizedAuthoredSet.has(wp),
1018
+ // Opaque recovery is mutation evidence only. The synthetic call still
1019
+ // records freshness and runs diagnostics, but it cannot format/autofix
1020
+ // or issue an edit-directed blocker/actionable instruction.
1021
+ _allowAutonomousWriters: recognizedAuthoredSet.has(wp),
1017
1022
  });
1018
1023
  if (syntheticResult) {
1019
1024
  // #1590: forward verbatim. The synthetic call already charged the
@@ -1476,7 +1481,7 @@ export async function handleToolResult(deps) {
1476
1481
  // bridge, so the dispatch's read-guard write refresh
1477
1482
  // carries evidence and stays enabled on every
1478
1483
  // per-path dispatch.
1479
- allowReadGuardWrites: true,
1484
+ allowAutonomousWriters: true,
1480
1485
  }), {
1481
1486
  ms: HOOK_WALL_BUDGET_MS.tool_result_edit,
1482
1487
  signal: observedDispatchSignal,
@@ -1787,7 +1792,7 @@ export async function handleToolResult(deps) {
1787
1792
  participantTotal,
1788
1793
  toolResultStart,
1789
1794
  nativeAppliedPairs,
1790
- allowReadGuardWrites: bashAuthorshipConfirmed,
1795
+ allowAutonomousWriters: bashAuthorshipConfirmed,
1791
1796
  }), {
1792
1797
  ms: HOOK_WALL_BUDGET_MS.tool_result_edit,
1793
1798
  signal: deps.signal || undefined,
@@ -1808,6 +1813,7 @@ export async function handleToolResult(deps) {
1808
1813
  const result = dispatchOutcome.result;
1809
1814
  let autofixNewlyQueued = false;
1810
1815
  if (!result.isError &&
1816
+ bashAuthorshipConfirmed &&
1811
1817
  autofixMode === "deferred" &&
1812
1818
  nodeFs.existsSync(filePath)) {
1813
1819
  autofixNewlyQueued =
@@ -1816,6 +1822,7 @@ export async function handleToolResult(deps) {
1816
1822
  }
1817
1823
  let formatQueued = false;
1818
1824
  if (!result.isError &&
1825
+ bashAuthorshipConfirmed &&
1819
1826
  !getFlag("no-autoformat", filePath) &&
1820
1827
  (autofixMode === "deferred" || !getFlag("immediate-format")) &&
1821
1828
  nodeFs.existsSync(filePath)) {
@@ -1869,7 +1876,11 @@ export async function handleToolResult(deps) {
1869
1876
  source: "autofix",
1870
1877
  dbg,
1871
1878
  });
1872
- if (resolvedChanged === path.resolve(filePath))
1879
+ // Workspace-edit paths come from fileURLToPath and are normally absolute,
1880
+ // so the turn-state cwd is inert for those values. Keep it in the resolve
1881
+ // call because the producer's contract is cwd-relative URI resolution, and
1882
+ // let pathsEqual ask the filesystem-aware path identity question (#3294).
1883
+ if (pathsEqual(path.resolve(turnStateCwd, changedFile), path.resolve(filePath)))
1873
1884
  continue;
1874
1885
  try {
1875
1886
  const content = nodeFs.readFileSync(resolvedChanged, "utf-8");
@@ -1929,7 +1940,11 @@ export async function handleToolResult(deps) {
1929
1940
  // #1561: stamp the verdict with THIS dispatch's write token — the same
1930
1941
  // counter `lsp_diagnostics`' reconciliation seam draws from — so a later
1931
1942
  // confirmed-clean result can be ordered against it instead of racing it.
1932
- runtime.recordInlineBlockers(filePath, result.inlineBlockerSummary, writeIndex, result.inlineBlockerSources, result.inlineBlockerLines, result.inlineBlockerFileContent);
1943
+ runtime.recordInlineBlockers(filePath, result.inlineBlockerSummary, writeIndex, result.inlineBlockerSources, result.inlineBlockerLines, result.inlineBlockerFileContent,
1944
+ // #3246: the structured blockers the summary was rendered from, so a
1945
+ // later `lens_diagnostic_mark` can be applied to this record at turn
1946
+ // end instead of replaying pre-mark text.
1947
+ result.inlineBlockerDiagnostics);
1933
1948
  }
1934
1949
  else {
1935
1950
  runtime.clearInlineBlockers(filePath);