@herbertgao/pi-extensions 2026.8.11 → 2026.8.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (476) hide show
  1. package/README.md +23 -10
  2. package/{node_modules/@herbertgao/pi-mermaid-open/LICENSE → THIRD_PARTY_NOTICES.md} +19 -1
  3. package/node_modules/@czottmann/pi-automode/CHANGELOG.md +15 -0
  4. package/node_modules/@czottmann/pi-automode/README.md +5 -3
  5. package/node_modules/@czottmann/pi-automode/docs/adr/ADR-001-permission-precedence-and-trust-boundaries.md +2 -0
  6. package/node_modules/@czottmann/pi-automode/docs/adr/ADR-002-global-config-in-extension-data-directory.md +60 -0
  7. package/node_modules/@czottmann/pi-automode/docs/adr/INDEX.md +1 -0
  8. package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +4 -4
  9. package/node_modules/@czottmann/pi-automode/docs/configuration.md +20 -4
  10. package/node_modules/@czottmann/pi-automode/docs/observability-logging.md +1 -1
  11. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/bash.ts +692 -0
  12. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +181 -3
  13. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +4 -1
  14. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +143 -36
  15. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +103 -148
  16. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +32 -6
  17. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +344 -22
  18. package/node_modules/@czottmann/pi-automode/extensions/auto-mode.ts +1 -0
  19. package/node_modules/@czottmann/pi-automode/package.json +4 -1
  20. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -1
  21. package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -1
  22. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +4 -0
  23. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +21 -1
  24. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +1 -1
  25. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +19 -19
  26. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +4 -2
  27. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +2 -1
  28. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +10 -2
  29. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  30. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +10 -0
  31. package/node_modules/@herbertgao/pi-subagents/README.md +21 -15
  32. package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
  33. package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +11 -8
  34. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +184 -106
  35. package/node_modules/@herbertgao/pi-subagents/src/cross-extension-rpc.ts +31 -11
  36. package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +9 -1
  37. package/node_modules/@herbertgao/pi-subagents/src/index.ts +156 -31
  38. package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +17 -0
  39. package/node_modules/@herbertgao/pi-subagents/src/model-resolver.ts +14 -0
  40. package/node_modules/@herbertgao/pi-subagents/src/schedule.ts +8 -0
  41. package/node_modules/@herbertgao/pi-subagents/src/settings.ts +32 -1
  42. package/node_modules/@herbertgao/pi-subagents/src/types.ts +17 -2
  43. package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +23 -2
  44. package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +259 -24
  45. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  46. package/node_modules/@luxusai/pi-hindsight/CHANGELOG.md +376 -0
  47. package/node_modules/@luxusai/pi-hindsight/README.md +92 -0
  48. package/node_modules/@luxusai/pi-hindsight/docs/adr/001-memory-lifecycle-and-scope.md +56 -0
  49. package/node_modules/@luxusai/pi-hindsight/docs/adr/002-explicit-routing-strategy-seam.md +169 -0
  50. package/node_modules/@luxusai/pi-hindsight/docs/adr/003-tui-memory-mode-vocabulary.md +107 -0
  51. package/node_modules/@luxusai/pi-hindsight/docs/adr/004-lifeos-dual-bank-design.md +89 -0
  52. package/node_modules/@luxusai/pi-hindsight/docs/adr/005-domain-banks-and-agent-first-surface.md +189 -0
  53. package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark.webp +0 -0
  54. package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark@2x.webp +0 -0
  55. package/node_modules/@luxusai/pi-hindsight/docs/coding-memory-evaluation.md +54 -0
  56. package/node_modules/@luxusai/pi-hindsight/docs/compatibility.md +75 -0
  57. package/node_modules/@luxusai/pi-hindsight/docs/hindsight-core-functions.md +300 -0
  58. package/node_modules/@luxusai/pi-hindsight/docs/mission-and-mental-model-quality.md +158 -0
  59. package/node_modules/@luxusai/pi-hindsight/docs/next-opt-out-design.md +164 -0
  60. package/node_modules/@luxusai/pi-hindsight/docs/risky-memory-modes.md +139 -0
  61. package/node_modules/@luxusai/pi-hindsight/docs/starter-mental-model-suggestions.md +74 -0
  62. package/node_modules/@luxusai/pi-hindsight/docs/surface-reference.md +261 -0
  63. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-operations.ts +151 -0
  64. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-selection.ts +18 -0
  65. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-settings-presenter.ts +46 -0
  66. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-templates.ts +383 -0
  67. package/node_modules/@luxusai/pi-hindsight/extensions/banks/banking.ts +240 -0
  68. package/node_modules/@luxusai/pi-hindsight/extensions/banks/knowledge-page-seed.ts +176 -0
  69. package/node_modules/@luxusai/pi-hindsight/extensions/banks/retain-strategies.ts +178 -0
  70. package/node_modules/@luxusai/pi-hindsight/extensions/client/client-retry.ts +41 -0
  71. package/node_modules/@luxusai/pi-hindsight/extensions/client/client.ts +386 -0
  72. package/node_modules/@luxusai/pi-hindsight/extensions/client/fetch-compat.ts +39 -0
  73. package/node_modules/@luxusai/pi-hindsight/extensions/client/timeout.ts +34 -0
  74. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-defaults.ts +140 -0
  75. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-model.ts +61 -0
  76. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-registry.ts +925 -0
  77. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-field-paths.ts +247 -0
  78. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-normalize.ts +547 -0
  79. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-writer.ts +480 -0
  80. package/node_modules/@luxusai/pi-hindsight/extensions/config/config.ts +182 -0
  81. package/node_modules/@luxusai/pi-hindsight/extensions/config/setup-gate.ts +86 -0
  82. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-execute.ts +1010 -0
  83. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-parse.ts +175 -0
  84. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-plan.ts +425 -0
  85. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-presentation.ts +210 -0
  86. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-sessions.ts +817 -0
  87. package/node_modules/@luxusai/pi-hindsight/extensions/index.ts +25 -0
  88. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/git-seed.ts +319 -0
  89. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-recall.ts +196 -0
  90. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-retain.ts +189 -0
  91. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-runtime.ts +65 -0
  92. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle.ts +260 -0
  93. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/mental-models.ts +244 -0
  94. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/observation-scopes.ts +59 -0
  95. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-cleanup.ts +82 -0
  96. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-visibility.ts +45 -0
  97. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall.ts +331 -0
  98. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-cursor.ts +354 -0
  99. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-job-builder.ts +66 -0
  100. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-receipts.ts +132 -0
  101. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain.ts +228 -0
  102. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-bank-template-operations.ts +74 -0
  103. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-config-operations.ts +16 -0
  104. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-control-operations.ts +648 -0
  105. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-diagnostics-operations.ts +105 -0
  106. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-identity.ts +68 -0
  107. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-service.ts +71 -0
  108. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-types.ts +13 -0
  109. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-recall-operations.ts +162 -0
  110. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-retain-operations.ts +131 -0
  111. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-scope.ts +104 -0
  112. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-session-operations.ts +37 -0
  113. package/node_modules/@luxusai/pi-hindsight/extensions/operations/operation-catalog.ts +893 -0
  114. package/node_modules/@luxusai/pi-hindsight/extensions/operations/reflect-presenter.ts +35 -0
  115. package/node_modules/@luxusai/pi-hindsight/extensions/operations/scope-migrate.ts +177 -0
  116. package/node_modules/@luxusai/pi-hindsight/extensions/operations/tools.ts +7 -0
  117. package/node_modules/@luxusai/pi-hindsight/extensions/queue/flush-presenter.ts +21 -0
  118. package/node_modules/@luxusai/pi-hindsight/extensions/queue/jsonl-queue-store.ts +112 -0
  119. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-delivery.ts +111 -0
  120. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-lock.ts +214 -0
  121. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-operations.ts +70 -0
  122. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue.ts +392 -0
  123. package/node_modules/@luxusai/pi-hindsight/extensions/tui/bank-template-presentation.ts +45 -0
  124. package/node_modules/@luxusai/pi-hindsight/extensions/tui/commands.ts +9 -0
  125. package/node_modules/@luxusai/pi-hindsight/extensions/tui/guided-setup.ts +860 -0
  126. package/node_modules/@luxusai/pi-hindsight/extensions/tui/prefill-input.ts +105 -0
  127. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-flow.ts +189 -0
  128. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-server-probe.ts +299 -0
  129. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-actions.ts +201 -0
  130. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-facts.ts +47 -0
  131. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-render.ts +239 -0
  132. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-types.ts +50 -0
  133. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui.ts +259 -0
  134. package/node_modules/@luxusai/pi-hindsight/extensions/tui/tool-presenters.ts +77 -0
  135. package/node_modules/@luxusai/pi-hindsight/extensions/types.ts +534 -0
  136. package/node_modules/@luxusai/pi-hindsight/extensions/utils/diagnostics.ts +319 -0
  137. package/node_modules/@luxusai/pi-hindsight/extensions/utils/messages.ts +325 -0
  138. package/node_modules/@luxusai/pi-hindsight/extensions/utils/sanitize.ts +42 -0
  139. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-memory-meta.ts +244 -0
  140. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-operations.ts +56 -0
  141. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session.ts +50 -0
  142. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-fields.ts +167 -0
  143. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-health.ts +207 -0
  144. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status.ts +120 -0
  145. package/node_modules/@luxusai/pi-hindsight/extensions/version.ts +8 -0
  146. package/node_modules/@luxusai/pi-hindsight/package.json +118 -0
  147. package/node_modules/@luxusai/pi-hindsight/skills/hindsight-memory-doctor/SKILL.md +75 -0
  148. package/node_modules/@narumitw/pi-btw/dist/index.ts +143 -46
  149. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
  150. package/node_modules/@narumitw/pi-btw/package.json +6 -6
  151. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +136 -22
  152. package/node_modules/{@herbertgao → @tifan}/pi-copy-response/README.md +2 -4
  153. package/node_modules/{@herbertgao → @tifan}/pi-copy-response/package.json +5 -15
  154. package/node_modules/{@herbertgao → @tifan}/pi-handoff/README.md +4 -6
  155. package/node_modules/@tifan/pi-handoff/package.json +43 -0
  156. package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/index.ts +1 -1
  157. package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/README.md +2 -4
  158. package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/package.json +5 -15
  159. package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/README.md +5 -7
  160. package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/package.json +5 -19
  161. package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/README.md +4 -6
  162. package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/package.json +6 -16
  163. package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/src/index.ts +1 -6
  164. package/node_modules/{@herbertgao → @tifan}/pi-recap/README.md +4 -6
  165. package/node_modules/@tifan/pi-recap/package.json +42 -0
  166. package/node_modules/{@herbertgao → @tifan}/pi-recap/src/models.ts +1 -6
  167. package/node_modules/{@herbertgao → @tifan}/pi-rename/README.md +13 -8
  168. package/node_modules/@tifan/pi-rename/package.json +47 -0
  169. package/node_modules/@tifan/pi-rename/src/herdr-label.ts +4 -0
  170. package/node_modules/{@herbertgao → @tifan}/pi-rename/src/index.ts +4 -16
  171. package/node_modules/{@herbertgao → @tifan}/pi-rename/src/models.ts +1 -6
  172. package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/README.md +2 -4
  173. package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/package.json +5 -15
  174. package/node_modules/pi-lens/CHANGELOG.md +96 -1
  175. package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -1
  176. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +14 -5
  177. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +48 -18
  178. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +1 -3
  179. package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +16 -4
  180. package/node_modules/pi-lens/dist/clients/bash-file-access.js +3 -1
  181. package/node_modules/pi-lens/dist/clients/biome-client.js +1 -3
  182. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +21 -8
  183. package/node_modules/pi-lens/dist/clients/bounded-cache.js +24 -8
  184. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +4 -3
  185. package/node_modules/pi-lens/dist/clients/cache-manager.js +6 -7
  186. package/node_modules/pi-lens/dist/clients/cache-observability.js +461 -66
  187. package/node_modules/pi-lens/dist/clients/call-graph.js +238 -63
  188. package/node_modules/pi-lens/dist/clients/codebase-model.js +13 -5
  189. package/node_modules/pi-lens/dist/clients/complexity-client.js +1 -3
  190. package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -8
  191. package/node_modules/pi-lens/dist/clients/dead-code-logger.js +1 -2
  192. package/node_modules/pi-lens/dist/clients/deadline-utils.js +3 -1
  193. package/node_modules/pi-lens/dist/clients/debug-heap.js +8 -1
  194. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +1 -1
  195. package/node_modules/pi-lens/dist/clients/dependency-checker.js +11 -7
  196. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +39 -2
  197. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +5 -1
  198. package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +2 -3
  199. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +13 -1
  200. package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +3 -1
  201. package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +2 -1
  202. package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +1 -1
  203. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +9 -4
  204. package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +3 -1
  205. package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +6 -2
  206. package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +31 -7
  207. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +5 -2
  208. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +10 -14
  209. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +5 -1
  210. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +1 -1
  211. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +3 -1
  212. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +25 -6
  213. package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +1 -1
  214. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +1 -1
  215. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +3 -1
  216. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +13 -8
  217. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +4 -1
  218. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +25 -10
  219. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +1 -1
  220. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +1 -1
  221. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +1 -1
  222. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +28 -4
  223. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +6 -8
  224. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +212 -11
  225. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +1 -1
  226. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +8 -4
  227. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +10 -6
  228. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +23 -14
  229. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -1
  230. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +7 -9
  231. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +5 -2
  232. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +7 -7
  233. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +6 -8
  234. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +13 -8
  235. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +13 -8
  236. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +17 -3
  237. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +7 -1
  238. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +24 -1
  239. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +35 -0
  240. package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +1 -3
  241. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +6 -8
  242. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +1 -1
  243. package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +2 -1
  244. package/node_modules/pi-lens/dist/clients/dispatch/types.js +6 -1
  245. package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +6 -2
  246. package/node_modules/pi-lens/dist/clients/extension-log.js +5 -3
  247. package/node_modules/pi-lens/dist/clients/feature-hints.js +8 -1
  248. package/node_modules/pi-lens/dist/clients/file-kinds.js +34 -129
  249. package/node_modules/pi-lens/dist/clients/file-utils.js +17 -1
  250. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +57 -2
  251. package/node_modules/pi-lens/dist/clients/formatters.js +144 -27
  252. package/node_modules/pi-lens/dist/clients/freshness.js +38 -0
  253. package/node_modules/pi-lens/dist/clients/git-guard.js +43 -13
  254. package/node_modules/pi-lens/dist/clients/go-client.js +1 -3
  255. package/node_modules/pi-lens/dist/clients/grammar-source.js +1 -1
  256. package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +30 -4
  257. package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +1 -3
  258. package/node_modules/pi-lens/dist/clients/install-diagnostics.js +4 -2
  259. package/node_modules/pi-lens/dist/clients/installer/index.js +86 -77
  260. package/node_modules/pi-lens/dist/clients/instance-reaper.js +5 -2
  261. package/node_modules/pi-lens/dist/clients/instance-registry.js +4 -2
  262. package/node_modules/pi-lens/dist/clients/jscpd-client.js +6 -1
  263. package/node_modules/pi-lens/dist/clients/knip-client.js +29 -15
  264. package/node_modules/pi-lens/dist/clients/language-profile.js +4 -1
  265. package/node_modules/pi-lens/dist/clients/latency-logger.js +13 -2
  266. package/node_modules/pi-lens/dist/clients/lens-config.js +1 -1
  267. package/node_modules/pi-lens/dist/clients/lens-map.js +8 -3
  268. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +1 -1
  269. package/node_modules/pi-lens/dist/clients/lsp/config.js +4 -6
  270. package/node_modules/pi-lens/dist/clients/lsp/edits.js +119 -32
  271. package/node_modules/pi-lens/dist/clients/lsp/index.js +94 -35
  272. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +2 -1
  273. package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +4 -1
  274. package/node_modules/pi-lens/dist/clients/lsp/launch.js +11 -3
  275. package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +152 -0
  276. package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -7
  277. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +10 -2
  278. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +9 -4
  279. package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -3
  280. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +10 -20
  281. package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +1 -1
  282. package/node_modules/pi-lens/dist/clients/memory-sampler.js +73 -7
  283. package/node_modules/pi-lens/dist/clients/metrics-client.js +1 -3
  284. package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +8 -3
  285. package/node_modules/pi-lens/dist/clients/module-report-lsp.js +7 -1
  286. package/node_modules/pi-lens/dist/clients/module-report.js +14 -17
  287. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +3 -5
  288. package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +220 -0
  289. package/node_modules/pi-lens/dist/clients/package-manager.js +6 -1
  290. package/node_modules/pi-lens/dist/clients/pipeline.js +57 -9
  291. package/node_modules/pi-lens/dist/clients/project-conventions.js +2 -8
  292. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +10 -7
  293. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +2 -1
  294. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +3 -1
  295. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +13 -9
  296. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +3 -1
  297. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -2
  298. package/node_modules/pi-lens/dist/clients/project-lens-config.js +12 -5
  299. package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +48 -0
  300. package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +15 -1
  301. package/node_modules/pi-lens/dist/clients/project-snapshot.js +472 -66
  302. package/node_modules/pi-lens/dist/clients/read-expansion.js +12 -2
  303. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +5 -4
  304. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +5 -2
  305. package/node_modules/pi-lens/dist/clients/read-guard.js +1 -1
  306. package/node_modules/pi-lens/dist/clients/resource-sampler.js +1 -1
  307. package/node_modules/pi-lens/dist/clients/reverse-deps.js +6 -5
  308. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +42 -17
  309. package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +8 -2
  310. package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +10 -1
  311. package/node_modules/pi-lens/dist/clients/review-graph/query.js +2 -1
  312. package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +4 -2
  313. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +2 -2
  314. package/node_modules/pi-lens/dist/clients/ruff-client.js +6 -5
  315. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +63 -31
  316. package/node_modules/pi-lens/dist/clients/runtime-context.js +12 -4
  317. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +83 -4
  318. package/node_modules/pi-lens/dist/clients/runtime-session.js +14 -0
  319. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +59 -3
  320. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +148 -34
  321. package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -6
  322. package/node_modules/pi-lens/dist/clients/rust-client.js +1 -3
  323. package/node_modules/pi-lens/dist/clients/safe-spawn.js +150 -11
  324. package/node_modules/pi-lens/dist/clients/security-scan-client.js +1 -3
  325. package/node_modules/pi-lens/dist/clients/session-summary.js +3 -1
  326. package/node_modules/pi-lens/dist/clients/sg-runner.js +1 -3
  327. package/node_modules/pi-lens/dist/clients/source-filter.js +10 -6
  328. package/node_modules/pi-lens/dist/clients/source-walker.js +1 -1
  329. package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +96 -0
  330. package/node_modules/pi-lens/dist/clients/startup-scan.js +4 -1
  331. package/node_modules/pi-lens/dist/clients/tool-definition.js +7 -0
  332. package/node_modules/pi-lens/dist/clients/tool-policy.js +26 -11
  333. package/node_modules/pi-lens/dist/clients/tool-render.js +2 -1
  334. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +10 -4
  335. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
  336. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +12 -5
  337. package/node_modules/pi-lens/dist/clients/warm-attach.js +12 -5
  338. package/node_modules/pi-lens/dist/clients/widget-state.js +27 -11
  339. package/node_modules/pi-lens/dist/clients/word-index.js +3 -1
  340. package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -2
  341. package/node_modules/pi-lens/dist/clients/zizmor-config.js +9 -1
  342. package/node_modules/pi-lens/dist/i18n.js +13 -5
  343. package/node_modules/pi-lens/dist/index.js +10797 -8627
  344. package/node_modules/pi-lens/dist/mcp/server.js +3 -1
  345. package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +68 -12
  346. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +21 -7
  347. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +164 -35
  348. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +24 -7
  349. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +3 -1
  350. package/node_modules/pi-lens/dist/tools/module-report.js +1 -1
  351. package/node_modules/pi-lens/dist/tools/project-report.js +1 -1
  352. package/node_modules/pi-lens/dist/tools/symbol-search.js +5 -2
  353. package/node_modules/pi-lens/docs/durable-store-audit-1202.md +1 -1
  354. package/node_modules/pi-lens/docs/servercapabilities.md +1 -1
  355. package/node_modules/pi-lens/package.json +160 -156
  356. package/node_modules/pi-lens/rules/typos/_typos.toml +2 -2
  357. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +31 -13
  358. package/node_modules/pi-lens/scripts/download-grammars.js +9 -3
  359. package/node_modules/pi-lens/scripts/rpc-load-check.mjs +30 -9
  360. package/node_modules/pi-mcp-adapter/CHANGELOG.md +47 -0
  361. package/node_modules/pi-mcp-adapter/README.md +42 -13
  362. package/node_modules/pi-mcp-adapter/commands.ts +4 -2
  363. package/node_modules/pi-mcp-adapter/config.ts +45 -5
  364. package/node_modules/pi-mcp-adapter/direct-tools.ts +103 -92
  365. package/node_modules/pi-mcp-adapter/dist/agent-dir.d.ts +10 -0
  366. package/node_modules/pi-mcp-adapter/dist/agent-dir.js +63 -0
  367. package/node_modules/pi-mcp-adapter/dist/agent-dir.js.map +1 -0
  368. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.d.ts +8 -0
  369. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js +356 -0
  370. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js.map +1 -0
  371. package/node_modules/pi-mcp-adapter/dist/config.d.ts +123 -0
  372. package/node_modules/pi-mcp-adapter/dist/config.js +1087 -0
  373. package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -0
  374. package/node_modules/pi-mcp-adapter/dist/metadata-cache.d.ts +19 -0
  375. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +319 -0
  376. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +1 -0
  377. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.d.ts +2 -0
  378. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js +156 -0
  379. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js.map +1 -0
  380. package/node_modules/pi-mcp-adapter/dist/resource-tools.d.ts +1 -0
  381. package/node_modules/pi-mcp-adapter/dist/resource-tools.js +15 -0
  382. package/node_modules/pi-mcp-adapter/dist/resource-tools.js.map +1 -0
  383. package/node_modules/pi-mcp-adapter/dist/types.d.ts +564 -0
  384. package/node_modules/pi-mcp-adapter/dist/types.js +287 -0
  385. package/node_modules/pi-mcp-adapter/dist/types.js.map +1 -0
  386. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.d.ts +6 -0
  387. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js +37 -0
  388. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js.map +1 -0
  389. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.d.ts +104 -0
  390. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js +59 -0
  391. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js.map +1 -0
  392. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.d.ts +4 -0
  393. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js +27 -0
  394. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js.map +1 -0
  395. package/node_modules/pi-mcp-adapter/dist/utils.d.ts +32 -0
  396. package/node_modules/pi-mcp-adapter/dist/utils.js +338 -0
  397. package/node_modules/pi-mcp-adapter/dist/utils.js.map +1 -0
  398. package/node_modules/pi-mcp-adapter/failure-backoff.ts +23 -0
  399. package/node_modules/pi-mcp-adapter/index.ts +204 -82
  400. package/node_modules/pi-mcp-adapter/init.ts +41 -30
  401. package/node_modules/pi-mcp-adapter/lifecycle.ts +16 -8
  402. package/node_modules/pi-mcp-adapter/mcp-code.ts +2 -0
  403. package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +66 -16
  404. package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +95 -7
  405. package/node_modules/pi-mcp-adapter/mcp-probe.ts +18 -4
  406. package/node_modules/pi-mcp-adapter/mcp-references.ts +368 -0
  407. package/node_modules/pi-mcp-adapter/mcp-status.ts +8 -19
  408. package/node_modules/pi-mcp-adapter/metadata-cache.ts +20 -12
  409. package/node_modules/pi-mcp-adapter/namespace-tools.ts +276 -0
  410. package/node_modules/pi-mcp-adapter/package.json +24 -6
  411. package/node_modules/pi-mcp-adapter/proxy-modes.ts +66 -10
  412. package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -0
  413. package/node_modules/pi-mcp-adapter/server-manager.ts +63 -12
  414. package/node_modules/pi-mcp-adapter/state.ts +1 -3
  415. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +16 -2
  416. package/node_modules/pi-mcp-adapter/types.ts +48 -1
  417. package/node_modules/pi-mcp-adapter/ui-server.ts +3 -19
  418. package/node_modules/pi-mcp-adapter/ui-session.ts +2 -1
  419. package/node_modules/pi-mcp-adapter/utils.ts +21 -19
  420. package/node_modules/pi-web-access/CHANGELOG.md +26 -0
  421. package/node_modules/pi-web-access/README.md +71 -14
  422. package/node_modules/pi-web-access/chrome-cookies.ts +115 -35
  423. package/node_modules/pi-web-access/credential-source.ts +6 -2
  424. package/node_modules/pi-web-access/curator-page.ts +5 -3
  425. package/node_modules/pi-web-access/curator-server.ts +2 -1
  426. package/node_modules/pi-web-access/extract.ts +89 -9
  427. package/node_modules/pi-web-access/fetch-params.ts +13 -0
  428. package/node_modules/pi-web-access/gemini-adc.ts +298 -0
  429. package/node_modules/pi-web-access/gemini-api.ts +59 -15
  430. package/node_modules/pi-web-access/gemini-search.ts +58 -18
  431. package/node_modules/pi-web-access/gemini-url-context.ts +3 -2
  432. package/node_modules/pi-web-access/gemini-web-config.ts +57 -7
  433. package/node_modules/pi-web-access/gemini-web.ts +9 -3
  434. package/node_modules/pi-web-access/github-api.ts +5 -4
  435. package/node_modules/pi-web-access/github-issue-pr.ts +700 -0
  436. package/node_modules/pi-web-access/index.ts +403 -297
  437. package/node_modules/pi-web-access/kimi-search.ts +234 -0
  438. package/node_modules/pi-web-access/openai-search.ts +118 -21
  439. package/node_modules/pi-web-access/package.json +3 -2
  440. package/node_modules/pi-web-access/ssrf-protection.ts +4 -1
  441. package/node_modules/pi-web-access/utils.ts +307 -1
  442. package/node_modules/pi-web-access/youtube-extract.ts +2 -2
  443. package/package.json +46 -37
  444. package/node_modules/@herbertgao/pi-copy-response/CHANGELOG.md +0 -49
  445. package/node_modules/@herbertgao/pi-copy-response/LICENSE +0 -22
  446. package/node_modules/@herbertgao/pi-handoff/CHANGELOG.md +0 -83
  447. package/node_modules/@herbertgao/pi-handoff/LICENSE +0 -22
  448. package/node_modules/@herbertgao/pi-handoff/package.json +0 -60
  449. package/node_modules/@herbertgao/pi-inline-skills/CHANGELOG.md +0 -57
  450. package/node_modules/@herbertgao/pi-inline-skills/LICENSE +0 -22
  451. package/node_modules/@herbertgao/pi-mermaid-open/CHANGELOG.md +0 -39
  452. package/node_modules/@herbertgao/pi-preferred-thinking/CHANGELOG.md +0 -63
  453. package/node_modules/@herbertgao/pi-preferred-thinking/LICENSE +0 -22
  454. package/node_modules/@herbertgao/pi-recap/CHANGELOG.md +0 -101
  455. package/node_modules/@herbertgao/pi-recap/LICENSE +0 -22
  456. package/node_modules/@herbertgao/pi-recap/package.json +0 -55
  457. package/node_modules/@herbertgao/pi-rename/CHANGELOG.md +0 -49
  458. package/node_modules/@herbertgao/pi-rename/LICENSE +0 -22
  459. package/node_modules/@herbertgao/pi-rename/package.json +0 -63
  460. package/node_modules/@herbertgao/pi-titlebar-spinner/CHANGELOG.md +0 -25
  461. package/node_modules/@herbertgao/pi-titlebar-spinner/LICENSE +0 -22
  462. /package/node_modules/{@herbertgao → @tifan}/pi-copy-response/src/index.ts +0 -0
  463. /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/complete-text.ts +0 -0
  464. /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/session-query.ts +0 -0
  465. /package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/src/index.ts +0 -0
  466. /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/herdr-plugin.toml +0 -0
  467. /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/viewer.mjs +0 -0
  468. /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/src/index.ts +0 -0
  469. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/index.ts +0 -0
  470. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/model-picker.ts +0 -0
  471. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/sanitize.ts +0 -0
  472. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/tui.ts +0 -0
  473. /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/model-picker.ts +0 -0
  474. /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/naming.ts +0 -0
  475. /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/sanitize.ts +0 -0
  476. /package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/src/index.ts +0 -0
@@ -1,7 +1,14 @@
1
+ import {
2
+ analyzeBash,
3
+ type BashAnalysis,
4
+ type BashCommandAnalysis,
5
+ type BashRedirectAnalysis,
6
+ } from "./bash.ts";
1
7
  import type { ToolPattern } from "./types.ts";
2
8
  import {
3
9
  expandHomePattern,
4
10
  normalizePathForMatch,
11
+ resolveInputPath,
5
12
  resolvePathForPolicy,
6
13
  resolveToolInputPath,
7
14
  } from "./paths.ts";
@@ -9,6 +16,8 @@ import {
9
16
  export const MAX_WILDCARD_PATTERN_LENGTH = 4096;
10
17
  export const MAX_WILDCARD_INPUT_LENGTH = 1024 * 1024;
11
18
 
19
+ const bashPatternAnalyses = new WeakMap<ToolPattern, BashAnalysis>();
20
+
12
21
  /** Preserve the previous non-Unicode RegExp `/i` case-equivalence rules. */
13
22
  function canonicalizeCase(value: string): string {
14
23
  let canonical = "";
@@ -55,11 +64,14 @@ export function parseToolPattern(value: unknown): ToolPattern | undefined {
55
64
 
56
65
  const match = raw.match(/^@?([A-Za-z0-9_-]+)(?:\((.*)\))?$/s);
57
66
  if (!match) return { raw };
58
- return {
59
- raw,
60
- toolName: normalizeToolName(match[1] ?? ""),
61
- argumentPattern: match[2],
62
- };
67
+ const toolName = normalizeToolName(match[1] ?? "");
68
+ const argumentPattern = match[2];
69
+ const bashPatternAnalysis = toolName === "bash" && argumentPattern
70
+ ? analyzeBash(argumentPattern)
71
+ : undefined;
72
+ const pattern: ToolPattern = { raw, toolName, argumentPattern };
73
+ if (bashPatternAnalysis) bashPatternAnalyses.set(pattern, bashPatternAnalysis);
74
+ return pattern;
63
75
  }
64
76
 
65
77
  function literalPrefixTable(value: string): number[] {
@@ -166,36 +178,110 @@ export function matchesWildcardPattern(
166
178
  return true;
167
179
  }
168
180
 
169
- function getPrimaryArgument(
181
+ export function normalizePermissionPathForMatch(
182
+ path: string,
183
+ platform: NodeJS.Platform = process.platform,
184
+ ): string {
185
+ return platform === "win32" ? path.replace(/\\/g, "/") : path;
186
+ }
187
+
188
+ function pathArgumentsForMatch(
189
+ toolName: string,
190
+ cwd: string,
191
+ value: string,
192
+ overflowPolicy: WildcardOverflowPolicy,
193
+ ): string[] {
194
+ const resolved = resolveToolInputPath(toolName, cwd, value) ?? value;
195
+ const canonical = resolvePathForPolicy(resolved);
196
+ const candidates = canonical
197
+ ? [canonical, normalizePathForMatch(canonical, cwd)]
198
+ : [];
199
+ if (overflowPolicy === "match") {
200
+ candidates.push(resolved, normalizePathForMatch(resolved, cwd));
201
+ }
202
+ return [...new Set(
203
+ candidates.map((candidate) => normalizePermissionPathForMatch(candidate)),
204
+ )];
205
+ }
206
+
207
+ function getPrimaryArguments(
170
208
  toolName: string,
171
209
  input: Record<string, unknown>,
172
210
  cwd: string,
173
- ): string {
211
+ overflowPolicy: WildcardOverflowPolicy,
212
+ ): string[] {
174
213
  if (toolName === "bash" && typeof input.command === "string") {
175
- return input.command;
214
+ return [input.command];
176
215
  }
177
216
  if (
178
217
  (toolName === "read" || toolName === "write" || toolName === "edit") &&
179
218
  typeof input.path === "string"
180
219
  ) {
181
- return normalizePathForMatch(
182
- resolveToolInputPath(toolName, cwd, input.path) ?? input.path,
183
- cwd,
184
- );
220
+ return pathArgumentsForMatch(toolName, cwd, input.path, overflowPolicy);
185
221
  }
186
222
  if (toolName === "grep" && typeof input.pattern === "string") {
187
- return input.pattern;
223
+ return [input.pattern];
188
224
  }
189
225
  if (
190
226
  (toolName === "find" || toolName === "ls") &&
191
227
  typeof input.path === "string"
192
228
  ) {
193
- return normalizePathForMatch(
194
- resolveToolInputPath(toolName, cwd, input.path) ?? input.path,
195
- cwd,
196
- );
229
+ return pathArgumentsForMatch(toolName, cwd, input.path, overflowPolicy);
197
230
  }
198
- return JSON.stringify(input);
231
+ return [JSON.stringify(input)];
232
+ }
233
+
234
+ function isPermissionPathTool(toolName: string): boolean {
235
+ return toolName === "read" ||
236
+ toolName === "write" ||
237
+ toolName === "edit" ||
238
+ toolName === "find" ||
239
+ toolName === "ls";
240
+ }
241
+
242
+ export function appendPermissionPathPatternSuffix(
243
+ scope: string,
244
+ suffix: string,
245
+ ): string {
246
+ const normalizedScope = withoutTrailingSlash(
247
+ normalizePermissionPathForMatch(scope),
248
+ );
249
+ return normalizedScope.endsWith("/")
250
+ ? `${normalizedScope}${suffix}`
251
+ : `${normalizedScope}/${suffix}`;
252
+ }
253
+
254
+ function permissionPathPatternVariants(
255
+ pattern: string,
256
+ cwd: string,
257
+ ): string[] {
258
+ const expanded = normalizePermissionPathForMatch(expandHomePattern(pattern));
259
+ const wildcardIndex = expanded.indexOf("*");
260
+ if (wildcardIndex === -1) {
261
+ const resolved = resolveInputPath(cwd, expanded);
262
+ const canonical = resolved ? resolvePathForPolicy(resolved) : undefined;
263
+ return [...new Set(
264
+ [expanded, resolved, canonical]
265
+ .filter((value): value is string => !!value)
266
+ .map((value) => normalizePermissionPathForMatch(value)),
267
+ )];
268
+ }
269
+
270
+ const fixedPrefix = expanded.slice(0, wildcardIndex);
271
+ const lastSlash = fixedPrefix.lastIndexOf("/");
272
+ if (lastSlash < 0) return [expanded];
273
+ const fixedScope = fixedPrefix.slice(0, lastSlash) || "/";
274
+ const resolvedScope = resolveInputPath(cwd, fixedScope);
275
+ if (!resolvedScope) return [expanded];
276
+ const canonicalScope = resolvePathForPolicy(resolvedScope);
277
+ const suffix = expanded.slice(lastSlash).replace(/^\/+/, "");
278
+ return [...new Set([
279
+ expanded,
280
+ appendPermissionPathPatternSuffix(resolvedScope, suffix),
281
+ ...(canonicalScope
282
+ ? [appendPermissionPathPatternSuffix(canonicalScope, suffix)]
283
+ : []),
284
+ ])];
199
285
  }
200
286
 
201
287
  /**
@@ -285,6 +371,37 @@ export function recursiveSearchMayReachDeniedPath(
285
371
  });
286
372
  }
287
373
 
374
+ function normalizedBashArgumentPattern(pattern: ToolPattern): string {
375
+ const patternAnalysis = bashPatternAnalyses.get(pattern);
376
+ if (
377
+ patternAnalysis &&
378
+ patternAnalysis.errors.length === 0 &&
379
+ patternAnalysis.redirects.length === 0 &&
380
+ isStructurallyPlainSingleCommand(patternAnalysis)
381
+ ) {
382
+ return patternAnalysis.commands[0]?.text ?? pattern.argumentPattern ?? "";
383
+ }
384
+ return pattern.argumentPattern ?? "";
385
+ }
386
+
387
+ function matchesBashArgumentPattern(
388
+ argumentPattern: string,
389
+ candidate: string,
390
+ overflowPolicy: WildcardOverflowPolicy,
391
+ ): boolean {
392
+ if (matchesWildcardPattern(argumentPattern, candidate, overflowPolicy)) {
393
+ return true;
394
+ }
395
+ if (overflowPolicy !== "match" || !argumentPattern.endsWith(" *")) {
396
+ return false;
397
+ }
398
+ return matchesWildcardPattern(
399
+ argumentPattern.slice(0, -2),
400
+ candidate,
401
+ overflowPolicy,
402
+ );
403
+ }
404
+
288
405
  /** Match a scoped permission rule against a concrete tool call. */
289
406
  export function matchesToolPattern(
290
407
  pattern: ToolPattern,
@@ -292,10 +409,215 @@ export function matchesToolPattern(
292
409
  input: Record<string, unknown>,
293
410
  cwd: string,
294
411
  overflowPolicy: WildcardOverflowPolicy = "match",
412
+ bashAnalysis?: BashAnalysis,
295
413
  ): boolean {
296
- if (!pattern.toolName) return false;
414
+ if (!pattern.toolName) return overflowPolicy === "match";
297
415
  if (pattern.toolName !== normalizeToolName(toolName)) return false;
298
- if (!pattern.argumentPattern) return true;
299
- const primary = getPrimaryArgument(toolName, input, cwd);
300
- return matchesWildcardPattern(pattern.argumentPattern, primary, overflowPolicy);
416
+ if (pattern.argumentPattern === undefined) return true;
417
+ if (pattern.argumentPattern.trim() === "") {
418
+ return overflowPolicy === "match";
419
+ }
420
+ if (
421
+ toolName === "bash" &&
422
+ (bashPatternAnalyses.get(pattern)?.errors.length ?? 0) > 0
423
+ ) {
424
+ return overflowPolicy === "match";
425
+ }
426
+ if (toolName === "bash" && bashAnalysis) {
427
+ if (bashAnalysis.errors.length > 0) return overflowPolicy === "match";
428
+ const candidates = overflowPolicy === "match"
429
+ ? [bashAnalysis.source, ...bashAnalysis.commands.map((command) => command.text)]
430
+ : [bashAnalysis.source];
431
+ const argumentPattern = normalizedBashArgumentPattern(pattern);
432
+ return candidates.some((candidate) =>
433
+ matchesBashArgumentPattern(argumentPattern, candidate, overflowPolicy)
434
+ );
435
+ }
436
+ const argumentPatterns = isPermissionPathTool(toolName)
437
+ ? permissionPathPatternVariants(pattern.argumentPattern, cwd)
438
+ : [pattern.argumentPattern];
439
+ const primaryArguments = getPrimaryArguments(
440
+ toolName,
441
+ input,
442
+ cwd,
443
+ overflowPolicy,
444
+ );
445
+ return argumentPatterns.some((argumentPattern) =>
446
+ primaryArguments.some((primary) =>
447
+ matchesWildcardPattern(argumentPattern, primary, overflowPolicy)
448
+ )
449
+ );
450
+ }
451
+
452
+ /** Return the normalized Bash command that matched a scoped permission rule. */
453
+ export function matchingBashCommandText(
454
+ pattern: ToolPattern,
455
+ bashAnalysis: BashAnalysis | undefined,
456
+ overflowPolicy: WildcardOverflowPolicy = "match",
457
+ ): string | undefined {
458
+ if (!bashAnalysis || pattern.toolName !== "bash") return undefined;
459
+ if (bashAnalysis.errors.length > 0) return undefined;
460
+ if (!pattern.argumentPattern) return undefined;
461
+ const argumentPattern = normalizedBashArgumentPattern(pattern);
462
+ const command = bashAnalysis.commands.find((candidate) =>
463
+ matchesBashArgumentPattern(argumentPattern, candidate.text, overflowPolicy)
464
+ );
465
+ if (command) return command.text;
466
+ return matchesBashArgumentPattern(argumentPattern, bashAnalysis.source, overflowPolicy)
467
+ ? bashAnalysis.source
468
+ : undefined;
469
+ }
470
+
471
+ function redirectListsMatch(
472
+ patternRedirects: BashRedirectAnalysis[],
473
+ inputRedirects: BashRedirectAnalysis[],
474
+ ): boolean {
475
+ if (patternRedirects.length !== inputRedirects.length) return false;
476
+ return patternRedirects.every((pattern, index) => {
477
+ const input = inputRedirects[index];
478
+ if (!input || pattern.heredoc || input.heredoc || input.targetDynamic) {
479
+ return false;
480
+ }
481
+ if (
482
+ pattern.operator !== input.operator ||
483
+ pattern.fileDescriptor !== input.fileDescriptor ||
484
+ pattern.variableName !== input.variableName
485
+ ) {
486
+ return false;
487
+ }
488
+ if (pattern.target === undefined) return input.target === undefined;
489
+ if (input.target === undefined) return false;
490
+ return matchesWildcardPattern(pattern.target, input.target, "no-match");
491
+ });
492
+ }
493
+
494
+ function commandMatchesAllowPattern(
495
+ patternCommand: BashCommandAnalysis,
496
+ inputCommand: BashCommandAnalysis,
497
+ ): boolean {
498
+ return matchesWildcardPattern(
499
+ patternCommand.text,
500
+ inputCommand.text,
501
+ "no-match",
502
+ ) && redirectListsMatch(patternCommand.redirects, inputCommand.redirects);
503
+ }
504
+
505
+ function structuresMatch(pattern: BashAnalysis, input: BashAnalysis): boolean {
506
+ return pattern.structure.length === input.structure.length &&
507
+ pattern.structure.every((token, index) => token === input.structure[index]);
508
+ }
509
+
510
+ function allRedirectsAreCommandRedirects(analysis: BashAnalysis): boolean {
511
+ return analysis.redirects.length === analysis.commands.reduce(
512
+ (count, command) => count + command.redirects.length,
513
+ 0,
514
+ );
515
+ }
516
+
517
+ function isStructurallyPlainSingleCommand(analysis: BashAnalysis): boolean {
518
+ if (analysis.commands.length !== 1) return false;
519
+ if (analysis.structure.length !== 3 + analysis.redirects.length) return false;
520
+ if (analysis.structure[0] !== "script:1") return false;
521
+ if (analysis.structure[1] !== "node:Statement:foreground:0") return false;
522
+ if (!/^node:Command:\d+:\d+$/.test(analysis.structure[2] ?? "")) {
523
+ return false;
524
+ }
525
+ return analysis.structure.slice(3).every((token) =>
526
+ token.startsWith("redirect:")
527
+ );
528
+ }
529
+
530
+ function supportsPerCommandAllowPatterns(analysis: BashAnalysis): boolean {
531
+ return analysis.structure.every((token) =>
532
+ token.startsWith("script:") ||
533
+ token.startsWith("node:Statement:foreground:") ||
534
+ token.startsWith("node:Command:") ||
535
+ token.startsWith("node:AndOr:") ||
536
+ token.startsWith("node:Pipeline:plain:plain:") ||
537
+ token.startsWith("redirect:")
538
+ );
539
+ }
540
+
541
+ /** Whether permission allow rules cover the complete tool call. */
542
+ export function matchesAllowedToolPatterns(
543
+ patterns: ToolPattern[],
544
+ toolName: string,
545
+ input: Record<string, unknown>,
546
+ cwd: string,
547
+ bashAnalysis?: BashAnalysis,
548
+ ): boolean {
549
+ if (toolName !== "bash" || !bashAnalysis) {
550
+ return patterns.some((pattern) =>
551
+ matchesToolPattern(pattern, toolName, input, cwd, "no-match")
552
+ );
553
+ }
554
+ if (
555
+ bashAnalysis.errors.length > 0 ||
556
+ bashAnalysis.commands.length === 0 ||
557
+ !bashAnalysis.allowStructureSafe
558
+ ) {
559
+ return false;
560
+ }
561
+ if (
562
+ bashAnalysis.commands.some((command) =>
563
+ command.dynamicName || command.dynamicShellScript
564
+ )
565
+ ) {
566
+ return false;
567
+ }
568
+
569
+ for (const pattern of patterns) {
570
+ if (pattern.toolName !== "bash") continue;
571
+ const patternAnalysis = bashPatternAnalyses.get(pattern);
572
+ if (
573
+ !patternAnalysis ||
574
+ patternAnalysis.errors.length > 0 ||
575
+ !patternAnalysis.allowStructureSafe ||
576
+ isStructurallyPlainSingleCommand(patternAnalysis) ||
577
+ patternAnalysis.commands.length !== bashAnalysis.commands.length ||
578
+ !structuresMatch(patternAnalysis, bashAnalysis) ||
579
+ !redirectListsMatch(patternAnalysis.redirects, bashAnalysis.redirects)
580
+ ) {
581
+ continue;
582
+ }
583
+ if (
584
+ patternAnalysis.commands.every((patternCommand, index) => {
585
+ const inputCommand = bashAnalysis.commands[index];
586
+ return !!inputCommand &&
587
+ commandMatchesAllowPattern(patternCommand, inputCommand);
588
+ })
589
+ ) {
590
+ return true;
591
+ }
592
+ }
593
+
594
+ const hasBareBashPattern = patterns.some((pattern) =>
595
+ pattern.toolName === "bash" && pattern.argumentPattern === undefined
596
+ );
597
+ if (
598
+ !hasBareBashPattern &&
599
+ !supportsPerCommandAllowPatterns(bashAnalysis)
600
+ ) {
601
+ return false;
602
+ }
603
+ if (!allRedirectsAreCommandRedirects(bashAnalysis)) return false;
604
+ return bashAnalysis.commands.every((command) =>
605
+ patterns.some((pattern) => {
606
+ if (pattern.toolName !== "bash") return false;
607
+ if (pattern.argumentPattern === undefined) {
608
+ return command.redirects.length === 0;
609
+ }
610
+ const patternAnalysis = bashPatternAnalyses.get(pattern);
611
+ if (
612
+ !patternAnalysis ||
613
+ patternAnalysis.errors.length > 0 ||
614
+ !isStructurallyPlainSingleCommand(patternAnalysis)
615
+ ) {
616
+ return false;
617
+ }
618
+ const patternCommand = patternAnalysis.commands[0];
619
+ return !!patternCommand &&
620
+ commandMatchesAllowPattern(patternCommand, command);
621
+ })
622
+ );
301
623
  }
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  export * from "./auto-mode/classifier.ts";
10
+ export * from "./auto-mode/bash.ts";
10
11
  export * from "./auto-mode/config.ts";
11
12
  export * from "./auto-mode/constants.ts";
12
13
  export * from "./auto-mode/extension.ts";
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@czottmann/pi-automode",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "Claude Code-style auto mode guardrail for pi.",
5
5
  "repository": {
6
6
  "url": "https://github.com/czottmann/pi-automode"
@@ -54,5 +54,8 @@
54
54
  "tsx": "^4.22.4",
55
55
  "typebox": "^1.3.10",
56
56
  "typescript": "^5.8.0"
57
+ },
58
+ "dependencies": {
59
+ "unbash": "4.0.10"
57
60
  }
58
61
  }
@@ -61,6 +61,7 @@ Run `/reload` after installation.
61
61
  "useSummaryTitlesAsThinkingTitle": true, // use the latest provider summary as the active thinking title
62
62
  "previewLines": 3, // thinking preview lines; 0 hides the preview body
63
63
  "animationIntervalMs": 90, // thinking title animation interval in ms
64
+ "dimThinkingText": false, // dim thinking body text
64
65
  "showStartupHeader": true, // custom startup header (logo + tips) toggle
65
66
  "scrollStepLines": 3, // fullscreen mouse wheel scroll lines
66
67
  "enableSessionReference": true, // @ session references
@@ -101,5 +102,5 @@ bun run typecheck
101
102
 
102
103
  ## Credits
103
104
 
104
- - Derived from [`minuque/pi-cc-extensions` v0.8.66](https://github.com/minuque/pi-cc-extensions/releases/tag/v0.8.66) (`e971a39`) under the MIT license.
105
+ - Derived from [`minuque/pi-cc-extensions` v0.8.67](https://github.com/minuque/pi-cc-extensions/releases/tag/v0.8.67) (`bc58504`) under the MIT license.
105
106
  - Rich diffs are adapted from [`MasuRii/pi-tool-display`](https://github.com/MasuRii/pi-tool-display) (MIT). See [`extensions/renderer/tool/diff/ATTRIBUTION.md`](./extensions/renderer/tool/diff/ATTRIBUTION.md).
@@ -61,6 +61,7 @@ pi install npm:@herbertgao/pi-cc-extensions
61
61
  "useSummaryTitlesAsThinkingTitle": true, // 用最新 provider 摘要作为思考标题
62
62
  "previewLines": 3, // thinking 预览行数,0 隐藏预览正文
63
63
  "animationIntervalMs": 90, // thinking 标题动画间隔(毫秒)
64
+ "dimThinkingText": false, // thinking 正文使用 dim 色
64
65
  "showStartupHeader": true, // 自定义启动头(logo + tips)开关
65
66
  "scrollStepLines": 3, // fullscreen 滚轮滚动步进行数
66
67
  "enableSessionReference": true, // @ session 引用
@@ -101,5 +102,5 @@ bun run typecheck
101
102
 
102
103
  ## 致谢
103
104
 
104
- - 基于 MIT 许可的 [`minuque/pi-cc-extensions` v0.8.66](https://github.com/minuque/pi-cc-extensions/releases/tag/v0.8.66)(`e971a39`)衍生维护。
105
+ - 基于 MIT 许可的 [`minuque/pi-cc-extensions` v0.8.67](https://github.com/minuque/pi-cc-extensions/releases/tag/v0.8.67)(`bc58504`)衍生维护。
105
106
  - Rich diff 改编自 [`MasuRii/pi-tool-display`](https://github.com/MasuRii/pi-tool-display)(MIT);详见 [`extensions/renderer/tool/diff/ATTRIBUTION.md`](./extensions/renderer/tool/diff/ATTRIBUTION.md)。
@@ -24,6 +24,7 @@ export type Config = {
24
24
  useSummaryTitlesAsThinkingTitle: boolean;
25
25
  previewLines: number;
26
26
  animationIntervalMs: number;
27
+ dimThinkingText: boolean;
27
28
  showStartupHeader: boolean;
28
29
  scrollStepLines: number;
29
30
  enableSessionReference: boolean;
@@ -75,6 +76,7 @@ export const DEFAULT_CONFIG: Config = {
75
76
  useSummaryTitlesAsThinkingTitle: true,
76
77
  previewLines: 3,
77
78
  animationIntervalMs: 90,
79
+ dimThinkingText: false,
78
80
  showStartupHeader: true,
79
81
  scrollStepLines: 3,
80
82
  enableSessionReference: true,
@@ -168,6 +170,7 @@ export function normalizeConfig(input: unknown): Config {
168
170
  source.animationIntervalMs,
169
171
  DEFAULT_CONFIG.animationIntervalMs,
170
172
  ),
173
+ dimThinkingText: source.dimThinkingText === true,
171
174
  showStartupHeader: source.showStartupHeader !== false,
172
175
  scrollStepLines: pickPositiveInt(source.scrollStepLines, DEFAULT_CONFIG.scrollStepLines, 1, 50),
173
176
  enableSessionReference: source.enableSessionReference !== false,
@@ -217,6 +220,7 @@ export function formatConfigStatus(source: Config = config): string {
217
220
  `thinkingTitle=${source.useSummaryTitlesAsThinkingTitle ? "summary" : "default"}`,
218
221
  `thinkingPreview=${source.previewLines}`,
219
222
  `thinkingAnimation=${source.animationIntervalMs}ms`,
223
+ `thinkingDim=${source.dimThinkingText ? "on" : "off"}`,
220
224
  `startupHeader=${source.showStartupHeader ? "on" : "off"}`,
221
225
  `scrollStep=${source.scrollStepLines}`,
222
226
  `sessionRef=${source.enableSessionReference ? "on" : "off"}`,
@@ -349,6 +349,15 @@ export async function showCcstylePanel(
349
349
  submenu: (_current: string, closeSubmenu: (selected?: string) => void) =>
350
350
  buildNumberInputSubmenu(theme, thinkingAnimationSetting, closeSubmenu),
351
351
  };
352
+ const thinkingDimSetting = {
353
+ id: "dimThinkingText",
354
+ label: "Dim thinking text",
355
+ description: config.dimThinkingText
356
+ ? "Thinking text uses the theme's dim color."
357
+ : "Keep the default thinking text color.",
358
+ currentValue: config.dimThinkingText ? "on" : "off",
359
+ values: ["on", "off"],
360
+ };
352
361
  const startupHeaderSetting = {
353
362
  id: "showStartupHeader",
354
363
  label: "Startup header",
@@ -505,6 +514,12 @@ export async function showCcstylePanel(
505
514
  );
506
515
  thinkingAnimationSetting.currentValue = String(config.animationIntervalMs);
507
516
  break;
517
+ case "dimThinkingText":
518
+ config.dimThinkingText = value === "on";
519
+ thinkingDimSetting.description = config.dimThinkingText
520
+ ? "Thinking text uses the theme's dim color."
521
+ : "Keep the default thinking text color.";
522
+ break;
508
523
  case "showStartupHeader":
509
524
  config.showStartupHeader = value === "on";
510
525
  startupHeaderSetting.description = config.showStartupHeader
@@ -548,7 +563,12 @@ export async function showCcstylePanel(
548
563
  {
549
564
  id: "thinking",
550
565
  label: "Thinking",
551
- items: [thinkingTitleSetting, thinkingPreviewSetting, thinkingAnimationSetting],
566
+ items: [
567
+ thinkingTitleSetting,
568
+ thinkingPreviewSetting,
569
+ thinkingAnimationSetting,
570
+ thinkingDimSetting,
571
+ ],
552
572
  },
553
573
  {
554
574
  id: "ui",
@@ -26,7 +26,7 @@ export type AgentSummaryData = {
26
26
 
27
27
  export function classifyTool(toolName: string): AgentToolCategory {
28
28
  const base = toolName.split(".").pop() ?? toolName;
29
- if (base === "bash") return "bash";
29
+ if (base === "bash" || base === "powershell") return "bash";
30
30
  if (base === "read") return "read";
31
31
  if (base === "edit") return "edit";
32
32
  if (base === "write") return "write";
@@ -1,7 +1,9 @@
1
1
  import {
2
2
  type ExtensionAPI,
3
3
  type ExtensionCommandContext,
4
+ type Skill,
4
5
  estimateTokens,
6
+ formatSkillsForPrompt,
5
7
  getMarkdownTheme,
6
8
  } from "@earendil-works/pi-coding-agent";
7
9
  import { Key, Markdown, matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
@@ -287,6 +289,11 @@ const tokenEstimate = (value: unknown): number => {
287
289
  return Math.max(0, Math.ceil(text.length / 4));
288
290
  };
289
291
 
292
+ function embeddedTokens(prompt: string, chunk: string): number {
293
+ if (!chunk || !prompt.includes(chunk)) return 0;
294
+ return tokenEstimate(chunk);
295
+ }
296
+
290
297
  type ToolPreviewInfo = {
291
298
  name: string;
292
299
  description?: string;
@@ -359,12 +366,7 @@ export function formatTokens(tokens: number): string {
359
366
 
360
367
  type SystemPromptOptions = {
361
368
  contextFiles?: Array<{ path: string; content: string }>;
362
- skills?: Array<{
363
- name: string;
364
- description?: string;
365
- filePath?: string;
366
- disableModelInvocation?: boolean;
367
- }>;
369
+ skills?: Skill[];
368
370
  selectedTools?: string[];
369
371
  toolSnippets?: Record<string, string>;
370
372
  promptGuidelines?: string[];
@@ -386,19 +388,11 @@ export function collectContextBreakdown(ctx: ExtensionCommandContext): ContextBr
386
388
  const systemPrompt = typeof ctx.getSystemPrompt === "function" ? ctx.getSystemPrompt() : "";
387
389
 
388
390
  const contextFileTokens = (options.contextFiles ?? []).reduce(
389
- (sum, file) => sum + tokenEstimate(file.content),
391
+ (sum, file) => sum + embeddedTokens(systemPrompt, file.content),
390
392
  0,
391
393
  );
392
- // Prefer field-level estimates over JSON.stringify(whole skill).
393
- const skillTokens = (options.skills ?? []).reduce((sum, skill) => {
394
- if (!skill || typeof skill !== "object") return sum + tokenEstimate(skill);
395
- return (
396
- sum +
397
- tokenEstimate(skill.name) +
398
- tokenEstimate(skill.description) +
399
- tokenEstimate(skill.filePath)
400
- );
401
- }, 0);
394
+ const skillsText = formatSkillsForPrompt(options.skills ?? []).trim();
395
+ const skillTokens = embeddedTokens(systemPrompt, skillsText);
402
396
  const tools = options.selectedTools ?? [];
403
397
  const snippets = options.toolSnippets;
404
398
  let toolTokens = tokenEstimate(options.promptGuidelines);
@@ -455,11 +449,17 @@ export default function contextUsageExtension(pi: ExtensionAPI) {
455
449
  const estimated = breakdown.parts.reduce((sum, part) => sum + part.tokens, 0);
456
450
  const fixedParts = breakdown.parts.filter(
457
451
  (part) =>
458
- part.label === "System prompt" || part.label === "Memory" || part.label === "Tools",
452
+ part.label === "System prompt" ||
453
+ part.label === "Memory" ||
454
+ part.label === "Skills" ||
455
+ part.label === "Tools",
459
456
  );
460
457
  const variableParts = breakdown.parts.filter(
461
458
  (part) =>
462
- part.label !== "System prompt" && part.label !== "Memory" && part.label !== "Tools",
459
+ part.label !== "System prompt" &&
460
+ part.label !== "Memory" &&
461
+ part.label !== "Skills" &&
462
+ part.label !== "Tools",
463
463
  );
464
464
  const orderedParts = [...fixedParts, ...variableParts];
465
465
  const fixedTokens = fixedParts.reduce((sum, part) => sum + part.tokens, 0);
@@ -71,7 +71,8 @@ export function styleCompactThinkingText(
71
71
  bold = false,
72
72
  ): string {
73
73
  if (!theme) return text;
74
- const colored = typeof theme.fg === "function" ? theme.fg("thinkingText", text) : text;
74
+ const color = config.dimThinkingText ? "dim" : "thinkingText";
75
+ const colored = typeof theme.fg === "function" ? theme.fg(color, text) : text;
75
76
  const weighted = bold && typeof theme.bold === "function" ? theme.bold(colored) : colored;
76
77
  return typeof theme.italic === "function" ? theme.italic(weighted) : weighted;
77
78
  }
@@ -1119,7 +1120,8 @@ export function installCompactMode(deps: CompactModeInstallDeps): CompactModeHoo
1119
1120
  }
1120
1121
  const name = String(this.toolName ?? "");
1121
1122
  if (EDIT_WRITE_TOOLS.has(name)) {
1122
- if (!this.result || this.isPartial === true) scheduleAnimation(this);
1123
+ if (this.executionStarted && (!this.result || this.isPartial === true))
1124
+ scheduleAnimation(this);
1123
1125
  const lines = compactEditWriteLine(this, width, deps.writeMetadata);
1124
1126
  if (this.expanded !== true) return lines;
1125
1127
  return compactEditWriteExpandedLines(this, width, deps.writeMetadata);
@@ -318,7 +318,7 @@ function createCcstyleTool(
318
318
  const isPending =
319
319
  visualState === "pending" ||
320
320
  (!visualState && (context?.isPartial || context?.executionStarted));
321
- if (isPending) scheduleAnimation(context);
321
+ if (isPending && context?.executionStarted) scheduleAnimation(context);
322
322
  const rawIcon = isPending ? pendingIcon(toolName) : settledIcon(toolName, visualState);
323
323
  const icon =
324
324
  visualState === "success"
@@ -678,6 +678,7 @@ export function installToolExpandedBackground(): () => void {
678
678
  const host = globalThis as any;
679
679
  const previous = host[TOOL_EXPANDED_BACKGROUND_PATCH] as ToolExpandedBackgroundPatch | undefined;
680
680
  if (previous) previous.dispose();
681
+ // SAFETY: Pi's runtime ToolExecutionComponent prototype owns updateDisplay; its public type omits it.
681
682
  const prototype = ToolExecutionComponent.prototype as unknown as { updateDisplay: () => void };
682
683
  const original = prototype.updateDisplay;
683
684
  const patch: ToolExpandedBackgroundPatch = {