@herbertgao/pi-extensions 2026.8.5 → 2026.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +19 -7
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +30 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +272 -22
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +74 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +94 -77
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +48 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/message-display.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +14 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +55 -17
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +41 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +75 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/types.ts +7 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +64 -1
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +16 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +30 -22
- package/node_modules/@herbertgao/pi-subagents/examples/agent-tool-description.md +5 -5
- package/node_modules/@herbertgao/pi-subagents/package.json +7 -7
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +7 -1
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +48 -19
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +22 -15
- package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +26 -2
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +219 -40
- package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +101 -3
- package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +18 -4
- package/node_modules/@herbertgao/pi-subagents/src/settings.ts +99 -0
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +22 -3
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +51 -3
- package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +20 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +34 -10
- package/node_modules/@herbertgao/pi-subagents/src/usage.ts +129 -1
- package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +29 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +3 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +46 -10
- package/node_modules/@juicesharp/rpiv-ask-user-question/config.ts +25 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/configuration.md +13 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +8 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/localization.md +3 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/en.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/zh.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +3 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +10 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +3 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +30 -7
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/state.ts +14 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/dialog-builder.ts +30 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/tab-content-strategy.ts +26 -5
- package/node_modules/@narumitw/pi-btw/README.md +119 -103
- package/node_modules/@narumitw/pi-btw/dist/index.ts +2898 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +7 -0
- package/node_modules/@narumitw/pi-btw/package.json +13 -9
- package/node_modules/@narumitw/pi-btw/src/btw.ts +40 -42
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +55 -10
- package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +390 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +78 -15
- package/node_modules/@narumitw/pi-btw/src/settings.ts +22 -2
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +136 -45
- package/node_modules/pi-lens/CHANGELOG.md +1004 -0
- package/node_modules/pi-lens/README.md +11 -3
- package/node_modules/pi-lens/config/ruff/core.toml +42 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +130 -27
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +427 -0
- package/node_modules/pi-lens/dist/clients/agent-nudge.js +79 -16
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +9 -3
- package/node_modules/pi-lens/dist/clients/atomic-write.js +9 -3
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +285 -8
- package/node_modules/pi-lens/dist/clients/biome-client.js +176 -37
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +428 -0
- package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +119 -0
- package/node_modules/pi-lens/dist/clients/bootstrap.js +12 -1
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +12 -3
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +192 -0
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +62 -6
- package/node_modules/pi-lens/dist/clients/bus-publish.js +11 -3
- package/node_modules/pi-lens/dist/clients/cascade-budget.js +196 -0
- package/node_modules/pi-lens/dist/clients/cascade-format.js +76 -2
- package/node_modules/pi-lens/dist/clients/cascade-types.js +9 -1
- package/node_modules/pi-lens/dist/clients/child-unref.js +54 -6
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +76 -24
- package/node_modules/pi-lens/dist/clients/console-guard-install.js +16 -4
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +249 -52
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +8 -1
- package/node_modules/pi-lens/dist/clients/debug-handles.js +5 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +62 -13
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +43 -9
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +153 -37
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +298 -0
- package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +165 -11
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +325 -72
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +7 -4
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +5 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +234 -18
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +187 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +6 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +11 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +398 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +11 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +12 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +18 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +895 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +4 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +16 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +81 -41
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +16 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +23 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +331 -55
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +38 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +97 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +14 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +20 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +22 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +10 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +18 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +73 -12
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +488 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +84 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +260 -27
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +943 -93
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +86 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +72 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +106 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +9 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +18 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +4 -2
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/eval-timestamp.js +17 -0
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +28 -5
- package/node_modules/pi-lens/dist/clients/extension-log.js +317 -3
- package/node_modules/pi-lens/dist/clients/file-kinds.js +8 -2
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +294 -0
- package/node_modules/pi-lens/dist/clients/finding-identity.js +88 -0
- package/node_modules/pi-lens/dist/clients/fix-worklog.js +5 -1
- package/node_modules/pi-lens/dist/clients/format-events-publish.js +39 -8
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +3 -2
- package/node_modules/pi-lens/dist/clients/formatters.js +500 -115
- package/node_modules/pi-lens/dist/clients/generation-guard.js +216 -0
- package/node_modules/pi-lens/dist/clients/git-guard.js +49 -21
- package/node_modules/pi-lens/dist/clients/gitleaks-client.js +181 -8
- package/node_modules/pi-lens/dist/clients/go-client.js +21 -39
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +219 -10
- package/node_modules/pi-lens/dist/clients/grammar-source.js +333 -10
- package/node_modules/pi-lens/dist/clients/host-ports.js +9 -1
- package/node_modules/pi-lens/dist/clients/installer/index.js +1119 -101
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +58 -0
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +715 -0
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +643 -97
- package/node_modules/pi-lens/dist/clients/instance-registry.js +87 -17
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +86 -15
- package/node_modules/pi-lens/dist/clients/knip-client.js +361 -24
- package/node_modules/pi-lens/dist/clients/language-policy.js +8 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +2 -0
- package/node_modules/pi-lens/dist/clients/latency-logger.js +487 -9
- package/node_modules/pi-lens/dist/clients/lazy-import.js +21 -0
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +21 -0
- package/node_modules/pi-lens/dist/clients/lens-events.js +56 -25
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +16 -0
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +45 -2
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +30 -4
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +160 -20
- package/node_modules/pi-lens/dist/clients/lsp/client.js +1666 -148
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +111 -0
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +389 -0
- package/node_modules/pi-lens/dist/clients/lsp/index.js +2496 -171
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +215 -0
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +146 -14
- package/node_modules/pi-lens/dist/clients/lsp/language.js +48 -4
- package/node_modules/pi-lens/dist/clients/lsp/server.js +517 -69
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +22 -0
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +43 -0
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +172 -0
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +21 -5
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +61 -3
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +422 -28
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +30 -0
- package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +175 -0
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +3 -2
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +4 -0
- package/node_modules/pi-lens/dist/clients/mcp/session.js +39 -18
- package/node_modules/pi-lens/dist/clients/model-provider.js +53 -0
- package/node_modules/pi-lens/dist/clients/module-report.js +8 -0
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +15 -1
- package/node_modules/pi-lens/dist/clients/package-manager.js +170 -14
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +27 -0
- package/node_modules/pi-lens/dist/clients/path-utils.js +160 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +178 -30
- package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +37 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +17 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +89 -22
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +85 -15
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +15 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +23 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +50 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -0
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +299 -0
- package/node_modules/pi-lens/dist/clients/quiet-window-config.js +47 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +11 -25
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +1 -1
- package/node_modules/pi-lens/dist/clients/read-guard.js +184 -10
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +49 -17
- package/node_modules/pi-lens/dist/clients/reverse-deps.js +50 -11
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +76 -4
- package/node_modules/pi-lens/dist/clients/run-duration.js +55 -0
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +248 -13
- package/node_modules/pi-lens/dist/clients/runtime-context.js +112 -12
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +472 -61
- package/node_modules/pi-lens/dist/clients/runtime-session.js +359 -13
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +217 -22
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +269 -22
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +948 -87
- package/node_modules/pi-lens/dist/clients/rust-client.js +21 -37
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +220 -7
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +161 -0
- package/node_modules/pi-lens/dist/clients/search-read-registration.js +34 -6
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +224 -8
- package/node_modules/pi-lens/dist/clients/sg-runner.js +249 -37
- package/node_modules/pi-lens/dist/clients/single-flight.js +158 -0
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +18 -11
- package/node_modules/pi-lens/dist/clients/stale-marker.js +17 -0
- package/node_modules/pi-lens/dist/clients/startup-timing.js +26 -2
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +574 -32
- package/node_modules/pi-lens/dist/clients/tool-event.js +56 -5
- package/node_modules/pi-lens/dist/clients/tool-policy.js +127 -20
- package/node_modules/pi-lens/dist/clients/tool-set-policy.js +76 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +75 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +769 -64
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +11 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +90 -0
- package/node_modules/pi-lens/dist/clients/trivy-client.js +19 -1
- package/node_modules/pi-lens/dist/clients/warm-attach.js +17 -0
- package/node_modules/pi-lens/dist/clients/widget-state.js +336 -36
- package/node_modules/pi-lens/dist/clients/word-index.js +305 -33
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +214 -14
- package/node_modules/pi-lens/dist/index.js +64677 -49484
- package/node_modules/pi-lens/dist/mcp/server.js +8 -2
- package/node_modules/pi-lens/dist/tools/activate-tools.js +17 -5
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +9 -4
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +5 -2
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +469 -56
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +190 -46
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -7
- package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -1
- package/node_modules/pi-lens/docs/agent-guide.md +44 -14
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +518 -501
- package/node_modules/pi-lens/docs/dispositions.md +21 -0
- package/node_modules/pi-lens/docs/features.md +33 -6
- package/node_modules/pi-lens/docs/globalconfig.md +14 -0
- package/node_modules/pi-lens/docs/language-coverage.md +71 -5
- package/node_modules/pi-lens/docs/mcp.md +2 -2
- package/node_modules/pi-lens/docs/servercapabilities.md +4 -1
- package/node_modules/pi-lens/docs/settings.md +25 -1
- package/node_modules/pi-lens/docs/usage.md +24 -5
- package/node_modules/pi-lens/docs/word-index.md +35 -0
- package/node_modules/pi-lens/package.json +10 -6
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-js-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/ts-void-zero-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-object-param-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +22 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-compile-call-test.yml +29 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-dupe-class-members-test.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-js-test.yml +7 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-test.yml +7 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-known-value-widening-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-non-null-assertion-test.yml +216 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-return-value-in-generator-test.yml +12 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-runtime-typeof-test.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-server-bind-wildcard-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-shape-in-symbol-names-test.yml +13 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-js-test.yml +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-test.yml +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-laundering-test.yml +11 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-parameters-test.yml +12 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-returns-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-any-test.yml +10 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-unknown-test.yml +8 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/redundant-unsafe-function-test.yml +35 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/require-safety-comment-for-as-unknown-as-test.yml +177 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/ts-void-zero-test.yml +1 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member-js.yml +13 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member.yml +13 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-object-param.yml +60 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +66 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-compile-call.yml +63 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread-js.yml +21 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread.yml +29 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-dupe-class-members.yml +52 -8
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html-js.yml +27 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html.yml +27 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-known-value-widening.yml +71 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-non-null-assertion.yml +316 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +29 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +30 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +41 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +42 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-return-value-in-generator.yml +22 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-runtime-typeof.yml +121 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-server-bind-wildcard.yml +23 -7
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-shape-in-symbol-names.yml +68 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code-js.yml +41 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code.yml +41 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +32 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-parameters.yml +67 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-returns.yml +106 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-any.yml +50 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-unknown.yml +56 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/redundant-unsafe-function.yml +32 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/require-safety-comment-for-as-unknown-as.yml +184 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/ts-void-zero.yml +5 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/self-scan-baseline.json +5 -0
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +132 -1
- package/node_modules/pi-lens/scripts/download-grammars.js +25 -0
- package/node_modules/pi-lens/scripts/grammars.lock.json +9 -0
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +12 -11
- package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +22 -22
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +87 -116
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +170 -0
- package/node_modules/pi-lens/skills/pi-lens-write-tree-sitter-rule/SKILL.md +3 -1
- package/node_modules/pi-lens/vendor/grammars/tree-sitter-cue.wasm +0 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +49 -0
- package/node_modules/pi-mcp-adapter/README.md +51 -6
- package/node_modules/pi-mcp-adapter/agent-dir.ts +12 -4
- package/node_modules/pi-mcp-adapter/cli.js +188 -5
- package/node_modules/pi-mcp-adapter/commands.ts +128 -22
- package/node_modules/pi-mcp-adapter/config.ts +28 -10
- package/node_modules/pi-mcp-adapter/direct-tools.ts +23 -19
- package/node_modules/pi-mcp-adapter/index.ts +219 -32
- package/node_modules/pi-mcp-adapter/init.ts +36 -4
- package/node_modules/pi-mcp-adapter/lifecycle.ts +315 -24
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +39 -6
- package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +387 -0
- package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +27 -3
- package/node_modules/pi-mcp-adapter/mcp-code.ts +4 -0
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +42 -13
- package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +2 -1
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +46 -25
- package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +168 -0
- package/node_modules/pi-mcp-adapter/package.json +4 -1
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +5 -4
- package/node_modules/pi-mcp-adapter/request-headers-command.ts +330 -0
- package/node_modules/pi-mcp-adapter/search-ranking.ts +92 -22
- package/node_modules/pi-mcp-adapter/server-manager.ts +145 -2
- package/node_modules/pi-mcp-adapter/session-recovery.ts +7 -0
- package/node_modules/pi-mcp-adapter/tool-approval.ts +15 -2
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +38 -18
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +44 -4
- package/node_modules/pi-mcp-adapter/types.ts +95 -10
- package/node_modules/pi-mcp-adapter/ui-server.ts +18 -16
- package/node_modules/pi-mcp-adapter/utils.ts +70 -0
- package/node_modules/pi-web-access/CHANGELOG.md +37 -0
- package/node_modules/pi-web-access/README.md +38 -14
- package/node_modules/pi-web-access/anysearch.ts +4 -2
- package/node_modules/pi-web-access/auth-fetch.ts +148 -0
- package/node_modules/pi-web-access/brave.ts +16 -4
- package/node_modules/pi-web-access/chrome-cookies.ts +110 -23
- package/node_modules/pi-web-access/curator-page.ts +8 -3
- package/node_modules/pi-web-access/curator-server.ts +5 -1
- package/node_modules/pi-web-access/exa.ts +18 -7
- package/node_modules/pi-web-access/extract.ts +134 -37
- package/node_modules/pi-web-access/fetch-params.ts +17 -3
- package/node_modules/pi-web-access/firecrawl.ts +172 -12
- package/node_modules/pi-web-access/gemini-search.ts +33 -7
- package/node_modules/pi-web-access/index.ts +160 -104
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/page-query.ts +4 -2
- package/node_modules/pi-web-access/parallel-mcp.ts +249 -0
- package/node_modules/pi-web-access/parallel.ts +2 -2
- package/node_modules/pi-web-access/query-rewrite.ts +51 -0
- package/node_modules/pi-web-access/serper.ts +211 -0
- package/node_modules/pi-web-access/summary-model-scope.ts +12 -4
- package/node_modules/pi-web-access/summary-review.ts +51 -23
- package/node_modules/pi-web-access/tavily.ts +16 -4
- package/node_modules/pi-web-access/utils.ts +87 -0
- package/node_modules/pi-web-access/valyu.ts +199 -0
- package/node_modules/pi-web-access/youtube-extract.ts +2 -2
- package/package.json +13 -13
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
import * as nodeCrypto from "node:crypto";
|
|
2
2
|
import * as nodeFs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import { noteAuthoritativeContentAttachment } from "./agent-nudge.js";
|
|
5
|
+
import { extractReadPathsFromCommand, extractDeletedPathsFromCommand, extractGrepSearchReadsFromOutput, extractWrittenPathsFromCommand, } from "./bash-file-access.js";
|
|
5
6
|
import { registerSearchReads, } from "./search-read-registration.js";
|
|
6
7
|
import { createFileTime } from "./file-time.js";
|
|
7
8
|
import { publishFormatQueued } from "./format-events-publish.js";
|
|
8
9
|
import { isPathIgnoredByProject } from "./file-utils.js";
|
|
9
10
|
import { getFormatService } from "./format-service.js";
|
|
10
|
-
import { isExternalOrVendorFile, normalizeEphemeralMapKey } from "./path-utils.js";
|
|
11
|
+
import { isExternalOrVendorFile, normalizeEphemeralMapKey, pathsEqual } from "./path-utils.js";
|
|
11
12
|
import { PathKeyedMap } from "./path-keyed-map.js";
|
|
12
13
|
import { resolveLanguageRootForFile } from "./language-profile.js";
|
|
13
14
|
import { logLatency } from "./latency-logger.js";
|
|
15
|
+
import { resolveToolCallCorrelationId } from "./tool-event.js";
|
|
14
16
|
import { boundedIndexesForCount, createReadGuardEditBatchSummary, getReadGuardCorrelationId, logReadGuardEvent, } from "./read-guard-logger.js";
|
|
17
|
+
import { notifyExternalFileChange } from "./lsp/index.js";
|
|
15
18
|
import { runPipeline } from "./pipeline.js";
|
|
19
|
+
import { renderPostAutofixNotice, } from "./post-autofix-notice.js";
|
|
16
20
|
import { appendProjectChange, } from "./project-changes.js";
|
|
17
21
|
import { syncGitGuardRecord } from "./git-guard.js";
|
|
18
22
|
import { scheduleWordIndexPersist } from "./word-index.js";
|
|
23
|
+
import { RUNTIME_CONFIG } from "./runtime-config.js";
|
|
24
|
+
const AUTHORITATIVE_CONTENT_MAX_BYTES = RUNTIME_CONFIG.pipeline.lspMaxFileBytes;
|
|
19
25
|
function parseDiffRanges(diff) {
|
|
20
26
|
const changedLines = [];
|
|
21
27
|
for (const line of diff.split("\n")) {
|
|
@@ -201,12 +207,104 @@ export async function handleToolResult(deps) {
|
|
|
201
207
|
const { event, getFlag, getFlagSource, dbg, runtime, cacheManager, biomeClient, ruffClient, metricsClient, resetLSPService, agentBehaviorRecord, formatBehaviorWarnings, } = deps;
|
|
202
208
|
const rawFilePath = event.input.path;
|
|
203
209
|
const workspaceRoot = runtime.projectRoot || process.cwd();
|
|
210
|
+
// #1642: a gitignored worktree edit got re-attributed onto a
|
|
211
|
+
// same-relative-path file in the parent checkout because this handler
|
|
212
|
+
// used to always resolve a relative path against `workspaceRoot`
|
|
213
|
+
// (`runtime.projectRoot`), with no idea the call actually ran under a
|
|
214
|
+
// different cwd/worktree.
|
|
215
|
+
//
|
|
216
|
+
// Source-level correction (pi host audit, earendil-works/pi): tool_call's
|
|
217
|
+
// own resolved path is NOT authoritative for what executed —
|
|
218
|
+
// `agent-session.ts:914-919`'s extension-handler contract lets a LATER
|
|
219
|
+
// `tool_call` handler mutate `event.input` in place with no
|
|
220
|
+
// re-validation, and edit's `prepareArguments` rewrites args before the
|
|
221
|
+
// event fires at all. `tool_result.input`, by contrast, is populated
|
|
222
|
+
// from the EXECUTED args (`agent-session.ts:502-516`) — it is the
|
|
223
|
+
// authoritative path source. So the correlation record's job is narrower
|
|
224
|
+
// than "the path": it is the RESOLUTION BASIS (the cwd/worktree the call
|
|
225
|
+
// actually ran under). Every tool_result resolves ITS OWN authoritative
|
|
226
|
+
// `rawFilePath` against that basis, rather than trusting a call-time path
|
|
227
|
+
// that a later handler may have superseded.
|
|
228
|
+
const toolCallId = resolveToolCallCorrelationId(event);
|
|
229
|
+
const attribution = toolCallId !== undefined
|
|
230
|
+
? runtime.takeToolCallAttribution(toolCallId)
|
|
231
|
+
: undefined;
|
|
232
|
+
let resolutionBasis;
|
|
233
|
+
if (attribution) {
|
|
234
|
+
resolutionBasis = attribution.originCwd;
|
|
235
|
+
}
|
|
236
|
+
else if (toolCallId !== undefined && rawFilePath && !path.isAbsolute(rawFilePath)) {
|
|
237
|
+
// A real correlation id existed (the host DOES support one) but no
|
|
238
|
+
// attribution was recorded under it — evicted, cleared because the
|
|
239
|
+
// call was blocked before it could execute, or simply never seen by
|
|
240
|
+
// `handleToolCall`. A RELATIVE path here is ambiguous: we have no
|
|
241
|
+
// idea which cwd it is relative to, and guessing `workspaceRoot` is
|
|
242
|
+
// exactly the #1642 collapse. Fail CLOSED instead of guessing — no
|
|
243
|
+
// turn state, no deferred work — and log it so a real incident is
|
|
244
|
+
// countable rather than silently mis-attributed.
|
|
245
|
+
const guessedPath = path.resolve(workspaceRoot, rawFilePath);
|
|
246
|
+
// Existence is not execution evidence: a same-named file can exist in
|
|
247
|
+
// the workspace while the tool ran in another cwd. Without the recorded
|
|
248
|
+
// call target and origin cwd there is no comparison to make, so retain the
|
|
249
|
+
// full record and fail closed.
|
|
250
|
+
dbg(`path_attribution_missing: no recorded resolution basis for toolCallId=${toolCallId}, refusing relative path ${rawFilePath} (would have guessed ${guessedPath})`);
|
|
251
|
+
logLatency({
|
|
252
|
+
type: "phase",
|
|
253
|
+
toolName: event.toolName,
|
|
254
|
+
filePath: guessedPath,
|
|
255
|
+
phase: "path_attribution_missing",
|
|
256
|
+
durationMs: 0,
|
|
257
|
+
metadata: { toolCallId, rawFilePath, guessedPath },
|
|
258
|
+
});
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
// Either an ABSOLUTE path (bash-synthetic writes always pass one —
|
|
263
|
+
// unambiguous regardless of any basis, see the bash-write dispatch
|
|
264
|
+
// below) or a host that supplies NO correlation id at all under any
|
|
265
|
+
// known field name. The latter cannot be correlated by identity full
|
|
266
|
+
// stop; this is the SAME exposure every host had before this fix,
|
|
267
|
+
// not a regression introduced by it.
|
|
268
|
+
resolutionBasis = workspaceRoot;
|
|
269
|
+
}
|
|
204
270
|
const filePath = rawFilePath
|
|
205
271
|
? path.isAbsolute(rawFilePath)
|
|
206
272
|
? rawFilePath
|
|
207
|
-
: path.resolve(
|
|
273
|
+
: path.resolve(resolutionBasis, rawFilePath)
|
|
208
274
|
: rawFilePath;
|
|
275
|
+
// Purely diagnostic: tool_call's call-time verdict (computed on ITS OWN
|
|
276
|
+
// resolved path, which may since have been superseded) disagreed with
|
|
277
|
+
// what actually executed. This does NOT gate anything by itself — the
|
|
278
|
+
// ignore re-check below, running on the freshly & correctly resolved
|
|
279
|
+
// `filePath`, is the real decision — but a divergence is exactly the
|
|
280
|
+
// shape of the reported incident, so it is named legibly.
|
|
281
|
+
if (attribution?.skipped &&
|
|
282
|
+
filePath &&
|
|
283
|
+
attribution.resolvedPath &&
|
|
284
|
+
!pathsEqual(filePath, attribution.resolvedPath)) {
|
|
285
|
+
const message = `path_attribution_refused: call target ${attribution.resolvedPath} (originCwd=${attribution.originCwd}) vs tool_result resolved ${filePath}`;
|
|
286
|
+
dbg(message);
|
|
287
|
+
logLatency({
|
|
288
|
+
type: "phase",
|
|
289
|
+
toolName: event.toolName,
|
|
290
|
+
filePath,
|
|
291
|
+
phase: "path_attribution_refused",
|
|
292
|
+
durationMs: 0,
|
|
293
|
+
metadata: {
|
|
294
|
+
callTarget: attribution.resolvedPath,
|
|
295
|
+
resolvedPath: filePath,
|
|
296
|
+
originCwd: attribution.originCwd,
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
}
|
|
209
300
|
const behaviorWarnings = agentBehaviorRecord(event.toolName, filePath);
|
|
301
|
+
const syntheticWriteContent = [];
|
|
302
|
+
// #1590: one shared authoritative-content budget for every path this bash
|
|
303
|
+
// command wrote. It is handed DOWN to each synthetic call so the single
|
|
304
|
+
// attachment decision there sees both limits; nothing re-decides out here.
|
|
305
|
+
const syntheticAttachmentBudget = {
|
|
306
|
+
remaining: AUTHORITATIVE_CONTENT_MAX_BYTES,
|
|
307
|
+
};
|
|
210
308
|
// Bash writes (redirects, tee, sed -i, cp/mv, touch, git checkout/restore) —
|
|
211
309
|
// these change file content but never go through the edit tool, so bash
|
|
212
310
|
// early-returns before the dispatch pipeline below. For each in-project file
|
|
@@ -224,11 +322,24 @@ export async function handleToolResult(deps) {
|
|
|
224
322
|
for (const wp of written) {
|
|
225
323
|
if (!getFlag("no-read-guard"))
|
|
226
324
|
deps.readGuard?.recordWritten(wp);
|
|
227
|
-
|
|
325
|
+
const receipt = runtime.recordMutationToolReceipt;
|
|
326
|
+
const autofixMode = receipt
|
|
327
|
+
? receipt.call(runtime, wp, "write").autofixMode
|
|
328
|
+
: "immediate";
|
|
329
|
+
const syntheticResult = await handleToolResult({
|
|
228
330
|
...deps,
|
|
229
331
|
event: { ...event, toolName: "write", input: { path: wp } },
|
|
230
332
|
_bypassDebounce: true,
|
|
333
|
+
_autofixMode: autofixMode,
|
|
334
|
+
_attachmentBudget: syntheticAttachmentBudget,
|
|
231
335
|
});
|
|
336
|
+
if (syntheticResult) {
|
|
337
|
+
// #1590: forward verbatim. The synthetic call already charged the
|
|
338
|
+
// shared budget above and phrased its own notice from the decision
|
|
339
|
+
// it made, so a second verdict out here could only contradict it —
|
|
340
|
+
// which is exactly the defect this shape produced before.
|
|
341
|
+
syntheticWriteContent.push(...syntheticResult.content.slice(event.content.length));
|
|
342
|
+
}
|
|
232
343
|
}
|
|
233
344
|
if (event.isError !== true && !getFlag("no-read-guard")) {
|
|
234
345
|
for (const span of extractReadPathsFromCommand(command, workspaceRoot)) {
|
|
@@ -249,6 +360,42 @@ export async function handleToolResult(deps) {
|
|
|
249
360
|
});
|
|
250
361
|
}
|
|
251
362
|
}
|
|
363
|
+
// #1668: bash-deleted files never go through the edit tool, so nothing
|
|
364
|
+
// else tells an LSP server one of its watched files is gone — the ONLY
|
|
365
|
+
// existing enqueue site fires on first open and can only emit type 1/2.
|
|
366
|
+
// Extract the command's likely delete targets, confirm each by existence
|
|
367
|
+
// (never scan the workspace — only the paths the command named), and only
|
|
368
|
+
// act on paths pi-lens already knows about (a read or a write this
|
|
369
|
+
// session) so an `rm` on something pi-lens never touched is not treated
|
|
370
|
+
// as a signal. Each match is routed to already-active LSP clients as a
|
|
371
|
+
// type-3 watched-files event through the same #271 coalescing queue a
|
|
372
|
+
// burst of deletes still flushes as one notification per server.
|
|
373
|
+
if (event.isError !== true &&
|
|
374
|
+
!getFlag("no-lsp") &&
|
|
375
|
+
!getFlag("no-read-guard")) {
|
|
376
|
+
for (const dp of extractDeletedPathsFromCommand(command, workspaceRoot)) {
|
|
377
|
+
if (isExternalOrVendorFile(dp, workspaceRoot))
|
|
378
|
+
continue;
|
|
379
|
+
if (isPathIgnoredByProject(dp, workspaceRoot, false))
|
|
380
|
+
continue;
|
|
381
|
+
if (!deps.readGuard || !deps.readGuard.hasKnownPath(dp))
|
|
382
|
+
continue;
|
|
383
|
+
// #1668 review F4: this is the ONLY gate standing between a merely
|
|
384
|
+
// NAMED path and an actual confirmed delete — extractDeletedPathsFromCommand
|
|
385
|
+
// only proposes candidates from parsing the command text, so it can't
|
|
386
|
+
// tell `git rm --cached f` (index-only, file still on disk) from a
|
|
387
|
+
// real delete, can't see a short-circuited `rm f && false` that never
|
|
388
|
+
// ran, and can't resolve a relative path run from a `cd`-ed subdirectory
|
|
389
|
+
// against the wrong cwd. Every one of those is caught here, and only
|
|
390
|
+
// here — do not remove or reorder this check relative to the loop body.
|
|
391
|
+
if (nodeFs.existsSync(dp))
|
|
392
|
+
continue; // still there — not a real delete
|
|
393
|
+
deps.readGuard.forgetPath(dp);
|
|
394
|
+
void notifyExternalFileChange(dp, 3).catch((err) => {
|
|
395
|
+
dbg(`tool_result: external-delete notify failed for ${dp}: ${err}`);
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
}
|
|
252
399
|
}
|
|
253
400
|
// Search tools reveal specific lines (file:line) the agent then edits — register
|
|
254
401
|
// those shown lines (± context) as reads so the follow-up edit isn't blocked (#169).
|
|
@@ -277,7 +424,9 @@ export async function handleToolResult(deps) {
|
|
|
277
424
|
}
|
|
278
425
|
if (event.toolName !== "write" && event.toolName !== "edit") {
|
|
279
426
|
dbg(`tool_result: skipped turn tracking - toolName="${event.toolName}" (not write/edit)`);
|
|
280
|
-
return
|
|
427
|
+
return syntheticWriteContent.length > 0
|
|
428
|
+
? { content: [...event.content, ...syntheticWriteContent] }
|
|
429
|
+
: undefined;
|
|
281
430
|
}
|
|
282
431
|
if (!filePath) {
|
|
283
432
|
dbg(`tool_result: skipped turn tracking - no filePath for toolName="${event.toolName}"`);
|
|
@@ -324,6 +473,16 @@ export async function handleToolResult(deps) {
|
|
|
324
473
|
});
|
|
325
474
|
return { content: event.content, isError: true };
|
|
326
475
|
}
|
|
476
|
+
// Must happen before debounce admission: latestDeps intentionally retains only
|
|
477
|
+
// the latest event, but write -> edit is a sticky turn transition.
|
|
478
|
+
const receipt = runtime.recordMutationToolReceipt;
|
|
479
|
+
const autofixMode = deps._bypassDebounce
|
|
480
|
+
? (deps._autofixMode ?? (event.toolName === "edit" ? "deferred" : "immediate"))
|
|
481
|
+
: receipt
|
|
482
|
+
? receipt.call(runtime, filePath, event.toolName).autofixMode
|
|
483
|
+
: event.toolName === "edit"
|
|
484
|
+
? "deferred"
|
|
485
|
+
: "immediate";
|
|
327
486
|
// Coalesce sequential edits to the same file into one pipeline run against
|
|
328
487
|
// the final state. Only the debounce-fired call (with _bypassDebounce=true)
|
|
329
488
|
// proceeds to the pipeline body; in-window callers share its promise.
|
|
@@ -332,6 +491,7 @@ export async function handleToolResult(deps) {
|
|
|
332
491
|
if (debounceMs > 0) {
|
|
333
492
|
return scheduleDebounced(filePath, debounceMs, {
|
|
334
493
|
...deps,
|
|
494
|
+
_autofixMode: autofixMode,
|
|
335
495
|
_telemetryParticipantIds: [readGuardCorrelationId],
|
|
336
496
|
_telemetryParticipantTotal: 1,
|
|
337
497
|
});
|
|
@@ -402,13 +562,15 @@ export async function handleToolResult(deps) {
|
|
|
402
562
|
const dispatchCwd = resolveLanguageRootForFile(filePath, workspaceRoot);
|
|
403
563
|
const turnStateCwd = path.resolve(workspaceRoot);
|
|
404
564
|
dbg(`tool_result: resolved dispatch cwd ${dispatchCwd} for ${filePath} (turnState cwd ${turnStateCwd})`);
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
565
|
+
// #1655 item 2: a `setTelemetryIdentity` call used to sit here, gated on
|
|
566
|
+
// `event.model`/`provider`/`sessionId`/`session.id`. pi sets none of those on
|
|
567
|
+
// a `tool_result` — `afterToolCall` builds the event with exactly
|
|
568
|
+
// `type`/`toolName`/`toolCallId`/`input`/`content`/`details`/`isError`/`usage`
|
|
569
|
+
// (`@earendil-works/pi-coding-agent/dist/core/agent-session.js:243-256`,
|
|
570
|
+
// source `src/core/agent-session.ts:502-516`), so the gate was always false
|
|
571
|
+
// against a real host and the branch never ran. Identity for this dispatch
|
|
572
|
+
// comes from the runtime, which `message_start`/`session_start` populate —
|
|
573
|
+
// see the `telemetry:` block handed to `runPipeline` below.
|
|
412
574
|
const writeIndex = runtime.nextWriteIndex();
|
|
413
575
|
let modifiedRanges;
|
|
414
576
|
try {
|
|
@@ -469,12 +631,15 @@ export async function handleToolResult(deps) {
|
|
|
469
631
|
cwd: dispatchCwd,
|
|
470
632
|
projectRoot: turnStateCwd,
|
|
471
633
|
toolName: event.toolName,
|
|
634
|
+
autofixMode,
|
|
472
635
|
modifiedRanges,
|
|
473
636
|
telemetry: {
|
|
474
637
|
model: runtime.telemetryModel,
|
|
475
638
|
sessionId: runtime.telemetrySessionId,
|
|
476
639
|
turnIndex: runtime.turnIndex,
|
|
477
640
|
writeIndex,
|
|
641
|
+
modelId: runtime.telemetryModelId,
|
|
642
|
+
provider: runtime.telemetryProviderId,
|
|
478
643
|
},
|
|
479
644
|
getFlag,
|
|
480
645
|
getFlagSource,
|
|
@@ -487,6 +652,9 @@ export async function handleToolResult(deps) {
|
|
|
487
652
|
projectSeq: () => runtime.projectSeq,
|
|
488
653
|
getFilesChangedSince: (seq) => runtime.getFilesChangedSince(seq),
|
|
489
654
|
},
|
|
655
|
+
// The settle clock is live because the deferred cascade may reach its
|
|
656
|
+
// budget derivation before or after turn_end starts waiting.
|
|
657
|
+
turnEndCascadeSettleStart: () => runtime.getTurnEndCascadeSettleStart(),
|
|
490
658
|
// #348 phase 2: live reference so the deferred cascade can update the
|
|
491
659
|
// warm word index in place at the same seam as the graph rebuild.
|
|
492
660
|
// `runtime.wordIndex` is read fresh (not captured) via this closure-free
|
|
@@ -638,11 +806,19 @@ export async function handleToolResult(deps) {
|
|
|
638
806
|
}
|
|
639
807
|
}
|
|
640
808
|
}
|
|
809
|
+
let autofixNewlyQueued = false;
|
|
810
|
+
if (!result.isError && autofixMode === "deferred" && nodeFs.existsSync(filePath)) {
|
|
811
|
+
autofixNewlyQueued =
|
|
812
|
+
runtime.deferMutation?.call(runtime, filePath, dispatchCwd, event.toolName, turnStateCwd, "autofix", deps.sessionId, resolutionBasis) ?? false;
|
|
813
|
+
dbg(`tool_result: queued deferred autofix for ${filePath}`);
|
|
814
|
+
}
|
|
815
|
+
let formatQueued = false;
|
|
641
816
|
if (!result.isError &&
|
|
642
817
|
!getFlag("no-autoformat", filePath) &&
|
|
643
|
-
!getFlag("immediate-format") &&
|
|
818
|
+
(autofixMode === "deferred" || !getFlag("immediate-format")) &&
|
|
644
819
|
nodeFs.existsSync(filePath)) {
|
|
645
|
-
const isNewlyQueued = runtime.deferFormat(filePath, dispatchCwd, event.toolName, turnStateCwd, deps.sessionId);
|
|
820
|
+
const isNewlyQueued = runtime.deferFormat(filePath, dispatchCwd, event.toolName, turnStateCwd, deps.sessionId, resolutionBasis);
|
|
821
|
+
formatQueued = true;
|
|
646
822
|
dbg(`tool_result: queued deferred format for ${filePath}`);
|
|
647
823
|
logLatency({
|
|
648
824
|
type: "phase",
|
|
@@ -652,19 +828,21 @@ export async function handleToolResult(deps) {
|
|
|
652
828
|
durationMs: 0,
|
|
653
829
|
metadata: { cwd: dispatchCwd },
|
|
654
830
|
});
|
|
655
|
-
//
|
|
656
|
-
//
|
|
657
|
-
|
|
658
|
-
// queue", so re-emitting would be spam with zero new information.
|
|
659
|
-
if (isNewlyQueued) {
|
|
831
|
+
// Publish a file's first queue entry and each newly added kind. A same-kind
|
|
832
|
+
// re-touch before agent_end carries no new information and stays silent.
|
|
833
|
+
if (isNewlyQueued || autofixNewlyQueued) {
|
|
660
834
|
publishFormatQueued({
|
|
661
835
|
filePath,
|
|
662
836
|
cwd: dispatchCwd,
|
|
663
837
|
tool: event.toolName,
|
|
664
838
|
dbg,
|
|
839
|
+
kinds: autofixMode === "deferred" ? ["autofix", "format"] : ["format"],
|
|
665
840
|
});
|
|
666
841
|
}
|
|
667
842
|
}
|
|
843
|
+
if (autofixNewlyQueued && !formatQueued) {
|
|
844
|
+
publishFormatQueued({ filePath, cwd: dispatchCwd, tool: event.toolName, kinds: ["autofix"], dbg });
|
|
845
|
+
}
|
|
668
846
|
for (const changedFile of result.changedFiles ?? []) {
|
|
669
847
|
const resolvedChanged = path.resolve(changedFile);
|
|
670
848
|
if (!nodeFs.existsSync(resolvedChanged))
|
|
@@ -733,7 +911,10 @@ export async function handleToolResult(deps) {
|
|
|
733
911
|
}
|
|
734
912
|
}
|
|
735
913
|
if (result.inlineBlockerSummary) {
|
|
736
|
-
|
|
914
|
+
// #1561: stamp the verdict with THIS dispatch's write token — the same
|
|
915
|
+
// counter `lsp_diagnostics`' reconciliation seam draws from — so a later
|
|
916
|
+
// confirmed-clean result can be ordered against it instead of racing it.
|
|
917
|
+
runtime.recordInlineBlockers(filePath, result.inlineBlockerSummary, writeIndex, result.inlineBlockerSources, result.inlineBlockerLines);
|
|
737
918
|
}
|
|
738
919
|
else {
|
|
739
920
|
runtime.clearInlineBlockers(filePath);
|
|
@@ -764,9 +945,75 @@ export async function handleToolResult(deps) {
|
|
|
764
945
|
result: output ? "completed" : "no_output",
|
|
765
946
|
});
|
|
766
947
|
runtime.reportedThisTurn.add(filePath);
|
|
767
|
-
|
|
948
|
+
// --- The ONE authoritative-attachment decision (#1590) ---
|
|
949
|
+
// Everything downstream — the attached block, the telemetry row, the nudge
|
|
950
|
+
// suppression, and the notice sentence — reads this single verdict. It is
|
|
951
|
+
// the only place that sees both limits: the per-file cap and the shared
|
|
952
|
+
// per-command budget a multi-file bash write threads in.
|
|
953
|
+
const postMutation = result.postMutation;
|
|
954
|
+
const attachmentText = postMutation
|
|
955
|
+
? `pi-lens applied autofix to ${postMutation.filePath}. The following full content is authoritative for subsequent edits:\n\n${postMutation.content}`
|
|
956
|
+
: "";
|
|
957
|
+
const contentBytes = postMutation
|
|
958
|
+
? Buffer.byteLength(postMutation.content, "utf-8")
|
|
959
|
+
: 0;
|
|
960
|
+
const withinPerFileCap = contentBytes <= AUTHORITATIVE_CONTENT_MAX_BYTES;
|
|
961
|
+
const budget = deps._attachmentBudget;
|
|
962
|
+
const withinSharedBudget = !budget || Buffer.byteLength(attachmentText, "utf-8") <= budget.remaining;
|
|
963
|
+
const attachAuthoritativeContent = postMutation !== undefined && withinPerFileCap && withinSharedBudget;
|
|
964
|
+
const attachmentDecision = !postMutation
|
|
965
|
+
? "none"
|
|
966
|
+
: attachAuthoritativeContent
|
|
967
|
+
? "attached"
|
|
968
|
+
: withinPerFileCap
|
|
969
|
+
? "aggregate-budget-degraded"
|
|
970
|
+
: "size-capped";
|
|
971
|
+
// #1590: the pipeline hands up the changed-file data and this layer renders
|
|
972
|
+
// the sentence, so a size-capped write can no longer carry both "attached
|
|
973
|
+
// content is authoritative" and "too large to attach". The fallback covers
|
|
974
|
+
// a post-mutation with no notice data, which must still say re-read.
|
|
975
|
+
const notice = result.postAutofixNotice ??
|
|
976
|
+
(postMutation
|
|
977
|
+
? { targetPath: postMutation.filePath, changedFiles: [] }
|
|
978
|
+
: undefined);
|
|
979
|
+
if (postMutation && attachAuthoritativeContent && budget) {
|
|
980
|
+
budget.remaining -= Buffer.byteLength(attachmentText, "utf-8");
|
|
981
|
+
}
|
|
982
|
+
// #1590 review F1: every mutation that produced a notice logs a row,
|
|
983
|
+
// INCLUDING the `none` decision a format-only change makes. Gating the row
|
|
984
|
+
// on `postMutation` made a legitimate "nothing was attachable here" verdict
|
|
985
|
+
// indistinguishable from missing instrumentation, which is the same
|
|
986
|
+
// empty-vs-errored confusion the read paths already guard against.
|
|
987
|
+
if (postMutation || notice) {
|
|
988
|
+
logLatency({
|
|
989
|
+
type: "phase",
|
|
990
|
+
phase: "authoritative_content_attachment_decision",
|
|
991
|
+
filePath: postMutation?.filePath ?? filePath,
|
|
992
|
+
durationMs: 0,
|
|
993
|
+
metadata: {
|
|
994
|
+
path: postMutation?.filePath ?? filePath,
|
|
995
|
+
bytes: contentBytes,
|
|
996
|
+
decision: attachmentDecision,
|
|
997
|
+
},
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
if (postMutation) {
|
|
1001
|
+
// #1464: the nudge suppresses exactly the paths this decision
|
|
1002
|
+
// delivered. Same boolean the attachment below reads — the nudge layer
|
|
1003
|
+
// never re-derives the cap or the budget for itself.
|
|
1004
|
+
noteAuthoritativeContentAttachment(postMutation.filePath, attachAuthoritativeContent);
|
|
1005
|
+
}
|
|
1006
|
+
const returnedContent = attachAuthoritativeContent
|
|
1007
|
+
? [...event.content, { type: "text", text: attachmentText }]
|
|
1008
|
+
: event.content;
|
|
1009
|
+
if (notice) {
|
|
1010
|
+
output = `${output ? `${output}\n\n` : ""}${renderPostAutofixNotice(notice, attachmentDecision)}`;
|
|
1011
|
+
}
|
|
1012
|
+
if (!output && !result.postMutation)
|
|
768
1013
|
return;
|
|
769
1014
|
return {
|
|
770
|
-
content:
|
|
1015
|
+
content: output
|
|
1016
|
+
? [...returnedContent, { type: "text", text: output }]
|
|
1017
|
+
: returnedContent,
|
|
771
1018
|
};
|
|
772
1019
|
}
|