@herbertgao/pi-extensions 2026.8.4 → 2026.8.6

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 (360) hide show
  1. package/README.md +5 -5
  2. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +11 -3
  3. package/node_modules/@herbertgao/pi-cc-extensions/README.md +11 -3
  4. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +24 -0
  5. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +91 -1
  6. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +7 -3
  7. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +74 -5
  8. package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +7 -6
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +21 -12
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +4 -5
  11. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +53 -14
  12. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +22 -12
  13. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +2 -4
  14. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  15. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +18 -0
  16. package/node_modules/@herbertgao/pi-subagents/package.json +8 -4
  17. package/node_modules/@herbertgao/pi-subagents/src/agent-color.ts +72 -67
  18. package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +255 -0
  19. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +191 -3
  20. package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +20 -4
  21. package/node_modules/@herbertgao/pi-subagents/src/index.ts +289 -113
  22. package/node_modules/@herbertgao/pi-subagents/src/output-file.ts +24 -1
  23. package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +24 -2
  24. package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +15 -6
  25. package/node_modules/@herbertgao/pi-subagents/src/ui/schedule-menu.ts +9 -8
  26. package/node_modules/@herbertgao/pi-subagents/src/ui/select-item.ts +48 -0
  27. package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +9 -5
  28. package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +2 -0
  29. package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +20 -0
  30. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +6 -0
  31. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/keyboard.md +7 -0
  32. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  33. package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +7 -0
  34. package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +16 -5
  35. package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +4 -2
  36. package/node_modules/@narumitw/pi-btw/README.md +32 -24
  37. package/node_modules/@narumitw/pi-btw/package.json +6 -6
  38. package/node_modules/@narumitw/pi-btw/src/btw.ts +4 -2
  39. package/node_modules/@narumitw/pi-btw/src/menu.ts +34 -13
  40. package/node_modules/@narumitw/pi-btw/src/settings.ts +22 -2
  41. package/node_modules/pi-lens/CHANGELOG.md +2535 -954
  42. package/node_modules/pi-lens/README.md +13 -0
  43. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +73 -18
  44. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +314 -0
  45. package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +21 -4
  46. package/node_modules/pi-lens/dist/clients/agent-nudge.js +14 -7
  47. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +68 -16
  48. package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -1
  49. package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +37 -10
  50. package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +63 -0
  51. package/node_modules/pi-lens/dist/clients/atomic-write.js +114 -14
  52. package/node_modules/pi-lens/dist/clients/bash-file-access.js +193 -23
  53. package/node_modules/pi-lens/dist/clients/biome-client.js +136 -24
  54. package/node_modules/pi-lens/dist/clients/bootstrap.js +11 -2
  55. package/node_modules/pi-lens/dist/clients/bounded-cache.js +34 -0
  56. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +192 -0
  57. package/node_modules/pi-lens/dist/clients/bus-events-logger.js +62 -6
  58. package/node_modules/pi-lens/dist/clients/bus-publish.js +19 -4
  59. package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +47 -5
  60. package/node_modules/pi-lens/dist/clients/cache-manager.js +97 -9
  61. package/node_modules/pi-lens/dist/clients/cache-observability.js +301 -14
  62. package/node_modules/pi-lens/dist/clients/call-graph.js +449 -117
  63. package/node_modules/pi-lens/dist/clients/cascade-format.js +57 -2
  64. package/node_modules/pi-lens/dist/clients/child-unref.js +85 -0
  65. package/node_modules/pi-lens/dist/clients/codebase-model.js +52 -23
  66. package/node_modules/pi-lens/dist/clients/collateral-test-role.js +40 -0
  67. package/node_modules/pi-lens/dist/clients/complexity-client.js +2 -1
  68. package/node_modules/pi-lens/dist/clients/console-guard-install.js +26 -0
  69. package/node_modules/pi-lens/dist/clients/cooperative-budget.js +42 -0
  70. package/node_modules/pi-lens/dist/clients/dead-code-client.js +137 -31
  71. package/node_modules/pi-lens/dist/clients/debug-handles.js +206 -0
  72. package/node_modules/pi-lens/dist/clients/debug-heap.js +167 -0
  73. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +153 -0
  74. package/node_modules/pi-lens/dist/clients/dependency-checker.js +361 -77
  75. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +65 -13
  76. package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +18 -4
  77. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +176 -29
  78. package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +23 -7
  79. package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +8 -18
  80. package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +8 -5
  81. package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +35 -0
  82. package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +17 -8
  83. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +1172 -683
  84. package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +14 -0
  85. package/node_modules/pi-lens/dist/clients/dispatch/plan.js +11 -1
  86. package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +50 -0
  87. package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +135 -0
  88. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +23 -5
  89. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +5 -9
  90. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +3 -2
  91. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +2 -1
  92. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +154 -0
  93. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +3 -2
  94. package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +5 -1
  95. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +47 -6
  96. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +4 -9
  97. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +9 -5
  98. package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +4 -8
  99. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +2 -3
  100. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -3
  101. package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +2 -1
  102. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +2 -1
  103. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +163 -0
  104. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +37 -5
  105. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +3 -1
  106. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +13 -7
  107. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +226 -0
  108. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +69 -0
  109. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +3 -0
  110. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +473 -42
  111. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +22 -0
  112. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +97 -0
  113. package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +5 -4
  114. package/node_modules/pi-lens/dist/clients/disposition-publish.js +18 -4
  115. package/node_modules/pi-lens/dist/clients/durable-store.js +97 -0
  116. package/node_modules/pi-lens/dist/clients/eval-timestamp.js +17 -0
  117. package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +94 -3
  118. package/node_modules/pi-lens/dist/clients/extension-log.js +432 -0
  119. package/node_modules/pi-lens/dist/clients/extension-mode.js +73 -0
  120. package/node_modules/pi-lens/dist/clients/file-kinds.js +57 -0
  121. package/node_modules/pi-lens/dist/clients/file-role.js +18 -3
  122. package/node_modules/pi-lens/dist/clients/file-utils.js +56 -34
  123. package/node_modules/pi-lens/dist/clients/fix-worklog.js +5 -1
  124. package/node_modules/pi-lens/dist/clients/format-events-publish.js +51 -7
  125. package/node_modules/pi-lens/dist/clients/format-service.js +24 -8
  126. package/node_modules/pi-lens/dist/clients/formatters-lazy.js +8 -0
  127. package/node_modules/pi-lens/dist/clients/formatters.js +358 -61
  128. package/node_modules/pi-lens/dist/clients/generated-artifacts.js +148 -15
  129. package/node_modules/pi-lens/dist/clients/git-guard.js +678 -11
  130. package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +4 -0
  131. package/node_modules/pi-lens/dist/clients/go-client.js +23 -40
  132. package/node_modules/pi-lens/dist/clients/govulncheck-client.js +124 -7
  133. package/node_modules/pi-lens/dist/clients/grammar-source.js +12 -4
  134. package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +21 -3
  135. package/node_modules/pi-lens/dist/clients/host-ports.js +31 -0
  136. package/node_modules/pi-lens/dist/clients/installer/index.js +395 -100
  137. package/node_modules/pi-lens/dist/clients/instance-reaper.js +142 -172
  138. package/node_modules/pi-lens/dist/clients/jscpd-client.js +27 -55
  139. package/node_modules/pi-lens/dist/clients/knip-client.js +58 -42
  140. package/node_modules/pi-lens/dist/clients/language-policy.js +14 -2
  141. package/node_modules/pi-lens/dist/clients/language-profile.js +13 -7
  142. package/node_modules/pi-lens/dist/clients/latency-logger.js +72 -1
  143. package/node_modules/pi-lens/dist/clients/lens-config.js +12 -1
  144. package/node_modules/pi-lens/dist/clients/lens-engine.js +86 -17
  145. package/node_modules/pi-lens/dist/clients/lens-events.js +63 -9
  146. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +16 -0
  147. package/node_modules/pi-lens/dist/clients/lens-map.js +94 -19
  148. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +73 -0
  149. package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -1
  150. package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +30 -4
  151. package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +59 -14
  152. package/node_modules/pi-lens/dist/clients/lsp/client.js +662 -56
  153. package/node_modules/pi-lens/dist/clients/lsp/config.js +13 -2
  154. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +115 -0
  155. package/node_modules/pi-lens/dist/clients/lsp/edits.js +1012 -121
  156. package/node_modules/pi-lens/dist/clients/lsp/index.js +2025 -800
  157. package/node_modules/pi-lens/dist/clients/lsp/launch.js +32 -26
  158. package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
  159. package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +83 -0
  160. package/node_modules/pi-lens/dist/clients/lsp/server.js +437 -86
  161. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +96 -0
  162. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +21 -5
  163. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +18 -3
  164. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +28 -4
  165. package/node_modules/pi-lens/dist/clients/lsp-lazy.js +8 -0
  166. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +248 -0
  167. package/node_modules/pi-lens/dist/clients/mcp/analyze.js +127 -32
  168. package/node_modules/pi-lens/dist/clients/mcp/ipc.js +157 -24
  169. package/node_modules/pi-lens/dist/clients/mcp/session.js +235 -14
  170. package/node_modules/pi-lens/dist/clients/memory-sampler.js +115 -0
  171. package/node_modules/pi-lens/dist/clients/metrics-client.js +2 -1
  172. package/node_modules/pi-lens/dist/clients/metrics-history.js +2 -1
  173. package/node_modules/pi-lens/dist/clients/model-provider.js +53 -0
  174. package/node_modules/pi-lens/dist/clients/module-report-lsp.js +5 -0
  175. package/node_modules/pi-lens/dist/clients/module-report.js +168 -3
  176. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +319 -118
  177. package/node_modules/pi-lens/dist/clients/opengrep-client.js +1 -1
  178. package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +120 -5
  179. package/node_modules/pi-lens/dist/clients/path-utils.js +110 -9
  180. package/node_modules/pi-lens/dist/clients/pipeline.js +76 -15
  181. package/node_modules/pi-lens/dist/clients/print-mode.js +21 -0
  182. package/node_modules/pi-lens/dist/clients/project-changes.js +40 -0
  183. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +3 -2
  184. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +1 -1
  185. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +8 -0
  186. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +23 -2
  187. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +21 -1
  188. package/node_modules/pi-lens/dist/clients/project-lens-config.js +86 -9
  189. package/node_modules/pi-lens/dist/clients/project-report.js +27 -13
  190. package/node_modules/pi-lens/dist/clients/project-snapshot.js +175 -20
  191. package/node_modules/pi-lens/dist/clients/project-trust.js +181 -0
  192. package/node_modules/pi-lens/dist/clients/quiet-window.js +18 -4
  193. package/node_modules/pi-lens/dist/clients/read-bridge.js +147 -0
  194. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +159 -1
  195. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +150 -29
  196. package/node_modules/pi-lens/dist/clients/read-guard.js +185 -4
  197. package/node_modules/pi-lens/dist/clients/resource-sampler.js +70 -84
  198. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +1122 -221
  199. package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +2 -1
  200. package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +21 -10
  201. package/node_modules/pi-lens/dist/clients/review-graph/query.js +24 -0
  202. package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +46 -0
  203. package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +57 -6
  204. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +51 -3
  205. package/node_modules/pi-lens/dist/clients/review-graph-logger.js +30 -1
  206. package/node_modules/pi-lens/dist/clients/ruff-client.js +27 -44
  207. package/node_modules/pi-lens/dist/clients/run-duration.js +55 -0
  208. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +257 -77
  209. package/node_modules/pi-lens/dist/clients/runtime-context.js +129 -12
  210. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +242 -26
  211. package/node_modules/pi-lens/dist/clients/runtime-session.js +428 -117
  212. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +71 -48
  213. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +342 -33
  214. package/node_modules/pi-lens/dist/clients/runtime-turn.js +619 -93
  215. package/node_modules/pi-lens/dist/clients/rust-client.js +23 -38
  216. package/node_modules/pi-lens/dist/clients/safe-spawn.js +777 -62
  217. package/node_modules/pi-lens/dist/clients/security-scan-client.js +90 -6
  218. package/node_modules/pi-lens/dist/clients/session-state-store.js +3 -2
  219. package/node_modules/pi-lens/dist/clients/sg-runner.js +424 -196
  220. package/node_modules/pi-lens/dist/clients/slow-fs.js +2 -1
  221. package/node_modules/pi-lens/dist/clients/smells-rollup.js +231 -0
  222. package/node_modules/pi-lens/dist/clients/source-filter.js +184 -20
  223. package/node_modules/pi-lens/dist/clients/source-walker.js +66 -10
  224. package/node_modules/pi-lens/dist/clients/startup-scan.js +15 -16
  225. package/node_modules/pi-lens/dist/clients/startup-timing.js +7 -1
  226. package/node_modules/pi-lens/dist/clients/test-runner-client.js +469 -32
  227. package/node_modules/pi-lens/dist/clients/tool-event.js +35 -0
  228. package/node_modules/pi-lens/dist/clients/tool-policy.js +390 -39
  229. package/node_modules/pi-lens/dist/clients/tool-render.js +155 -0
  230. package/node_modules/pi-lens/dist/clients/tool-set-policy.js +76 -0
  231. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +6 -1
  232. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +419 -50
  233. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +21 -0
  234. package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +7 -1
  235. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +7 -2
  236. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +44 -7
  237. package/node_modules/pi-lens/dist/clients/user-notify.js +51 -0
  238. package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +57 -0
  239. package/node_modules/pi-lens/dist/clients/warm-attach.js +50 -13
  240. package/node_modules/pi-lens/dist/clients/widget-state.js +300 -43
  241. package/node_modules/pi-lens/dist/clients/word-index.js +680 -81
  242. package/node_modules/pi-lens/dist/clients/workspace-topology.js +89 -6
  243. package/node_modules/pi-lens/dist/index.js +51785 -36118
  244. package/node_modules/pi-lens/dist/mcp/analyze-cli.js +182 -29
  245. package/node_modules/pi-lens/dist/mcp/server.js +219 -46
  246. package/node_modules/pi-lens/dist/tools/activate-tools.js +17 -5
  247. package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +9 -4
  248. package/node_modules/pi-lens/dist/tools/ast-grep-search.js +93 -27
  249. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +5 -2
  250. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +203 -38
  251. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +210 -42
  252. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -3
  253. package/node_modules/pi-lens/dist/tools/module-report.js +9 -0
  254. package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -1
  255. package/node_modules/pi-lens/docs/agent-guide.md +40 -15
  256. package/node_modules/pi-lens/docs/agent-tools.md +21 -10
  257. package/node_modules/pi-lens/docs/analysisall.md +192 -0
  258. package/node_modules/pi-lens/docs/api-ports-inventory.md +165 -0
  259. package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +14 -3
  260. package/node_modules/pi-lens/docs/durable-store-audit-1202.md +32 -0
  261. package/node_modules/pi-lens/docs/environment-variables.md +44 -0
  262. package/node_modules/pi-lens/docs/fable.md +27 -0
  263. package/node_modules/pi-lens/docs/features.md +45 -3
  264. package/node_modules/pi-lens/docs/globalconfig.md +56 -1
  265. package/node_modules/pi-lens/docs/language-coverage.md +4 -3
  266. package/node_modules/pi-lens/docs/lsp-capability-matrix.md +2 -2
  267. package/node_modules/pi-lens/docs/mcp.md +37 -4
  268. package/node_modules/pi-lens/docs/servercapabilities.md +3 -3
  269. package/node_modules/pi-lens/docs/settings.md +18 -1
  270. package/node_modules/pi-lens/docs/tools.md +4 -1
  271. package/node_modules/pi-lens/docs/usage.md +41 -5
  272. package/node_modules/pi-lens/docs/word-index.md +35 -0
  273. package/node_modules/pi-lens/package.json +10 -10
  274. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-except-test.yml +49 -0
  275. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-host-path-in-win32-branch-test.yml +87 -0
  276. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +8 -0
  277. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-js-test.yml +9 -0
  278. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-test.yml +9 -0
  279. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-nested-links-test.yml +11 -1
  280. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-raw-json-store-write-test.yml +17 -0
  281. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +7 -0
  282. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +7 -0
  283. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +8 -0
  284. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +8 -0
  285. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-laundering-test.yml +11 -0
  286. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-win32-isabsolute-for-qualification-test.yml +16 -0
  287. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-except.yml +3 -15
  288. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +25 -0
  289. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +21 -0
  290. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread-js.yml +21 -0
  291. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread.yml +29 -0
  292. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-nested-links.yml +7 -0
  293. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +30 -0
  294. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +9 -0
  295. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +9 -0
  296. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +13 -0
  297. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +16 -0
  298. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +27 -0
  299. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +23 -0
  300. package/node_modules/pi-lens/rules/tree-sitter-queries/tsx/no-nested-links.yml +4 -6
  301. package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/duplicate-function-arg.yml +2 -2
  302. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +134 -2
  303. package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +10 -11
  304. package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +22 -22
  305. package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +8 -114
  306. package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +129 -0
  307. package/node_modules/pi-lens/skills/pi-lens-write-tree-sitter-rule/SKILL.md +3 -1
  308. package/node_modules/pi-mcp-adapter/CHANGELOG.md +38 -0
  309. package/node_modules/pi-mcp-adapter/README.md +38 -4
  310. package/node_modules/pi-mcp-adapter/agent-dir.ts +12 -4
  311. package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +1 -1
  312. package/node_modules/pi-mcp-adapter/cli.js +25 -4
  313. package/node_modules/pi-mcp-adapter/commands.ts +15 -7
  314. package/node_modules/pi-mcp-adapter/config.ts +4 -4
  315. package/node_modules/pi-mcp-adapter/direct-tools.ts +58 -8
  316. package/node_modules/pi-mcp-adapter/host-html-template.ts +0 -8
  317. package/node_modules/pi-mcp-adapter/index.ts +8 -3
  318. package/node_modules/pi-mcp-adapter/init.ts +29 -5
  319. package/node_modules/pi-mcp-adapter/lifecycle.ts +0 -4
  320. package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +1 -2
  321. package/node_modules/pi-mcp-adapter/mcp-auth.ts +60 -2
  322. package/node_modules/pi-mcp-adapter/mcp-panel.ts +45 -9
  323. package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +22 -20
  324. package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +2 -1
  325. package/node_modules/pi-mcp-adapter/metadata-cache.ts +37 -4
  326. package/node_modules/pi-mcp-adapter/npx-resolver.ts +81 -26
  327. package/node_modules/pi-mcp-adapter/package.json +4 -3
  328. package/node_modules/pi-mcp-adapter/proxy-modes.ts +108 -26
  329. package/node_modules/pi-mcp-adapter/request-headers-command.ts +336 -0
  330. package/node_modules/pi-mcp-adapter/search-ranking.ts +86 -7
  331. package/node_modules/pi-mcp-adapter/server-manager.ts +41 -7
  332. package/node_modules/pi-mcp-adapter/session-recovery.ts +8 -2
  333. package/node_modules/pi-mcp-adapter/tool-approval.ts +48 -7
  334. package/node_modules/pi-mcp-adapter/tool-metadata.ts +62 -4
  335. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +138 -12
  336. package/node_modules/pi-mcp-adapter/types.ts +176 -27
  337. package/node_modules/pi-mcp-adapter/ui-server.ts +20 -1
  338. package/node_modules/pi-web-access/CHANGELOG.md +14 -0
  339. package/node_modules/pi-web-access/README.md +18 -12
  340. package/node_modules/pi-web-access/auth-fetch.ts +148 -0
  341. package/node_modules/pi-web-access/chrome-cookies.ts +110 -23
  342. package/node_modules/pi-web-access/curator-page.ts +5 -3
  343. package/node_modules/pi-web-access/curator-server.ts +2 -1
  344. package/node_modules/pi-web-access/extract.ts +106 -34
  345. package/node_modules/pi-web-access/fetch-params.ts +17 -3
  346. package/node_modules/pi-web-access/firecrawl.ts +172 -12
  347. package/node_modules/pi-web-access/gemini-search.ts +18 -4
  348. package/node_modules/pi-web-access/index.ts +120 -48
  349. package/node_modules/pi-web-access/package.json +2 -2
  350. package/node_modules/pi-web-access/summary-review.ts +11 -5
  351. package/node_modules/pi-web-access/youtube-extract.ts +2 -2
  352. package/package.json +12 -13
  353. package/node_modules/pi-lens/dist/clients/ast-grep-parser.js +0 -86
  354. package/node_modules/pi-lens/dist/clients/lsp/interactive-install.js +0 -367
  355. package/node_modules/pi-lens/dist/clients/lsp/lsp-index.js +0 -10
  356. package/node_modules/pi-lens/dist/clients/lsp/server-strategies.js +0 -5
  357. package/node_modules/pi-lens/dist/clients/project-metadata.js +0 -690
  358. package/node_modules/pi-lens/dist/clients/source-groups.js +0 -96
  359. package/node_modules/pi-lens/dist/clients/startup-marker.js +0 -6
  360. package/node_modules/pi-lens/dist/clients/types.js +0 -11
package/README.md CHANGED
@@ -11,13 +11,13 @@ pi install npm:@herbertgao/pi-extensions
11
11
  The package bundles 11 active `@herbertgao/*` child packages, including `@herbertgao/pi-cc-extensions`, plus the following upstream packages under their original names:
12
12
 
13
13
  - `@dietrichgebert/ponytail@4.9.0`
14
- - `@juicesharp/rpiv-ask-user-question@2.4.0`
15
- - `@narumitw/pi-btw@0.50.0`
14
+ - `@juicesharp/rpiv-ask-user-question@2.6.0`
15
+ - `@narumitw/pi-btw@0.52.0`
16
16
  - `@pi-plugins/fast-mode@0.1.9`
17
- - `pi-mcp-adapter@2.23.0`
17
+ - `pi-mcp-adapter@2.26.0`
18
18
  - `pi-footer@0.5.1`
19
- - `pi-lens@3.8.74`
20
- - `pi-web-access@0.22.0`
19
+ - `pi-lens@4.0.1`
20
+ - `pi-web-access@0.23.0`
21
21
  - `remote-pi@0.7.0`
22
22
  - `@czottmann/pi-automode@1.11.0`
23
23
 
@@ -39,8 +39,8 @@ Run `/reload` after installation.
39
39
  | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
40
40
  | Claude Code Output | Tool summaries, expand/collapse, rich edit/write diffs, and `on` / `compact` / `off` modes | `/ccstyle` |
41
41
  | Fullscreen mode | Tool card/group click-to-toggle, previews, hover highlight, and a back-to-bottom button | `TUIMODE=fullscreen` or `--tui-mode fullscreen` |
42
- | Settings panel | `Style / Diff / Thinking / Feature` tabs: startup header toggle and wheel step | `/ccstyle` |
43
- | Context inspection | Usage breakdown and previews for the system prompt, tools, skills, and messages | `/context` |
42
+ | Settings panel | `Style / Diff / Thinking / Feature` tabs with startup, wheel, and optional feature toggles | `/ccstyle` |
43
+ | Context inspection | Usage breakdown and previews for the system prompt, tools, tool results, skills, and messages | `/context` |
44
44
  | Session/Subagent references | Search and inject effective context from previous Sessions or existing SubAgents | `@` |
45
45
  | Theme | Bundled CC Dark and CC Light themes | `/theme` |
46
46
 
@@ -62,10 +62,18 @@ Run `/reload` after installation.
62
62
  "previewLines": 3, // thinking preview lines; 0 hides the preview body
63
63
  "animationIntervalMs": 90, // thinking title animation interval in ms
64
64
  "showStartupHeader": true, // custom startup header (logo + tips) toggle
65
- "scrollStepLines": 3 // fullscreen mouse wheel scroll lines
65
+ "scrollStepLines": 3, // fullscreen mouse wheel scroll lines
66
+ "enableSessionReference": true, // @ session references
67
+ "enableSubagentAutocomplete": true, // @ subagent autocomplete
68
+ "enableContextCommand": true, // /context inspection
69
+ "enableAgentSummary": true, // per-turn tool summary
70
+ "enableWorkingMessage": true, // Working... token/time details
71
+ "enableAliases": true // /clear and /exit aliases
66
72
  }
67
73
  ```
68
74
 
75
+ > **Tip**: set Mermaid diagrams to `final` in `/settings` to avoid redrawing streaming content frame by frame.
76
+
69
77
  ## Local development
70
78
 
71
79
  ```bash
@@ -39,8 +39,8 @@ pi install npm:@herbertgao/pi-cc-extensions
39
39
  | ---------------------- | ---------------------------------------------------------------------------------------------------------- | ------------- |
40
40
  | Claude Code UI | 工具摘要、折叠展开、rich edit/write diff,以及 `on` / `compact` / `off` 三种模式 | `/ccstyle` |
41
41
  | Fullscreen mode | 工具卡/group 点击展开与收起、预览、hover 高亮、回到底部按钮 | `TUIMODE=fullscreen` 或 `--tui-mode fullscreen` |
42
- | 配置面板 | `Style / Diff / Thinking / Feature` 四页签,含启动头开关与滚轮步进 | `/ccstyle` |
43
- | 上下文检查 | 查看上下文占用,并预览 System prompt、Tools、Skills 和消息内容 | `/context` |
42
+ | 配置面板 | `Style / Diff / Thinking / Feature` 四页签,含启动头、滚轮步进及可选功能开关 | `/ccstyle` |
43
+ | 上下文检查 | 查看上下文占用,并预览 System prompt、Tools、Tool results、Skills 和消息内容 | `/context` |
44
44
  | Session/Subagent 引用 | 搜索并注入历史 Session 或现有 SubAgent 的有效上下文 | `@` |
45
45
  | 主题 | 随包提供内置 CC Dark、CC Light 主题 | `/theme` |
46
46
 
@@ -62,10 +62,18 @@ pi install npm:@herbertgao/pi-cc-extensions
62
62
  "previewLines": 3, // thinking 预览行数,0 隐藏预览正文
63
63
  "animationIntervalMs": 90, // thinking 标题动画间隔(毫秒)
64
64
  "showStartupHeader": true, // 自定义启动头(logo + tips)开关
65
- "scrollStepLines": 3 // fullscreen 滚轮滚动步进行数
65
+ "scrollStepLines": 3, // fullscreen 滚轮滚动步进行数
66
+ "enableSessionReference": true, // @ session 引用
67
+ "enableSubagentAutocomplete": true, // @ subagent 自动补全
68
+ "enableContextCommand": true, // /context 上下文检查
69
+ "enableAgentSummary": true, // 每回合工具统计摘要
70
+ "enableWorkingMessage": true, // Working... token/耗时展示
71
+ "enableAliases": true // /clear、/exit 别名
66
72
  }
67
73
  ```
68
74
 
75
+ > **建议**:在 `/settings` 中将 Mermaid diagrams 设为 `final`,避免流式内容逐帧重绘。
76
+
69
77
  ## 本地开发
70
78
 
71
79
  ```bash
@@ -25,6 +25,12 @@ export type Config = {
25
25
  animationIntervalMs: number;
26
26
  showStartupHeader: boolean;
27
27
  scrollStepLines: number;
28
+ enableSessionReference: boolean;
29
+ enableSubagentAutocomplete: boolean;
30
+ enableContextCommand: boolean;
31
+ enableAgentSummary: boolean;
32
+ enableWorkingMessage: boolean;
33
+ enableAliases: boolean;
28
34
  };
29
35
 
30
36
  const AGENT_DIR = process.env.PI_CODING_AGENT_DIR ?? join(homedir(), ".pi", "agent");
@@ -67,6 +73,12 @@ export const DEFAULT_CONFIG: Config = {
67
73
  animationIntervalMs: 90,
68
74
  showStartupHeader: true,
69
75
  scrollStepLines: 3,
76
+ enableSessionReference: true,
77
+ enableSubagentAutocomplete: true,
78
+ enableContextCommand: true,
79
+ enableAgentSummary: true,
80
+ enableWorkingMessage: true,
81
+ enableAliases: true,
70
82
  };
71
83
 
72
84
  function pickEnum<T extends string>(value: unknown, allowed: readonly T[], fallback: T): T {
@@ -148,6 +160,12 @@ export function normalizeConfig(input: unknown): Config {
148
160
  ),
149
161
  showStartupHeader: source.showStartupHeader !== false,
150
162
  scrollStepLines: pickPositiveInt(source.scrollStepLines, DEFAULT_CONFIG.scrollStepLines, 1, 50),
163
+ enableSessionReference: source.enableSessionReference !== false,
164
+ enableSubagentAutocomplete: source.enableSubagentAutocomplete !== false,
165
+ enableContextCommand: source.enableContextCommand !== false,
166
+ enableAgentSummary: source.enableAgentSummary !== false,
167
+ enableWorkingMessage: source.enableWorkingMessage !== false,
168
+ enableAliases: source.enableAliases !== false,
151
169
  };
152
170
  }
153
171
 
@@ -189,6 +207,12 @@ export function formatConfigStatus(source: Config = config): string {
189
207
  `thinkingAnimation=${source.animationIntervalMs}ms`,
190
208
  `startupHeader=${source.showStartupHeader ? "on" : "off"}`,
191
209
  `scrollStep=${source.scrollStepLines}`,
210
+ `sessionRef=${source.enableSessionReference ? "on" : "off"}`,
211
+ `subagentAuto=${source.enableSubagentAutocomplete ? "on" : "off"}`,
212
+ `context=${source.enableContextCommand ? "on" : "off"}`,
213
+ `agentSummary=${source.enableAgentSummary ? "on" : "off"}`,
214
+ `workingMsg=${source.enableWorkingMessage ? "on" : "off"}`,
215
+ `aliases=${source.enableAliases ? "on" : "off"}`,
192
216
  ].join(" · ");
193
217
  }
194
218
 
@@ -64,6 +64,29 @@ function diffIndicatorDescription(mode: DiffIndicatorMode): string {
64
64
  return "Vertical bar indicators on changed lines (default).";
65
65
  }
66
66
 
67
+ function featureToggleSetting(
68
+ id: string,
69
+ label: string,
70
+ onDescription: string,
71
+ offDescription: string,
72
+ current: boolean,
73
+ ) {
74
+ const setting = {
75
+ id,
76
+ label,
77
+ description: current ? onDescription : offDescription,
78
+ currentValue: current ? "on" : "off",
79
+ values: ["on", "off"],
80
+ };
81
+ return {
82
+ setting,
83
+ apply(on: boolean): void {
84
+ setting.currentValue = on ? "on" : "off";
85
+ setting.description = on ? onDescription : offDescription;
86
+ },
87
+ };
88
+ }
89
+
67
90
  function buildExcludeRenderersSubmenu(
68
91
  onClose: () => void,
69
92
  onLiveChange: () => void,
@@ -333,8 +356,66 @@ export async function showCcstylePanel(
333
356
  submenu: (_current: string, closeSubmenu: (selected?: string) => void) =>
334
357
  buildNumberInputSubmenu(theme, scrollStepSetting, closeSubmenu),
335
358
  };
359
+ const sessionReferenceToggle = featureToggleSetting(
360
+ "enableSessionReference",
361
+ "Session reference",
362
+ "@ session mentions search and inject referenced context after restart.",
363
+ "Session reference disabled.",
364
+ config.enableSessionReference,
365
+ );
366
+ const subagentAutocompleteToggle = featureToggleSetting(
367
+ "enableSubagentAutocomplete",
368
+ "Subagent autocomplete",
369
+ "@ subagent mentions suggest agents and delegation instructions after restart.",
370
+ "Subagent autocomplete disabled.",
371
+ config.enableSubagentAutocomplete,
372
+ );
373
+ const contextCommandToggle = featureToggleSetting(
374
+ "enableContextCommand",
375
+ "Context usage",
376
+ "/context shows context-window distribution after restart.",
377
+ "Context command disabled.",
378
+ config.enableContextCommand,
379
+ );
380
+ const agentSummaryToggle = featureToggleSetting(
381
+ "enableAgentSummary",
382
+ "Agent summary",
383
+ "Append per-round tool stats after each agent turn after restart.",
384
+ "Agent summary disabled.",
385
+ config.enableAgentSummary,
386
+ );
387
+ const workingMessageToggle = featureToggleSetting(
388
+ "enableWorkingMessage",
389
+ "Working message",
390
+ "Extend Working... with token count and elapsed time after restart.",
391
+ "Native Working... footer only.",
392
+ config.enableWorkingMessage,
393
+ );
394
+ const aliasesToggle = featureToggleSetting(
395
+ "enableAliases",
396
+ "Aliases",
397
+ "/clear and /exit aliases enabled after restart.",
398
+ "Aliases disabled.",
399
+ config.enableAliases,
400
+ );
401
+ const featureToggles: Record<string, { apply: (on: boolean) => void }> = {
402
+ enableSessionReference: sessionReferenceToggle,
403
+ enableSubagentAutocomplete: subagentAutocompleteToggle,
404
+ enableContextCommand: contextCommandToggle,
405
+ enableAgentSummary: agentSummaryToggle,
406
+ enableWorkingMessage: workingMessageToggle,
407
+ enableAliases: aliasesToggle,
408
+ };
336
409
 
337
410
  const onSettingChange = (id: string, value: string) => {
411
+ const featureToggle = featureToggles[id];
412
+ if (featureToggle) {
413
+ (config as unknown as Record<string, boolean>)[id] = value === "on";
414
+ featureToggle.apply(value === "on");
415
+ saveConfig();
416
+ ctx.ui.notify(`Updated ${id}: ${value} (next restart)`, "info");
417
+ return;
418
+ }
338
419
  switch (id) {
339
420
  case "mode": {
340
421
  // 选项值带 Experimental 标记,选择后还原为真实 mode 值。
@@ -450,7 +531,16 @@ export async function showCcstylePanel(
450
531
  {
451
532
  id: "feature",
452
533
  label: "Feature",
453
- items: [startupHeaderSetting, scrollStepSetting],
534
+ items: [
535
+ startupHeaderSetting,
536
+ scrollStepSetting,
537
+ sessionReferenceToggle.setting,
538
+ subagentAutocompleteToggle.setting,
539
+ contextCommandToggle.setting,
540
+ agentSummaryToggle.setting,
541
+ workingMessageToggle.setting,
542
+ aliasesToggle.setting,
543
+ ],
454
544
  },
455
545
  ];
456
546
 
@@ -94,7 +94,7 @@ type AssistantInternals = {
94
94
  };
95
95
 
96
96
  type PatchedPrototype = typeof AssistantMessageComponent.prototype & {
97
- updateContent: (message: AssistantMessage) => void;
97
+ updateContent: (message: AssistantMessage, isStreaming?: boolean) => void;
98
98
  };
99
99
 
100
100
  // 配置由 claude-code-style 管控(installCompactThinking 注入初始值,
@@ -334,9 +334,13 @@ function compactThinking(pi: ExtensionAPI) {
334
334
  );
335
335
  }
336
336
 
337
- prototype.updateContent = function patchedUpdateContent(message: AssistantMessage) {
337
+ prototype.updateContent = function patchedUpdateContent(
338
+ message: AssistantMessage,
339
+ isStreaming?: boolean,
340
+ ) {
338
341
  const component = this as AssistantMessageComponentLike;
339
342
  const self = this as unknown as AssistantInternals;
343
+ self.isStreaming = isStreaming ?? self.isStreaming;
340
344
  self.lastMessage = message;
341
345
  latestComponent = component;
342
346
  latestComponentTimestamp = message.timestamp;
@@ -344,7 +348,7 @@ function compactThinking(pi: ExtensionAPI) {
344
348
  // Visible mode is intentionally untouched: Shift+Tab restores Pi's exact
345
349
  // built-in Thinking Markdown renderer, including every OpenAI summary stage.
346
350
  if (!self.hideThinkingBlock) {
347
- originalUpdateContent.call(this, message);
351
+ originalUpdateContent.call(this, message, self.isStreaming);
348
352
  return;
349
353
  }
350
354
 
@@ -12,7 +12,7 @@ export type ContextPart = {
12
12
  color: "accent" | "success" | "warning" | "muted" | "dim";
13
13
  };
14
14
 
15
- type PreviewKey = "systemPrompt" | "tools" | "contextFiles" | "skills";
15
+ type PreviewKey = "systemPrompt" | "tools" | "toolResults" | "contextFiles" | "skills";
16
16
 
17
17
  type ContextPreview = {
18
18
  key: PreviewKey;
@@ -303,6 +303,48 @@ export function scaleParts(parts: ContextPart[], target: number): ContextPart[]
303
303
  return scaled;
304
304
  }
305
305
 
306
+ export function resolveUsedTokens(
307
+ usage: { tokens: number | null; percent: number | null } | undefined,
308
+ estimated: number,
309
+ contextWindow: number,
310
+ ): number {
311
+ const reported = usage?.tokens;
312
+ const fromPercent =
313
+ usage?.percent !== null && usage?.percent !== undefined && contextWindow > 0
314
+ ? Math.round((usage.percent / 100) * contextWindow)
315
+ : undefined;
316
+ let resolved = reported ?? fromPercent ?? estimated;
317
+ if (reported !== null && reported !== undefined && fromPercent !== undefined) {
318
+ const tolerance = Math.max(32, Math.round(contextWindow * 0.001));
319
+ if (Math.abs(reported - fromPercent) > tolerance) resolved = fromPercent;
320
+ }
321
+ if (estimated > 0 && resolved < estimated * 0.25) return estimated;
322
+ return resolved;
323
+ }
324
+
325
+ export function capParts(parts: ContextPart[], target: number, fixedPrefix = 0): ContextPart[] {
326
+ const fixed = parts.slice(0, fixedPrefix);
327
+ const variable = parts.slice(fixedPrefix);
328
+ const fixedTokens = fixed.reduce((sum, part) => sum + part.tokens, 0);
329
+ const variableTarget = Math.max(0, target - fixedTokens);
330
+ const estimated = variable.reduce((sum, part) => sum + part.tokens, 0);
331
+ if (estimated <= variableTarget || estimated === 0) return parts;
332
+ if (variableTarget === 0) return [...fixed, ...variable.map((part) => ({ ...part, tokens: 0 }))];
333
+ let previous = 0;
334
+ let cumulative = 0;
335
+ const capped = variable.map((part, index) => {
336
+ cumulative += part.tokens;
337
+ const next =
338
+ index === variable.length - 1
339
+ ? variableTarget
340
+ : Math.round((cumulative / estimated) * variableTarget);
341
+ const tokens = next - previous;
342
+ previous = next;
343
+ return { ...part, tokens };
344
+ });
345
+ return [...fixed, ...capped];
346
+ }
347
+
306
348
  export function formatTokens(tokens: number): string {
307
349
  if (tokens < 1_000) return String(tokens);
308
350
  if (tokens < 100_000) return `${(tokens / 1_000).toFixed(1)}k`;
@@ -326,13 +368,14 @@ type ContextBreakdown = {
326
368
  parts: ContextPart[];
327
369
  options: SystemPromptOptions;
328
370
  systemPrompt: string;
371
+ toolResults: string;
329
372
  };
330
373
 
331
374
  /**
332
375
  * Single pass over prompt options + session entries. Returns options/systemPrompt
333
376
  * so the /context UI does not re-fetch or re-stringify the same sources.
334
377
  */
335
- function collectContextBreakdown(ctx: ExtensionCommandContext): ContextBreakdown {
378
+ export function collectContextBreakdown(ctx: ExtensionCommandContext): ContextBreakdown {
336
379
  const options = (ctx.getSystemPromptOptions?.() ?? {}) as SystemPromptOptions;
337
380
  const systemPrompt = typeof ctx.getSystemPrompt === "function" ? ctx.getSystemPrompt() : "";
338
381
 
@@ -361,12 +404,16 @@ function collectContextBreakdown(ctx: ExtensionCommandContext): ContextBreakdown
361
404
  let assistant = 0;
362
405
  let toolResults = 0;
363
406
  let summaries = 0;
407
+ const toolResultPreview: string[] = [];
364
408
  for (const entry of ctx.sessionManager.buildContextEntries()) {
365
409
  if (entry.type === "message") {
366
410
  const tokens = estimateTokens(entry.message);
367
411
  if (entry.message.role === "user") user += tokens;
368
412
  else if (entry.message.role === "assistant") assistant += tokens;
369
413
  else toolResults += tokens;
414
+ if (entry.message.role === "toolResult") {
415
+ toolResultPreview.push(`## Tool result\n\n${JSON.stringify(entry.message, null, 2)}`);
416
+ }
370
417
  } else if (entry.type === "compaction" || entry.type === "branch_summary") {
371
418
  summaries += tokenEstimate(entry);
372
419
  }
@@ -388,6 +435,7 @@ function collectContextBreakdown(ctx: ExtensionCommandContext): ContextBreakdown
388
435
  parts: parts.filter((part) => part.tokens > 0),
389
436
  options,
390
437
  systemPrompt,
438
+ toolResults: toolResultPreview.join("\n\n") || "No tool results in the current context.",
391
439
  };
392
440
  }
393
441
 
@@ -398,10 +446,25 @@ export default function contextUsageExtension(pi: ExtensionAPI) {
398
446
  const usage = ctx.getContextUsage();
399
447
  const contextWindow = usage?.contextWindow ?? ctx.model?.contextWindow ?? 0;
400
448
  const breakdown = collectContextBreakdown(ctx);
401
- const used = usage?.tokens ?? breakdown.parts.reduce((sum, part) => sum + part.tokens, 0);
402
- const parts = scaleParts(breakdown.parts, used);
449
+ const estimated = breakdown.parts.reduce((sum, part) => sum + part.tokens, 0);
450
+ const fixedParts = breakdown.parts.filter(
451
+ (part) => part.label === "System prompt" || part.label === "Tools",
452
+ );
453
+ const variableParts = breakdown.parts.filter(
454
+ (part) => part.label !== "System prompt" && part.label !== "Tools",
455
+ );
456
+ const orderedParts = [...fixedParts, ...variableParts];
457
+ const fixedTokens = fixedParts.reduce((sum, part) => sum + part.tokens, 0);
458
+ const used = Math.max(resolveUsedTokens(usage, estimated, contextWindow), fixedTokens);
459
+ const parts = capParts(orderedParts, used, fixedParts.length);
460
+ const attributed = parts.reduce((sum, part) => sum + part.tokens, 0);
461
+ const other = Math.max(0, used - attributed);
403
462
  const free = Math.max(0, contextWindow - used);
404
- const allParts = [...parts, { label: "Free space", tokens: free, color: "dim" as const }];
463
+ const allParts = [
464
+ ...parts,
465
+ { label: "Other", tokens: other, color: "muted" as const },
466
+ { label: "Free space", tokens: free, color: "dim" as const },
467
+ ];
405
468
 
406
469
  if (ctx.mode !== "tui") {
407
470
  const lines = allParts.map((part) => `${part.label}: ${formatTokens(part.tokens)} tokens`);
@@ -456,6 +519,12 @@ export default function contextUsageExtension(pi: ExtensionAPI) {
456
519
  title: "Tools",
457
520
  content: toolContent.join("\n\n") || "No active tools.",
458
521
  },
522
+ {
523
+ key: "toolResults",
524
+ label: "Tool results",
525
+ title: "Tool Results",
526
+ content: breakdown.toolResults,
527
+ },
459
528
  {
460
529
  key: "contextFiles",
461
530
  label: "Context files",
@@ -1,4 +1,5 @@
1
1
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ import { config } from "./config/config.ts";
2
3
 
3
4
  // shell
4
5
  import piAliases from "./feature/shell/aliases.ts";
@@ -21,9 +22,9 @@ import markdownEnhance from "./renderer/markdown-enhance.ts";
21
22
 
22
23
  export default function (pi: ExtensionAPI): void {
23
24
  // shell chrome
24
- piAliases(pi);
25
+ if (config.enableAliases) piAliases(pi);
25
26
  piStartupHeader(pi);
26
- workingMessage(pi);
27
+ if (config.enableWorkingMessage) workingMessage(pi);
27
28
 
28
29
  // Renderer 必须先注册 lifecycle handler,shutdown 时才能先解开外层 compact
29
30
  // patch;bridge 让稍后安装的 thinking controller 仍可直接供 renderer query。
@@ -42,8 +43,8 @@ export default function (pi: ExtensionAPI): void {
42
43
  compactThinking = installCompactThinking(pi, getCompactThinkingConfig());
43
44
 
44
45
  // features
45
- context(pi);
46
- sessionReference(pi);
47
- agentAutocomplete(pi);
48
- agentSummary(pi);
46
+ if (config.enableContextCommand) context(pi);
47
+ if (config.enableSessionReference) sessionReference(pi);
48
+ if (config.enableSubagentAutocomplete) agentAutocomplete(pi);
49
+ if (config.enableAgentSummary) agentSummary(pi);
49
50
  }
@@ -769,13 +769,13 @@ export function installCompactMode(deps: CompactModeInstallDeps): CompactModeHoo
769
769
  dispose: () => {},
770
770
  };
771
771
 
772
- const passThroughAssistant = (component: any, message: any): any => {
772
+ const passThroughAssistant = (component: any, message: any, isStreaming?: boolean): any => {
773
773
  const self = component as any;
774
774
  if (self[ASSISTANT_REENTRY_KEY] === patch)
775
- return patch.assistantNative.call(component, message);
775
+ return patch.assistantNative.call(component, message, isStreaming);
776
776
  self[ASSISTANT_REENTRY_KEY] = patch;
777
777
  try {
778
- return patch.assistantOriginal.call(component, message);
778
+ return patch.assistantOriginal.call(component, message, isStreaming);
779
779
  } finally {
780
780
  delete self[ASSISTANT_REENTRY_KEY];
781
781
  }
@@ -845,12 +845,20 @@ export function installCompactMode(deps: CompactModeInstallDeps): CompactModeHoo
845
845
  if (render) renderRound(round);
846
846
  };
847
847
 
848
- const renderAssistantWithoutThinking = (component: any, message: any): any => {
848
+ const renderAssistantWithoutThinking = (
849
+ component: any,
850
+ message: any,
851
+ isStreaming?: boolean,
852
+ ): any => {
849
853
  const content = Array.isArray(message?.content) ? message.content : [];
850
- const result = passThroughAssistant(component, {
851
- ...message,
852
- content: content.filter((item: any) => item?.type !== "thinking"),
853
- });
854
+ const result = passThroughAssistant(
855
+ component,
856
+ {
857
+ ...message,
858
+ content: content.filter((item: any) => item?.type !== "thinking"),
859
+ },
860
+ isStreaming,
861
+ );
854
862
  component.lastMessage = message;
855
863
  return result;
856
864
  };
@@ -980,18 +988,19 @@ export function installCompactMode(deps: CompactModeInstallDeps): CompactModeHoo
980
988
  stopRoundTick();
981
989
  };
982
990
 
983
- patch.assistantInstalled = function (this: any, message: any) {
991
+ patch.assistantInstalled = function (this: any, message: any, isStreaming?: boolean) {
984
992
  const self = this as any;
993
+ if (isStreaming !== undefined) self.isStreaming = isStreaming;
985
994
  if (self[ASSISTANT_REENTRY_KEY] === patch) {
986
- return patch.assistantNative.call(this, message);
995
+ return patch.assistantNative.call(this, message, isStreaming);
987
996
  }
988
997
  self.lastMessage = message;
989
998
  trackedAssistantComponents.add(this);
990
999
  if (!patch.active || config.mode !== "compact") {
991
- return passThroughAssistant(this, message);
1000
+ return passThroughAssistant(this, message, isStreaming);
992
1001
  }
993
1002
  if (!self.contentContainer || typeof self.contentContainer.clear !== "function") {
994
- return passThroughAssistant(this, message);
1003
+ return passThroughAssistant(this, message, isStreaming);
995
1004
  }
996
1005
 
997
1006
  const content = Array.isArray(message?.content) ? message.content : [];
@@ -158,11 +158,10 @@ function singleToolCallSummary(
158
158
  const name = toolName.toLowerCase();
159
159
  const value = (fallback: string, ...keys: string[]) => {
160
160
  const found = keys.map((key) => args[key]).find((item) => typeof item === "string" && item);
161
- // 与多 tool 摘要对齐:从头截断,上限 96 字符(tool-grouping oneLine 默认值)。
162
- return `${title} ${oneLine(found || fallback, 96)}`;
161
+ return `${title} ${oneLine(found || fallback)}`;
163
162
  };
164
163
  if (AGENT_FAMILY_TOOL_NAMES.has(toolName) && args.agent_id) {
165
- return { main: `${title} ${oneLine(args.agent_id, 96)}`, detail: "" };
164
+ return { main: `${title} ${oneLine(args.agent_id)}`, detail: "" };
166
165
  }
167
166
  // Agents 走 ccstyle wrapper;Agent 保留专用渲染器。
168
167
  if (name === "agents") {
@@ -203,7 +202,7 @@ function singleToolCallSummary(
203
202
  args.limit !== undefined ? `limit=${args.limit}` : "",
204
203
  ].filter(Boolean);
205
204
  return {
206
- main: `${title}${args.path ? ` ${oneLine(args.path, 96)}` : ""}`,
205
+ main: `${title}${args.path ? ` ${oneLine(args.path)}` : ""}`,
207
206
  detail: details.length ? ` (${details.join(", ")})` : "",
208
207
  };
209
208
  }
@@ -223,7 +222,7 @@ function singleToolCallSummary(
223
222
  return {
224
223
  main:
225
224
  preferred !== undefined && preferred !== null && typeof preferred !== "object"
226
- ? `${title} ${oneLine(preferred, 96)}`
225
+ ? `${title} ${oneLine(preferred)}`
227
226
  : title,
228
227
  detail: "",
229
228
  };
@@ -55,9 +55,8 @@ const ADMONITION_STYLE: Record<string, { icon: string; label: string }> = {
55
55
  };
56
56
 
57
57
  /**
58
- * 把 > [!TYPE] 及其后续 > 行转成两列表格(图标标签列 + 内容列),视觉上成提示框。
59
- * 表格 cell 内不支持换行(<br> 显示为字面量),多行内容用空格合并。
60
- * 返回 null 表示该行不是提示框。
58
+ * 把 > [!TYPE] 及其后续 > 行转成带加粗标签的引用块,视觉上成提示框。
59
+ * 多行内容用空格合并为一行。返回 null 表示该行不是提示框。
61
60
  */
62
61
  function renderAdmonition(lines: string[], i: number): { output: string[]; next: number } | null {
63
62
  const m = lines[i].match(ADMONITION);
@@ -70,11 +69,9 @@ function renderAdmonition(lines: string[], i: number): { output: string[]; next:
70
69
  j++;
71
70
  }
72
71
  while (body.length > 0 && body[body.length - 1].trim() === "") body.pop();
73
- // 内容里的 | 转义,避免拆出额外表格列
74
- const content = body.join(" ").trim().replace(/\|/g, "\\|");
75
- // 表格后补空行,防止紧接的段落被解析为表格数据行
72
+ const content = body.join(" ").trim();
76
73
  return {
77
- output: [`| ${style.icon} ${style.label} | ${content} |`, "|---|---|", ""],
74
+ output: [`> **${style.icon} ${style.label}**${content ? ` ${content}` : ""}`, ""],
78
75
  next: j,
79
76
  };
80
77
  }
@@ -83,14 +80,20 @@ function renderAdmonition(lines: string[], i: number): { output: string[]; next:
83
80
  // 裸 URL 转可点击超链接
84
81
  // ============================================================================
85
82
 
86
- const URL_RE = /(?<!<)(?<!\]\()https?:\/\/[^\s<>'"|,。;:!?、」』】]+/g;
87
- const TRIM_URL_RE = /[.,;:!?】」』"']+$/;
83
+ const URL_RE = /(?<!<)(?<!\]\()https?:\/\/[^\s<>'"|,。;:!?、」』】()【】《》『』「」]+/g;
84
+ const TRIM_URL_RE = /[.,;:!?】」』"'》)}]+$/;
88
85
 
89
86
  /** 去掉 URL 尾部标点;括号按平衡保留(如 Wikipedia 链接含括号)。 */
90
87
  function trimUrl(url: string): string {
91
88
  let t = url.replace(TRIM_URL_RE, "");
92
- while (t.endsWith(")") && (t.match(/\(/g)?.length ?? 0) < (t.match(/\)/g)?.length ?? 0)) {
93
- t = t.slice(0, -1);
89
+ while (true) {
90
+ if (t.endsWith(")") && (t.match(/\(/g)?.length ?? 0) < (t.match(/\)/g)?.length ?? 0)) {
91
+ t = t.slice(0, -1);
92
+ } else if (t.endsWith("]") && (t.match(/\[/g)?.length ?? 0) < (t.match(/\]/g)?.length ?? 0)) {
93
+ t = t.slice(0, -1);
94
+ } else {
95
+ break;
96
+ }
94
97
  }
95
98
  return t;
96
99
  }
@@ -249,6 +252,41 @@ function deCircled(markdown: string): string {
249
252
  return output.join("\n");
250
253
  }
251
254
 
255
+ // ============================================================================
256
+ // 跨行链接规整
257
+ // ============================================================================
258
+
259
+ const MULTILINE_LINK_RE = /\[([^\]\n]*(?:\n[^\]\n]*)+)\](?=\()/g;
260
+
261
+ /** 防止 Markdown 跨行链接把行尾填充空格纳入 OSC 8 点击区。 */
262
+ function normalizeMultilineLinks(markdown: string): string {
263
+ const out: string[] = [];
264
+ let prose: string[] = [];
265
+ let fence: MarkdownFence | undefined;
266
+ const flush = () => {
267
+ if (prose.length === 0) return;
268
+ out.push(
269
+ prose.join("\n").replace(MULTILINE_LINK_RE, (_match, label: string) => {
270
+ const normalized = label.replace(/[ \t]*\n[ \t]*/g, " ").trim();
271
+ return `[${normalized}]`;
272
+ }),
273
+ );
274
+ prose = [];
275
+ };
276
+ for (const line of markdown.split("\n")) {
277
+ const scanned = scanMarkdownFence(line, fence);
278
+ fence = scanned.fence;
279
+ if (scanned.protected) {
280
+ flush();
281
+ out.push(line);
282
+ } else {
283
+ prose.push(line);
284
+ }
285
+ }
286
+ flush();
287
+ return out.join("\n");
288
+ }
289
+
252
290
  // ============================================================================
253
291
  // 注册
254
292
  // ============================================================================
@@ -258,8 +296,9 @@ export default function (pi: ExtensionAPI): void {
258
296
  // 所以三个转换合并为一次注册,内部按序链式执行。
259
297
  pi.registerMarkdownTransformer((markdown, context) => {
260
298
  const { messageType, isStreaming = false } = context ?? {};
261
- // 与官方推荐一致:thinking 块与流式中间态不转换
262
- if (messageType === "assistant-thinking" || isStreaming) return markdown;
299
+ if (messageType === "assistant-thinking") return markdown;
300
+ markdown = normalizeMultilineLinks(markdown);
301
+ if (isStreaming) return markdown;
263
302
  // 0. 圈数字转半角括号(Nerd Font 补丁字形缺陷规避)
264
303
  markdown = deCircled(markdown);
265
304
  // 1. Mermaid 方言渲染
@@ -330,7 +369,7 @@ function renderDiagrams(
330
369
  return out.join("\n");
331
370
  }
332
371
 
333
- /** GitHub 风格提示框 → 两列表格(跳过代码块)。 */
372
+ /** GitHub 风格提示框 → 加粗标签引用块(跳过代码块)。 */
334
373
  function renderAdmonitions(markdown: string): string {
335
374
  const lines = markdown.split("\n");
336
375
  const out: string[] = [];