@herbertgao/pi-extensions 2026.8.6 → 2026.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/README.md +5 -5
  2. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +1 -1
  3. package/node_modules/@herbertgao/pi-cc-extensions/README.md +1 -1
  4. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +19 -7
  5. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +30 -9
  6. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +272 -22
  7. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +94 -77
  8. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/message-display.ts +1 -1
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +14 -0
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +55 -17
  11. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +41 -2
  12. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +75 -6
  13. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/types.ts +7 -3
  14. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +64 -1
  15. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  16. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
  17. package/node_modules/@herbertgao/pi-subagents/README.md +30 -22
  18. package/node_modules/@herbertgao/pi-subagents/examples/agent-tool-description.md +5 -5
  19. package/node_modules/@herbertgao/pi-subagents/package.json +7 -7
  20. package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +7 -1
  21. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +48 -19
  22. package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +17 -13
  23. package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +26 -2
  24. package/node_modules/@herbertgao/pi-subagents/src/index.ts +219 -40
  25. package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +101 -3
  26. package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +18 -4
  27. package/node_modules/@herbertgao/pi-subagents/src/settings.ts +99 -0
  28. package/node_modules/@herbertgao/pi-subagents/src/types.ts +22 -3
  29. package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +51 -3
  30. package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +20 -2
  31. package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +21 -6
  32. package/node_modules/@herbertgao/pi-subagents/src/usage.ts +129 -1
  33. package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +20 -0
  34. package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +1 -0
  35. package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +26 -10
  36. package/node_modules/@juicesharp/rpiv-ask-user-question/config.ts +25 -0
  37. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/configuration.md +13 -4
  38. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +2 -1
  39. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/localization.md +3 -1
  40. package/node_modules/@juicesharp/rpiv-ask-user-question/locales/en.json +2 -2
  41. package/node_modules/@juicesharp/rpiv-ask-user-question/locales/zh.json +2 -2
  42. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +3 -2
  43. package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +10 -0
  44. package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +3 -1
  45. package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +30 -7
  46. package/node_modules/@juicesharp/rpiv-ask-user-question/state/state.ts +14 -6
  47. package/node_modules/@juicesharp/rpiv-ask-user-question/view/dialog-builder.ts +30 -4
  48. package/node_modules/@juicesharp/rpiv-ask-user-question/view/tab-content-strategy.ts +26 -5
  49. package/node_modules/@narumitw/pi-btw/README.md +120 -111
  50. package/node_modules/@narumitw/pi-btw/dist/index.ts +2898 -0
  51. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +7 -0
  52. package/node_modules/@narumitw/pi-btw/package.json +10 -6
  53. package/node_modules/@narumitw/pi-btw/src/btw.ts +36 -40
  54. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +55 -10
  55. package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +390 -0
  56. package/node_modules/@narumitw/pi-btw/src/menu.ts +45 -2
  57. package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +136 -45
  58. package/node_modules/pi-lens/CHANGELOG.md +909 -0
  59. package/node_modules/pi-lens/README.md +11 -3
  60. package/node_modules/pi-lens/config/ruff/core.toml +42 -0
  61. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +130 -27
  62. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +126 -13
  63. package/node_modules/pi-lens/dist/clients/agent-nudge.js +67 -11
  64. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +9 -3
  65. package/node_modules/pi-lens/dist/clients/atomic-write.js +9 -3
  66. package/node_modules/pi-lens/dist/clients/bash-file-access.js +285 -8
  67. package/node_modules/pi-lens/dist/clients/biome-client.js +61 -30
  68. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +428 -0
  69. package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +119 -0
  70. package/node_modules/pi-lens/dist/clients/bootstrap.js +12 -1
  71. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +12 -3
  72. package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +192 -0
  73. package/node_modules/pi-lens/dist/clients/cascade-budget.js +196 -0
  74. package/node_modules/pi-lens/dist/clients/cascade-format.js +20 -1
  75. package/node_modules/pi-lens/dist/clients/cascade-types.js +9 -1
  76. package/node_modules/pi-lens/dist/clients/child-unref.js +54 -6
  77. package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +76 -24
  78. package/node_modules/pi-lens/dist/clients/dead-code-client.js +123 -31
  79. package/node_modules/pi-lens/dist/clients/deadline-utils.js +8 -1
  80. package/node_modules/pi-lens/dist/clients/debug-handles.js +5 -0
  81. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +62 -13
  82. package/node_modules/pi-lens/dist/clients/dependency-checker.js +25 -3
  83. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +147 -33
  84. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +298 -0
  85. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +52 -2
  86. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +256 -88
  87. package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +7 -4
  88. package/node_modules/pi-lens/dist/clients/dispatch/plan.js +5 -0
  89. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +234 -18
  90. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +187 -19
  91. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +6 -3
  92. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +11 -9
  93. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +398 -0
  94. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +11 -3
  95. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +12 -7
  96. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +18 -0
  97. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +895 -0
  98. package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +4 -0
  99. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +16 -3
  100. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +60 -53
  101. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +16 -0
  102. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +23 -0
  103. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +331 -55
  104. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +38 -5
  105. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +97 -19
  106. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +14 -0
  107. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +20 -0
  108. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +22 -0
  109. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +10 -0
  110. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +18 -6
  111. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +73 -12
  112. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +275 -13
  113. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +21 -6
  114. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +260 -27
  115. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +734 -64
  116. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +86 -11
  117. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +72 -0
  118. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +9 -0
  119. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +9 -0
  120. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +18 -1
  121. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +4 -2
  122. package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +28 -5
  123. package/node_modules/pi-lens/dist/clients/extension-log.js +22 -1
  124. package/node_modules/pi-lens/dist/clients/file-kinds.js +8 -2
  125. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +294 -0
  126. package/node_modules/pi-lens/dist/clients/finding-identity.js +88 -0
  127. package/node_modules/pi-lens/dist/clients/formatters-lazy.js +3 -2
  128. package/node_modules/pi-lens/dist/clients/formatters.js +500 -115
  129. package/node_modules/pi-lens/dist/clients/generation-guard.js +216 -0
  130. package/node_modules/pi-lens/dist/clients/git-guard.js +31 -0
  131. package/node_modules/pi-lens/dist/clients/gitleaks-client.js +181 -8
  132. package/node_modules/pi-lens/dist/clients/govulncheck-client.js +109 -9
  133. package/node_modules/pi-lens/dist/clients/grammar-source.js +333 -10
  134. package/node_modules/pi-lens/dist/clients/host-ports.js +8 -0
  135. package/node_modules/pi-lens/dist/clients/installer/index.js +1114 -100
  136. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +58 -0
  137. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +715 -0
  138. package/node_modules/pi-lens/dist/clients/instance-reaper.js +643 -97
  139. package/node_modules/pi-lens/dist/clients/instance-registry.js +87 -17
  140. package/node_modules/pi-lens/dist/clients/jscpd-client.js +82 -6
  141. package/node_modules/pi-lens/dist/clients/knip-client.js +310 -10
  142. package/node_modules/pi-lens/dist/clients/language-policy.js +8 -2
  143. package/node_modules/pi-lens/dist/clients/language-profile.js +2 -0
  144. package/node_modules/pi-lens/dist/clients/latency-logger.js +440 -11
  145. package/node_modules/pi-lens/dist/clients/lazy-import.js +21 -0
  146. package/node_modules/pi-lens/dist/clients/ledger-bounds.js +21 -0
  147. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
  148. package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +102 -7
  149. package/node_modules/pi-lens/dist/clients/lsp/client.js +1516 -159
  150. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +83 -1
  151. package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +389 -0
  152. package/node_modules/pi-lens/dist/clients/lsp/index.js +2274 -147
  153. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +215 -0
  154. package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +146 -14
  155. package/node_modules/pi-lens/dist/clients/lsp/language.js +48 -4
  156. package/node_modules/pi-lens/dist/clients/lsp/server.js +277 -16
  157. package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +22 -0
  158. package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +43 -0
  159. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +79 -3
  160. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +43 -0
  161. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +422 -28
  162. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +30 -0
  163. package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +175 -0
  164. package/node_modules/pi-lens/dist/clients/lsp-lazy.js +3 -2
  165. package/node_modules/pi-lens/dist/clients/mcp/session.js +10 -2
  166. package/node_modules/pi-lens/dist/clients/module-report.js +8 -0
  167. package/node_modules/pi-lens/dist/clients/opengrep-client.js +15 -1
  168. package/node_modules/pi-lens/dist/clients/package-manager.js +170 -14
  169. package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +27 -0
  170. package/node_modules/pi-lens/dist/clients/path-utils.js +160 -0
  171. package/node_modules/pi-lens/dist/clients/pipeline.js +154 -33
  172. package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +37 -0
  173. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +17 -3
  174. package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +89 -22
  175. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +84 -14
  176. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +15 -3
  177. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +50 -2
  178. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -0
  179. package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
  180. package/node_modules/pi-lens/dist/clients/project-snapshot.js +299 -0
  181. package/node_modules/pi-lens/dist/clients/quiet-window-config.js +47 -0
  182. package/node_modules/pi-lens/dist/clients/quiet-window.js +11 -25
  183. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +1 -1
  184. package/node_modules/pi-lens/dist/clients/read-guard.js +184 -10
  185. package/node_modules/pi-lens/dist/clients/resource-sampler.js +49 -17
  186. package/node_modules/pi-lens/dist/clients/reverse-deps.js +50 -11
  187. package/node_modules/pi-lens/dist/clients/review-graph/query.js +52 -4
  188. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +96 -7
  189. package/node_modules/pi-lens/dist/clients/runtime-context.js +8 -1
  190. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +308 -45
  191. package/node_modules/pi-lens/dist/clients/runtime-session.js +332 -9
  192. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +217 -22
  193. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +212 -79
  194. package/node_modules/pi-lens/dist/clients/runtime-turn.js +575 -67
  195. package/node_modules/pi-lens/dist/clients/safe-spawn.js +220 -7
  196. package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +161 -0
  197. package/node_modules/pi-lens/dist/clients/search-read-registration.js +34 -6
  198. package/node_modules/pi-lens/dist/clients/security-scan-client.js +157 -24
  199. package/node_modules/pi-lens/dist/clients/sg-runner.js +116 -22
  200. package/node_modules/pi-lens/dist/clients/single-flight.js +158 -0
  201. package/node_modules/pi-lens/dist/clients/stale-marker.js +17 -0
  202. package/node_modules/pi-lens/dist/clients/startup-timing.js +19 -1
  203. package/node_modules/pi-lens/dist/clients/test-runner-client.js +151 -16
  204. package/node_modules/pi-lens/dist/clients/tool-event.js +56 -5
  205. package/node_modules/pi-lens/dist/clients/tool-policy.js +125 -20
  206. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +75 -1
  207. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +769 -64
  208. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +11 -0
  209. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +90 -0
  210. package/node_modules/pi-lens/dist/clients/trivy-client.js +19 -1
  211. package/node_modules/pi-lens/dist/clients/widget-state.js +336 -36
  212. package/node_modules/pi-lens/dist/clients/zizmor-config.js +214 -14
  213. package/node_modules/pi-lens/dist/index.js +67738 -55739
  214. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +466 -54
  215. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +132 -43
  216. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -7
  217. package/node_modules/pi-lens/docs/agent-guide.md +6 -1
  218. package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +515 -506
  219. package/node_modules/pi-lens/docs/dispositions.md +21 -0
  220. package/node_modules/pi-lens/docs/features.md +19 -5
  221. package/node_modules/pi-lens/docs/globalconfig.md +3 -0
  222. package/node_modules/pi-lens/docs/language-coverage.md +71 -5
  223. package/node_modules/pi-lens/docs/mcp.md +2 -2
  224. package/node_modules/pi-lens/docs/servercapabilities.md +4 -1
  225. package/node_modules/pi-lens/docs/settings.md +19 -1
  226. package/node_modules/pi-lens/docs/usage.md +1 -0
  227. package/node_modules/pi-lens/package.json +10 -6
  228. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-js-snapshot.yml +23 -0
  229. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-snapshot.yml +23 -0
  230. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/ts-void-zero-snapshot.yml +23 -0
  231. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-object-param-test.yml +16 -0
  232. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +15 -1
  233. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-compile-call-test.yml +29 -1
  234. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-dupe-class-members-test.yml +33 -0
  235. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-js-test.yml +7 -1
  236. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-test.yml +7 -1
  237. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-known-value-widening-test.yml +9 -0
  238. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-non-null-assertion-test.yml +216 -0
  239. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +2 -0
  240. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +2 -0
  241. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +2 -1
  242. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +2 -1
  243. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-return-value-in-generator-test.yml +12 -0
  244. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-runtime-typeof-test.yml +33 -0
  245. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-server-bind-wildcard-test.yml +9 -0
  246. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-shape-in-symbol-names-test.yml +13 -0
  247. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-js-test.yml +5 -1
  248. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-test.yml +5 -1
  249. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-parameters-test.yml +12 -0
  250. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-returns-test.yml +16 -0
  251. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-any-test.yml +10 -0
  252. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-unknown-test.yml +8 -0
  253. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/redundant-unsafe-function-test.yml +35 -0
  254. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/require-safety-comment-for-as-unknown-as-test.yml +177 -0
  255. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/ts-void-zero-test.yml +1 -0
  256. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member-js.yml +13 -2
  257. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member.yml +13 -2
  258. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +2 -0
  259. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-object-param.yml +60 -0
  260. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +57 -12
  261. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-compile-call.yml +63 -5
  262. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-dupe-class-members.yml +52 -8
  263. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html-js.yml +27 -2
  264. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html.yml +27 -2
  265. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-known-value-widening.yml +71 -0
  266. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-non-null-assertion.yml +316 -0
  267. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +7 -0
  268. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +22 -2
  269. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +23 -2
  270. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +33 -5
  271. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +34 -8
  272. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-return-value-in-generator.yml +22 -5
  273. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-runtime-typeof.yml +121 -0
  274. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-server-bind-wildcard.yml +23 -7
  275. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-shape-in-symbol-names.yml +68 -0
  276. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code-js.yml +41 -2
  277. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code.yml +41 -2
  278. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +6 -1
  279. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-parameters.yml +67 -0
  280. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-returns.yml +106 -0
  281. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-any.yml +50 -0
  282. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-unknown.yml +56 -0
  283. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +2 -0
  284. package/node_modules/pi-lens/rules/ast-grep-rules/rules/redundant-unsafe-function.yml +32 -0
  285. package/node_modules/pi-lens/rules/ast-grep-rules/rules/require-safety-comment-for-as-unknown-as.yml +184 -0
  286. package/node_modules/pi-lens/rules/ast-grep-rules/rules/ts-void-zero.yml +5 -0
  287. package/node_modules/pi-lens/rules/ast-grep-rules/self-scan-baseline.json +5 -0
  288. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +53 -1
  289. package/node_modules/pi-lens/scripts/download-grammars.js +25 -0
  290. package/node_modules/pi-lens/scripts/grammars.lock.json +9 -0
  291. package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +2 -0
  292. package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +80 -3
  293. package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +41 -0
  294. package/node_modules/pi-lens/vendor/grammars/tree-sitter-cue.wasm +0 -0
  295. package/node_modules/pi-mcp-adapter/CHANGELOG.md +36 -0
  296. package/node_modules/pi-mcp-adapter/README.md +47 -5
  297. package/node_modules/pi-mcp-adapter/cli.js +163 -1
  298. package/node_modules/pi-mcp-adapter/commands.ts +128 -22
  299. package/node_modules/pi-mcp-adapter/config.ts +25 -7
  300. package/node_modules/pi-mcp-adapter/direct-tools.ts +5 -4
  301. package/node_modules/pi-mcp-adapter/index.ts +219 -32
  302. package/node_modules/pi-mcp-adapter/init.ts +36 -4
  303. package/node_modules/pi-mcp-adapter/lifecycle.ts +315 -24
  304. package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +39 -6
  305. package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +387 -0
  306. package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +27 -3
  307. package/node_modules/pi-mcp-adapter/mcp-code.ts +4 -0
  308. package/node_modules/pi-mcp-adapter/mcp-panel.ts +42 -13
  309. package/node_modules/pi-mcp-adapter/metadata-cache.ts +32 -21
  310. package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +168 -0
  311. package/node_modules/pi-mcp-adapter/package.json +3 -1
  312. package/node_modules/pi-mcp-adapter/proxy-modes.ts +5 -4
  313. package/node_modules/pi-mcp-adapter/request-headers-command.ts +31 -37
  314. package/node_modules/pi-mcp-adapter/search-ranking.ts +92 -22
  315. package/node_modules/pi-mcp-adapter/server-manager.ts +140 -2
  316. package/node_modules/pi-mcp-adapter/session-recovery.ts +7 -0
  317. package/node_modules/pi-mcp-adapter/tool-approval.ts +15 -2
  318. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +44 -4
  319. package/node_modules/pi-mcp-adapter/types.ts +2 -0
  320. package/node_modules/pi-mcp-adapter/ui-server.ts +18 -16
  321. package/node_modules/pi-mcp-adapter/utils.ts +70 -0
  322. package/node_modules/pi-web-access/CHANGELOG.md +23 -0
  323. package/node_modules/pi-web-access/README.md +27 -9
  324. package/node_modules/pi-web-access/anysearch.ts +4 -2
  325. package/node_modules/pi-web-access/brave.ts +16 -4
  326. package/node_modules/pi-web-access/curator-page.ts +6 -3
  327. package/node_modules/pi-web-access/curator-server.ts +4 -1
  328. package/node_modules/pi-web-access/exa.ts +18 -7
  329. package/node_modules/pi-web-access/extract.ts +28 -3
  330. package/node_modules/pi-web-access/gemini-search.ts +16 -4
  331. package/node_modules/pi-web-access/index.ts +41 -57
  332. package/node_modules/pi-web-access/package.json +1 -1
  333. package/node_modules/pi-web-access/page-query.ts +4 -2
  334. package/node_modules/pi-web-access/parallel-mcp.ts +249 -0
  335. package/node_modules/pi-web-access/parallel.ts +2 -2
  336. package/node_modules/pi-web-access/query-rewrite.ts +51 -0
  337. package/node_modules/pi-web-access/serper.ts +211 -0
  338. package/node_modules/pi-web-access/summary-model-scope.ts +12 -4
  339. package/node_modules/pi-web-access/summary-review.ts +44 -22
  340. package/node_modules/pi-web-access/tavily.ts +16 -4
  341. package/node_modules/pi-web-access/utils.ts +87 -0
  342. package/node_modules/pi-web-access/valyu.ts +199 -0
  343. package/package.json +13 -13
@@ -8,7 +8,7 @@ import {
8
8
  } from "@earendil-works/pi-tui";
9
9
  import { TOOL_LOADING_INTERVAL_MS, toolLoadingIcon } from "../../utils/tool-loading-icon.ts";
10
10
  import { sanitizeToolResultText } from "../../utils/tool-result-sanitize.ts";
11
- import { showMoreHintText } from "../show-more-hint.ts";
11
+ import { isToolTuiFullscreen, showMoreHintText } from "../show-more-hint.ts";
12
12
 
13
13
  const PATCH_KEY = Symbol.for("pi.ccstyle.tool-grouping-patch");
14
14
  const PARENT_KEY = Symbol.for("pi.ccstyle.tool-grouping-parent");
@@ -274,6 +274,17 @@ function groupChildWidth(width: number): number {
274
274
  return Math.max(1, panelInnerWidth(width));
275
275
  }
276
276
 
277
+ type SettledGroupCache = {
278
+ width: number;
279
+ hover: boolean;
280
+ theme: unknown;
281
+ fullscreen: boolean;
282
+ children: readonly unknown[];
283
+ args: unknown[];
284
+ results: unknown[];
285
+ lines: string[];
286
+ };
287
+
277
288
  export class ToolGroupComponent extends Container {
278
289
  readonly toolCallId = `ccstyle-tool-group-${nextGroupId++}`;
279
290
  readonly toolName = "Tool group";
@@ -284,6 +295,8 @@ export class ToolGroupComponent extends Container {
284
295
  }
285
296
  private hintHovered = false;
286
297
  private readonly patch: Patch;
298
+ /** 仅缓存已完成且折叠的分组;pending / expanded 每帧现算。 */
299
+ private settledCache: SettledGroupCache | undefined;
287
300
 
288
301
  constructor(patch: Patch) {
289
302
  super();
@@ -292,11 +305,13 @@ export class ToolGroupComponent extends Container {
292
305
  }
293
306
 
294
307
  addTool(tool: any): void {
308
+ this.settledCache = undefined;
295
309
  this.children.push(tool);
296
310
  tool[PARENT_KEY] = this;
297
311
  }
298
312
 
299
313
  releaseTools(): any[] {
314
+ this.settledCache = undefined;
300
315
  const tools = [...this.children];
301
316
  this.children.length = 0;
302
317
  this.patch.groups.delete(this);
@@ -304,18 +319,21 @@ export class ToolGroupComponent extends Container {
304
319
  }
305
320
 
306
321
  removeTool(tool: any): void {
322
+ this.settledCache = undefined;
307
323
  const index = this.children.indexOf(tool);
308
324
  if (index >= 0) this.children.splice(index, 1);
309
325
  if (tool?.[PARENT_KEY] === this) delete tool[PARENT_KEY];
310
326
  }
311
327
 
312
328
  setExpanded(expanded: boolean): void {
329
+ if (this._expanded !== expanded) this.settledCache = undefined;
313
330
  this._expanded = expanded;
314
331
  for (const tool of this.children)
315
332
  (tool as Component & { setExpanded?: (expanded: boolean) => void }).setExpanded?.(expanded);
316
333
  }
317
334
 
318
335
  setHintHovered(hovered: boolean): void {
336
+ if (this.hintHovered !== hovered) this.settledCache = undefined;
319
337
  this.hintHovered = hovered;
320
338
  }
321
339
 
@@ -344,10 +362,53 @@ export class ToolGroupComponent extends Container {
344
362
  }
345
363
 
346
364
  invalidate(): void {
365
+ this.settledCache = undefined;
347
366
  for (const tool of this.children) tool.invalidate?.();
348
367
  }
349
368
 
369
+ private settledCacheHit(width: number): string[] | undefined {
370
+ const cache = this.settledCache;
371
+ if (!cache || this._expanded) return;
372
+ if (
373
+ cache.width !== width ||
374
+ cache.hover !== this.hintHovered ||
375
+ cache.theme !== this.patch.theme ||
376
+ cache.fullscreen !== isToolTuiFullscreen()
377
+ ) {
378
+ return;
379
+ }
380
+ const tools = this.children as any[];
381
+ if (cache.children.length !== tools.length) return;
382
+ for (let i = 0; i < tools.length; i++) {
383
+ const tool = tools[i];
384
+ if (
385
+ cache.children[i] !== tool ||
386
+ cache.args[i] !== tool?.args ||
387
+ cache.results[i] !== tool?.result ||
388
+ status(tool) === "pending"
389
+ ) {
390
+ return;
391
+ }
392
+ }
393
+ return cache.lines;
394
+ }
395
+
396
+ private storeSettledCache(width: number, lines: string[]): void {
397
+ this.settledCache = {
398
+ width,
399
+ hover: this.hintHovered,
400
+ theme: this.patch.theme,
401
+ fullscreen: isToolTuiFullscreen(),
402
+ children: [...this.children],
403
+ args: (this.children as any[]).map((tool) => tool?.args),
404
+ results: (this.children as any[]).map((tool) => tool?.result),
405
+ lines,
406
+ };
407
+ }
408
+
350
409
  render(width: number): string[] {
410
+ const cached = this.settledCacheHit(width);
411
+ if (cached) return cached;
351
412
  const theme = this.patch.theme;
352
413
  const fg = (color: string, text: string) => theme?.fg?.(color, text) ?? text;
353
414
  const counts = { pending: 0, success: 0, error: 0 };
@@ -420,6 +481,8 @@ export class ToolGroupComponent extends Container {
420
481
  lines.push(paddedBackgroundRow(theme, backgroundSlot, line, width));
421
482
  }
422
483
  lines.push(paddedBackgroundRow(theme, backgroundSlot, "", width));
484
+ } else if (counts.pending === 0) {
485
+ this.storeSettledCache(width, lines);
423
486
  }
424
487
  return lines;
425
488
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@herbertgao/pi-cc-extensions",
3
- "version": "0.8.55",
3
+ "version": "0.8.56",
4
4
  "license": "MIT",
5
5
  "description": "A Pi productivity suite with Claude Code-style UI, context inspection, and agent/session references",
6
6
  "type": "module",
@@ -69,8 +69,8 @@
69
69
  },
70
70
  "x-upstream": {
71
71
  "package": "pi-cc-extensions",
72
- "version": "0.8.60",
72
+ "version": "0.8.63",
73
73
  "repository": "https://github.com/minuque/pi-cc-extensions",
74
- "commit": "268e017acde0b2adb65cefef3c740e37b1aef202"
74
+ "commit": "6b7447eb9d82afa9ea26dd7433c59ff56663098e"
75
75
  }
76
76
  }
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.16.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#90](https://github.com/HerbertGao/pi-extensions/pull/90) [`74b7bce`](https://github.com/HerbertGao/pi-extensions/commit/74b7bceac14c36961d25af9cbc6aecc502bdaf3b) Thanks [@HerbertGao](https://github.com/HerbertGao)! - Selectively sync pi-subagents with upstream 0.18.0, including worktree controls, background-by-default top-level agents, usage and cost reporting, programmatic activity tracking, child-session shutdown, and nested print-mode coverage.
8
+
3
9
  ## 0.15.5
4
10
 
5
11
  ### Patch Changes
@@ -13,7 +13,7 @@ Spawn specialized agents that run in isolated sessions — each with its own too
13
13
  ## Features
14
14
 
15
15
  - **Claude Code look & feel** — same tool names, calling conventions, and UI patterns (`Agent`, `get_subagent_result`, `steer_subagent`) — feels native
16
- - **Parallel background agents** — spawn multiple agents that run concurrently with automatic queuing (configurable concurrency limit, default 4) and smart group join (consolidated notifications)
16
+ - **Parallel background agents** — top-level agents run detached by default, with automatic queuing (configurable concurrency limit, default 10) and smart group join; nested delegation still defaults to foreground
17
17
  - **Live widget UI** — persistent above-editor widget with animated spinners, live tool activity, token counts, and colored status icons. Configurable via `/agents → Settings → Widget`: `all` (every agent), `background` (default — hides foreground runs, which already render inline as the `Agent` tool result), or `off`
18
18
  - **FleetView** — Claude Code-style navigable list of `main` + every running subagent rendered below the editor (earliest-launched first). Press `↓` (or `←`) at an empty prompt to jump in, `↑`/`↓` to move the selection, `Enter` to open the selected agent's live, auto-updating conversation, `Esc` to return. Finished agents linger briefly before dropping out, and a viewer stays open through completion so you can read the final output. Toggle via `/agents → Settings → Fleet view`
19
19
  - **Conversation viewer** — select any agent in `/agents` to open a live-scrolling overlay of its full conversation (auto-follows new content, scroll up to pause). Steer a running agent inline by pressing `Enter` to open a composer, typing, then `Enter` to send (`Esc` or an empty submit returns) — the message appears as a user message and redirects the agent after its current tool. Stop a still-running agent by pressing `x` (then `x` again to confirm) — both work for background agents too
@@ -26,7 +26,8 @@ Spawn specialized agents that run in isolated sessions — each with its own too
26
26
  - **Fuzzy model selection** — specify models by name (`"haiku"`, `"sonnet"`) instead of full IDs, with automatic filtering to only available/configured models
27
27
  - **Context inheritance** — optionally fork the parent conversation into a sub-agent so it knows what's been discussed
28
28
  - **Persistent agent memory** — three scopes (project, local, user) with automatic read-only fallback for agents without write tools
29
- - **Git worktree isolation** — run agents in isolated repo copies; changes auto-committed to branches on completion
29
+ - **Git worktree isolation** — run agents in isolated repo copies; `isolation: off` and the project-wide `worktreeIsolation` switch keep work in the current checkout, while preservation commits bypass interactive signing
30
+ - **Usage and cost reporting** — optionally include subagent spend in the parent session's stats (`reportUsage`) and show estimated USD cost across subagent UI surfaces (`showCost`)
30
31
  - **Skill preloading** — inject named skills into agent system prompts, discovered from `.pi/skills/`, `.agents/skills/`, and global locations (Pi-standard `<name>/SKILL.md` directory layout supported)
31
32
  - **Tool denylist** — block specific tools via `disallowed_tools` frontmatter
32
33
  - **Styled completion notifications** — background agent results render as themed, compact notification boxes (icon, stats, result preview) instead of raw XML. Expandable to show full output. Group completions render each agent individually
@@ -60,7 +61,7 @@ Agent({
60
61
  })
61
62
  ```
62
63
 
63
- Foreground agents block until complete and return results inline. Background agents return an ID immediately and notify you on completion.
64
+ Agents run in the background by default: calls return an ID immediately and notify on completion. Pass `run_in_background: false` to block and return the full result inline. Nested spawns keep the safer foreground default unless explicitly overridden.
64
65
 
65
66
  ### Scheduling
66
67
 
@@ -227,7 +228,7 @@ All fields are optional — sensible defaults for everything.
227
228
  | `skills` | `true` | Inherit skills from parent. Can be a comma-separated list of skill names to preload (see [Skill Preloading](#skill-preloading) for discovery locations) |
228
229
  | `memory` | — | Persistent agent memory scope: `project`, `local`, or `user`. Auto-detects read-only agents |
229
230
  | `disallowed_tools` | — | Comma-separated tools to deny even if extensions provide them |
230
- | `isolation` | — | Set to `worktree` to run in an isolated git worktree |
231
+ | `isolation` | — | `worktree` runs in an isolated git worktree; `off` vetoes a caller-requested worktree |
231
232
  | `model` | inherit parent | Model — `provider/modelId` or fuzzy name (`"haiku"`, `"sonnet"`). Resolved tolerantly (`.`/`-` and a trailing date stamp are interchangeable) and falls back to the same model under another provider if the named one doesn't have it |
232
233
  | `thinking` | inherit | off, minimal, low, medium, high, xhigh, max — actual availability depends on your pi version and model; pi clamps unsupported levels down |
233
234
  | `max_turns` | unlimited | Max agentic turns before graceful shutdown. `0` or omit for unlimited |
@@ -237,7 +238,7 @@ All fields are optional — sensible defaults for everything.
237
238
  | `allowed_subagents` | none | Opt in to scoped nested `Agent`, `get_subagent_result`, and `steer_subagent` tools. Omitted / empty / `none` / `false` = no nesting; `all` (or `"*"` / `true`) = any enabled agent; comma-separated list = only those agent types |
238
239
  | `prompt_mode` | `replace` | `replace`: body is the full system prompt (no AGENTS.md / CLAUDE.md inheritance). `append`: body appended to parent's prompt (agent acts as a "parent twin" — inherits parent's AGENTS.md / CLAUDE.md) |
239
240
  | `inherit_context` | `false` | Fork parent conversation into agent |
240
- | `run_in_background` | `false` | Run in background by default |
241
+ | `run_in_background` | `backgroundByDefault` | Pin this agent to background (`true`) or foreground (`false`); omit to follow the project default |
241
242
  | `isolated` | `false` | Hermetic specialist mode: forces `extensions: false` + `skills: false` + drops `ext:` selectors. Only built-in tools. Distinct from `isolation: worktree` (filesystem) |
242
243
  | `enabled` | `true` | Set to `false` to disable an agent (useful for hiding a default agent per-project) |
243
244
 
@@ -298,6 +299,7 @@ A few rules the examples don't make obvious:
298
299
  - Any `ext:` entry flips extension tools to an explicit allowlist — unnamed extensions still load (handlers fire) but expose no tools. So `tools: "*, ext:mcp/search"` exposes only `search` from `mcp`, nothing from any other extension.
299
300
  - Extension names match case-insensitively (`[Mcp]` = `[mcp]`); tool names in `ext:foo/bar` stay case-sensitive.
300
301
  - Extensions that register tools **lazily** work too. MCP-backed extensions typically can't enumerate their tools until their servers connect, so they register from `session_start` or `before_agent_start` rather than at load. Subagent scoping is re-derived as tools appear, so these surface normally — including under `ext:` selectors, which keep narrowing correctly no matter when a tool shows up.
302
+ - Extensions bound into a child session receive `session_shutdown` before disposal, including record eviction and root-session shutdown; release per-session timers, watchers, sockets, and temp resources there.
301
303
  - An installed **package** extension matches by its package short name (`@scope/pi-subagents` → `[pi-subagents]`), in addition to its path-derived name (a package whose entry is `src/index.ts` also answers to `[src]`). Prefer the package name — the path-derived one is incidental.
302
304
  - Plain `tools:` typos fail loudly: `tools: reed, grep` fires `tools-error:…` instead of silently producing an under-tooled agent.
303
305
  - `exclude_extensions:` wins over `extensions:` and over `ext:` selectors — an excluded extension never loads and a `tools: ext:` entry can't pull it back. Plain names only (no paths, no `*`); a name matching nothing fires an `extension-error:…` warning.
@@ -310,19 +312,19 @@ A few rules the examples don't make obvious:
310
312
 
311
313
  Launch a sub-agent.
312
314
 
313
- | Parameter | Type | Required | Description |
314
- | ------------------- | ------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
315
- | `prompt` | string | yes | The task for the agent |
316
- | `description` | string | yes | Short 3-5 word summary (shown in UI) |
317
- | `subagent_type` | string | yes | Agent type (built-in or custom) |
318
- | `model` | string | no | Model — `provider/modelId` or fuzzy name (`"haiku"`, `"sonnet"`). Resolved tolerantly (`.`/`-` and a trailing date stamp interchangeable) with provider fallback |
319
- | `thinking` | string | no | Thinking level: off, minimal, low, medium, high, xhigh, max (availability depends on pi version and model) |
320
- | `max_turns` | number | no | Max agentic turns. Omit for unlimited (default) |
321
- | `run_in_background` | boolean | no | Run without blocking |
322
- | `resume` | string | no | Agent ID to resume a previous session |
323
- | `isolated` | boolean | no | No extension/MCP tools |
324
- | `isolation` | `"worktree"` | no | Run in an isolated git worktree |
325
- | `inherit_context` | boolean | no | Fork parent conversation into agent |
315
+ | Parameter | Type | Required | Description |
316
+ | ------------------- | ----------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
317
+ | `prompt` | string | yes | The task for the agent |
318
+ | `description` | string | yes | Short 3-5 word summary (shown in UI) |
319
+ | `subagent_type` | string | yes | Agent type (built-in or custom) |
320
+ | `model` | string | no | Model — `provider/modelId` or fuzzy name (`"haiku"`, `"sonnet"`). Resolved tolerantly (`.`/`-` and a trailing date stamp interchangeable) with provider fallback |
321
+ | `thinking` | string | no | Thinking level: off, minimal, low, medium, high, xhigh, max (availability depends on pi version and model) |
322
+ | `max_turns` | number | no | Max agentic turns. Omit for unlimited (default) |
323
+ | `run_in_background` | boolean | no | Defaults to `true`; `false` blocks and returns the result inline |
324
+ | `resume` | string | no | Agent ID to resume a previous session |
325
+ | `isolated` | boolean | no | No extension/MCP tools |
326
+ | `isolation` | `"off"` \| `"worktree"` | no | `worktree` isolates; `off` keeps the current checkout. Omitted when worktree isolation is disabled |
327
+ | `inherit_context` | boolean | no | Fork parent conversation into agent |
326
328
 
327
329
  ### `get_subagent_result`
328
330
 
@@ -388,7 +390,7 @@ Instead of hard-aborting at the turn limit, agents get a graceful shutdown:
388
390
 
389
391
  ## Concurrency
390
392
 
391
- Background agents are subject to a configurable concurrency limit (default: 4). Excess agents are automatically queued and start as running agents complete. The widget shows queued agents as a collapsed count.
393
+ Background agents are subject to a configurable concurrency limit (default: 10). Excess agents are automatically queued and start as running agents complete. The widget shows queued agents as a collapsed count.
392
394
 
393
395
  Foreground agents bypass the queue — they block the parent anyway.
394
396
 
@@ -432,12 +434,18 @@ When on, each subagent spawn's effective model is validated against pi's own `en
432
434
 
433
435
  ## Persistent Settings
434
436
 
435
- Runtime tuning values set via `/agents` → Settings (max concurrency, default max turns, grace turns, nested depth, fallback agent, default join mode, scheduling on/off, scope models on/off, strict agent files on/off, disable defaults on/off, output transcript on/off, tool description full/compact/custom, widget all/background/off) persist across pi restarts. Two files, merged on load:
437
+ Runtime tuning values set via `/agents` → Settings (including background default, worktree isolation, usage reporting, and cost display) persist across pi restarts. Two files, merged on load:
436
438
 
437
439
  - **Global:** `~/.pi/agent/subagents.json` — your machine-wide defaults. Edit by hand; the `/agents` menu never writes here.
438
440
  - **Project:** `<cwd>/.pi/subagents.json` — per-project overrides. Written by `/agents` → Settings.
439
441
 
440
- **Precedence:** project overrides global on any field present in both. Missing fields fall back to the hardcoded defaults (max concurrency `4`, default max turns unlimited, grace turns `5`, nested depth `2`, join mode `smart`, strict agent files disabled, defaults enabled).
442
+ **Precedence:** project overrides global on any field present in both. Missing fields fall back to the hardcoded defaults (max concurrency `10`, background by default enabled, default max turns unlimited, grace turns `5`, nested depth `2`, join mode `smart`, worktree isolation enabled, usage/cost reporting disabled, strict agent files disabled, defaults enabled).
443
+
444
+ **Background by default** (`backgroundByDefault`, default `true`): unqualified top-level `Agent` calls run detached. Set `false` to restore foreground-by-default behavior. Explicit tool or agent-file `run_in_background` values win. Nested calls always default to foreground so a parent cannot finish and stop an uncollected child.
445
+
446
+ **Worktree isolation** (`worktreeIsolation`, default `true`): set `false` to reject worktree creation on every spawn path and remove the `isolation` parameter and guidance on the next Pi session. `isolation: off` in agent frontmatter vetoes a caller's `worktree` request.
447
+
448
+ **Usage and cost** (`reportUsage` and `showCost`, both default `false`): `reportUsage` attaches child usage to parent tool results so Pi session stats include delegated work; `showCost` renders Pi's estimated USD totals in subagent surfaces. They are independent.
441
449
 
442
450
  **Strict agent files** (`strictAgentFiles`, default `false`): fail extension startup when any discovered agent file is unreadable or malformed. Enable via `/agents → Settings → Strict agent files` or set `true` in `subagents.json`. Strictness applies only to startup; reloads before later Agent calls remain tolerant so a file edited incorrectly mid-session is skipped with a warning instead of aborting the call.
443
451
 
@@ -460,7 +468,7 @@ Launch an autonomous agent. Available types:
460
468
  Custom agents live in .pi/agents/ or {{agentDir}}/agents/.
461
469
  ```
462
470
 
463
- Placeholders: `{{typeList}}` (full per-agent descriptions), `{{compactTypeList}}` (first sentence each), `{{agentDir}}`, `{{scheduleGuideline}}` (expands with its own leading newline + `-` bullet when scheduling is on — place it directly after your last rule line; empty when scheduling is off). Unknown placeholders are left verbatim with a stderr warning; a missing or empty file falls back to `"full"` with a warning. Note the usual trust umbrella: a project-level file shapes the orchestrator's prompt, same as project agents and extensions do.
471
+ Placeholders: `{{typeList}}` (full per-agent descriptions), `{{compactTypeList}}` (first sentence each), `{{agentDir}}`, `{{isolationGuideline}}` (empty when worktrees are disabled), `{{scheduleGuideline}}` (expands with its own leading newline + `-` bullet when scheduling is on — place it directly after your last rule line; empty when scheduling is off). Unknown placeholders are left verbatim with a stderr warning; a missing or empty file falls back to `"full"` with a warning. Note the usual trust umbrella: a project-level file shapes the orchestrator's prompt, same as project agents and extensions do.
464
472
 
465
473
  **Starting point:** copy [`examples/agent-tool-description.md`](examples/agent-tool-description.md) — it reproduces the default full description exactly (a CI test keeps it in sync), so you can trim from a known-good baseline instead of writing from scratch.
466
474
 
@@ -14,19 +14,19 @@ If the target is already known, use a direct tool — `read` for a known path, `
14
14
  ## Usage notes
15
15
 
16
16
  - Always include a short (3-5 word) description summarizing what the agent will do (shown in UI).
17
- - When you launch multiple agents for independent work, send them in a single message with multiple tool uses, with run_in_background: true on each, so they run concurrently. If the user specifies that they want agents run "in parallel", you MUST send a single message with multiple tool calls. Foreground calls run sequentially — only one executes at a time.
17
+ - When you launch multiple agents for independent work, send them in a single message with multiple tool uses so they run concurrently.
18
18
  - When the agent is done, it returns a single message back to you. The result is not visible to the user — to show the user, send a text message with a concise summary.
19
19
  - Trust but verify: an agent's summary describes what it intended to do, not necessarily what it did. When an agent writes or edits code, check the actual changes before reporting work as done.
20
- - Use run_in_background for work you don't need immediately. You will be notified when it completes — do NOT poll or sleep waiting for it. Continue with other work or respond to the user instead.
21
- - Foreground vs background: use foreground (default) when you need the agent's results before you can proceed. Use background when you have genuinely independent work to do in parallel.
20
+ - Agents run in the background by default. You will be notified when one completes — do NOT poll or sleep waiting for it.
21
+ - Pass `run_in_background: false` only when your very next action depends on the result and nothing else could usefully happen while it runs.
22
+ - Never fabricate or predict a pending agent's results; if asked before completion, say it is still running.
22
23
  - Use resume with an agent ID to continue a previous agent's work. A new (non-resume) Agent call starts a fresh agent with no memory of prior runs, so the prompt must be self-contained.
23
24
  - Use steer_subagent to send mid-run messages to a running background agent.
24
25
  - Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, etc.), since it is not aware of the user's intent.
25
26
  - If an agent's description says it should be used proactively, try to use it without the user having to ask for it first.
26
27
  - Use model to specify a different model (as "provider/modelId", or fuzzy e.g. "haiku", "sonnet").
27
28
  - Use thinking to control extended thinking level.
28
- - Use inherit_context if the agent needs the parent conversation history.
29
- - Use isolation: "worktree" to run the agent in an isolated git worktree (safe parallel file modifications). The worktree is automatically cleaned up if the agent makes no changes; otherwise the path and branch are returned in the result.{{scheduleGuideline}}
29
+ - Use inherit_context if the agent needs the parent conversation history.{{isolationGuideline}}{{scheduleGuideline}}
30
30
 
31
31
  ## Writing the prompt
32
32
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@herbertgao/pi-subagents",
3
- "version": "0.15.5",
3
+ "version": "0.16.0",
4
4
  "description": "Claude Code-style autonomous subagents for Pi, with HerbertGao-maintained UI extensions.",
5
5
  "keywords": [
6
6
  "agent",
@@ -46,15 +46,15 @@
46
46
  "dependencies": {
47
47
  "@sinclair/typebox": "^0.34.49",
48
48
  "croner": "^10.0.1",
49
- "nanoid": "^5.0.0"
49
+ "nanoid": "^5.1.16"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@vitest/coverage-istanbul": "^4.1.10"
53
53
  },
54
54
  "peerDependencies": {
55
- "@earendil-works/pi-ai": ">=0.80.0",
56
- "@earendil-works/pi-coding-agent": ">=0.80.0",
57
- "@earendil-works/pi-tui": ">=0.80.0"
55
+ "@earendil-works/pi-ai": ">=0.81.0",
56
+ "@earendil-works/pi-coding-agent": ">=0.81.0",
57
+ "@earendil-works/pi-tui": ">=0.81.0"
58
58
  },
59
59
  "engines": {
60
60
  "node": ">=22.19.0"
@@ -68,8 +68,8 @@
68
68
  },
69
69
  "x-upstream": {
70
70
  "package": "@tintinweb/pi-subagents",
71
- "version": "0.16.1",
71
+ "version": "0.18.0",
72
72
  "repository": "https://github.com/tintinweb/pi-subagents",
73
- "commit": "bb47763"
73
+ "commit": "3f9d35cd078d18a141eb5a6d8f4fc5010d756280"
74
74
  }
75
75
  }
@@ -245,7 +245,13 @@ export function serializeAgentFile(cfg: AgentConfig): string {
245
245
  if (cfg.disallowedTools?.length)
246
246
  fmFields.push(`disallowed_tools: ${cfg.disallowedTools.join(", ")}`)
247
247
  if (cfg.inheritContext) fmFields.push("inherit_context: true")
248
- if (cfg.runInBackground) fmFields.push("run_in_background: true")
248
+ // Both cases, not just `true`: with `backgroundByDefault` on, omitting the
249
+ // field means background, so `false` is the only way to pin an agent file to
250
+ // foreground and is no longer interchangeable with absence. No caller can
251
+ // reach it yet — Eject only handles built-in defaults, which omit the field —
252
+ // so this keeps the writer symmetric with the loader, nothing more.
253
+ if (cfg.runInBackground !== undefined)
254
+ fmFields.push(`run_in_background: ${cfg.runInBackground}`)
249
255
  if (cfg.outputTranscript === false) fmFields.push("output_transcript: false")
250
256
  if (cfg.isolated) fmFields.push("isolated: true")
251
257
  if (cfg.memory) fmFields.push(`memory: ${cfg.memory}`)
@@ -24,19 +24,25 @@ import type {
24
24
  SubagentType,
25
25
  ThinkingLevel,
26
26
  } from "./types.js"
27
- import { addUsage } from "./usage.js"
28
- import { cleanupWorktree, createWorktree, pruneWorktrees } from "./worktree.js"
27
+ import { addUsage, type LifetimeUsage } from "./usage.js"
28
+ import {
29
+ cleanupWorktree,
30
+ createWorktree,
31
+ isWorktreeIsolationEnabled,
32
+ pruneWorktrees,
33
+ } from "./worktree.js"
29
34
 
30
35
  export type OnAgentComplete = (record: AgentRecord) => void
31
36
  export type OnAgentStart = (record: AgentRecord) => void
32
37
  export type OnAgentCompact = (record: AgentRecord, info: CompactionInfo) => void
38
+ export type OnAgentUsage = (record: AgentRecord, usage: LifetimeUsage) => void
33
39
  export type CompactionInfo = {
34
40
  reason: "manual" | "threshold" | "overflow"
35
41
  tokensBefore: number
36
42
  }
37
43
 
38
44
  /** Default max concurrent background agents. */
39
- const DEFAULT_MAX_CONCURRENT = 4
45
+ const DEFAULT_MAX_CONCURRENT = 10
40
46
 
41
47
  /**
42
48
  * Validate a caller-supplied SpawnOptions.cwd. `undefined`/`null` mean "unset"
@@ -125,11 +131,7 @@ interface SpawnOptions {
125
131
  /** Called at the end of each agentic turn with the cumulative count. */
126
132
  onTurnEnd?: (turnCount: number) => void
127
133
  /** Called once per assistant message_end with that message's usage delta. */
128
- onAssistantUsage?: (usage: {
129
- input: number
130
- output: number
131
- cacheWrite: number
132
- }) => void
134
+ onAssistantUsage?: (usage: LifetimeUsage) => void
133
135
  /** Called when the session successfully compacts. */
134
136
  onCompaction?: (info: CompactionInfo) => void
135
137
  /** Nesting depth: top-level subagent = 1. */
@@ -158,11 +160,7 @@ interface ResumeOptions {
158
160
  /** Called at the end of each resumed agentic turn with the cumulative count. */
159
161
  onTurnEnd?: (turnCount: number) => void
160
162
  /** Called once per assistant message_end with that message's usage delta. */
161
- onAssistantUsage?: (usage: {
162
- input: number
163
- output: number
164
- cacheWrite: number
165
- }) => void
163
+ onAssistantUsage?: (usage: LifetimeUsage) => void
166
164
  /** Called when the session successfully compacts. */
167
165
  onCompaction?: (info: CompactionInfo) => void
168
166
  /**
@@ -176,12 +174,38 @@ interface ResumeOptions {
176
174
  onStarted?: () => void
177
175
  }
178
176
 
177
+ const CHILD_SHUTDOWN_TIMEOUT_MS = 3_000
178
+
179
+ async function shutdownChildSession(
180
+ session: AgentSession | undefined,
181
+ ): Promise<void> {
182
+ try {
183
+ const runner = session?.extensionRunner
184
+ if (runner?.hasHandlers?.("session_shutdown")) {
185
+ await Promise.race([
186
+ runner.emit({ type: "session_shutdown", reason: "quit" }),
187
+ new Promise<void>((resolve) =>
188
+ setTimeout(resolve, CHILD_SHUTDOWN_TIMEOUT_MS).unref(),
189
+ ),
190
+ ])
191
+ }
192
+ } catch {
193
+ /* best-effort lifecycle cleanup */
194
+ }
195
+ try {
196
+ session?.dispose?.()
197
+ } catch {
198
+ /* ignore */
199
+ }
200
+ }
201
+
179
202
  export class AgentManager {
180
203
  private agents = new Map<string, AgentRecord>()
181
204
  private cleanupInterval: ReturnType<typeof setInterval>
182
205
  private onComplete?: OnAgentComplete
183
206
  private onStart?: OnAgentStart
184
207
  private onCompact?: OnAgentCompact
208
+ private onUsage?: OnAgentUsage
185
209
  private maxConcurrent: number
186
210
  /** Base repos worktrees were created from — so dispose() can prune them all,
187
211
  * not just the parent repo (caller-supplied cwd can target other repos). */
@@ -197,10 +221,12 @@ export class AgentManager {
197
221
  maxConcurrent = DEFAULT_MAX_CONCURRENT,
198
222
  onStart?: OnAgentStart,
199
223
  onCompact?: OnAgentCompact,
224
+ onUsage?: OnAgentUsage,
200
225
  ) {
201
226
  this.onComplete = onComplete
202
227
  this.onStart = onStart
203
228
  this.onCompact = onCompact
229
+ this.onUsage = onUsage
204
230
  this.maxConcurrent = maxConcurrent
205
231
  // Cleanup completed agents after 10 minutes (but keep sessions for resume)
206
232
  this.cleanupInterval = setInterval(() => this.cleanup(), 60_000)
@@ -302,7 +328,7 @@ export class AgentManager {
302
328
  // fail loud if not possible (no silent fallback to main tree). Done
303
329
  // BEFORE state mutation so a throw doesn't leave the record half-running.
304
330
  let worktreeCwd: string | undefined
305
- if (options.isolation === "worktree") {
331
+ if (options.isolation === "worktree" && isWorktreeIsolationEnabled()) {
306
332
  const wt = createWorktree(baseCwd, id)
307
333
  if (!wt) {
308
334
  throw new Error(
@@ -365,6 +391,7 @@ export class AgentManager {
365
391
  onTextDelta: options.onTextDelta,
366
392
  onAssistantUsage: (usage) => {
367
393
  addUsage(record.lifetimeUsage, usage)
394
+ this.onUsage?.(record, usage)
368
395
  options.onAssistantUsage?.(usage)
369
396
  },
370
397
  onCompaction: (info) => {
@@ -662,6 +689,7 @@ export class AgentManager {
662
689
  onTurnEnd: options?.onTurnEnd,
663
690
  onAssistantUsage: (usage) => {
664
691
  addUsage(record.lifetimeUsage, usage)
692
+ this.onUsage?.(record, usage)
665
693
  options?.onAssistantUsage?.(usage)
666
694
  },
667
695
  onCompaction: (info) => {
@@ -766,6 +794,7 @@ export class AgentManager {
766
794
  onTurnEnd: options.onTurnEnd,
767
795
  onAssistantUsage: (usage) => {
768
796
  addUsage(record.lifetimeUsage, usage)
797
+ this.onUsage?.(record, usage)
769
798
  options.onAssistantUsage?.(usage)
770
799
  },
771
800
  onCompaction: (info) => {
@@ -851,9 +880,10 @@ export class AgentManager {
851
880
 
852
881
  /** Dispose a record's session and remove it from the map. */
853
882
  private removeRecord(id: string, record: AgentRecord): void {
854
- record.session?.dispose?.()
883
+ const session = record.session
855
884
  record.session = undefined
856
885
  this.agents.delete(id)
886
+ void shutdownChildSession(session)
857
887
  }
858
888
 
859
889
  private cleanup() {
@@ -926,14 +956,13 @@ export class AgentManager {
926
956
  }
927
957
  }
928
958
 
929
- dispose() {
959
+ async dispose(): Promise<void> {
930
960
  clearInterval(this.cleanupInterval)
931
961
  // Clear queue
932
962
  this.queue = []
933
- for (const record of this.agents.values()) {
934
- record.session?.dispose()
935
- }
963
+ const sessions = [...this.agents.values()].map((record) => record.session)
936
964
  this.agents.clear()
965
+ await Promise.all(sessions.map((session) => shutdownChildSession(session)))
937
966
  // Prune any orphaned git worktrees (crash recovery)
938
967
  try {
939
968
  pruneWorktrees(process.cwd())
@@ -41,6 +41,7 @@ import {
41
41
  import { buildAgentPrompt, type PromptExtras } from "./prompts.js"
42
42
  import { preloadSkills } from "./skill-loader.js"
43
43
  import type { SubagentType, ThinkingLevel } from "./types.js"
44
+ import type { LifetimeUsage } from "./usage.js"
44
45
 
45
46
  /**
46
47
  * Tool names registered by THIS extension. Single source of truth so the
@@ -349,6 +350,15 @@ export function setDefaultMaxTurns(n: number | undefined): void {
349
350
  defaultMaxTurns = normalizeMaxTurns(n)
350
351
  }
351
352
 
353
+ export function resolveEffectiveMaxTurns(
354
+ type: string,
355
+ explicit?: number,
356
+ ): number | undefined {
357
+ return normalizeMaxTurns(
358
+ explicit ?? getAgentConfig(type)?.maxTurns ?? defaultMaxTurns,
359
+ )
360
+ }
361
+
352
362
  /** Additional turns allowed after the soft limit steer message. */
353
363
  let graceTurns = 5
354
364
 
@@ -442,11 +452,7 @@ export interface RunOptions {
442
452
  * Lets callers maintain a lifetime accumulator that survives compaction
443
453
  * (which replaces session.state.messages and resets stats-derived sums).
444
454
  */
445
- onAssistantUsage?: (usage: {
446
- input: number
447
- output: number
448
- cacheWrite: number
449
- }) => void
455
+ onAssistantUsage?: (usage: LifetimeUsage) => void
450
456
  /**
451
457
  * Called when the session successfully compacts. `tokensBefore` is upstream's
452
458
  * pre-compaction context size estimate. Aborted compactions don't fire.
@@ -1030,9 +1036,7 @@ export async function runAgent(
1030
1036
 
1031
1037
  // Track turns for graceful max_turns enforcement
1032
1038
  let turnCount = 0
1033
- const maxTurns = normalizeMaxTurns(
1034
- options.maxTurns ?? agentConfig?.maxTurns ?? defaultMaxTurns,
1035
- )
1039
+ const maxTurns = resolveEffectiveMaxTurns(type, options.maxTurns)
1036
1040
  let softLimitReached = false
1037
1041
  let aborted = false
1038
1042
 
@@ -1079,6 +1083,8 @@ export async function runAgent(
1079
1083
  input: u.input ?? 0,
1080
1084
  output: u.output ?? 0,
1081
1085
  cacheWrite: u.cacheWrite ?? 0,
1086
+ cacheRead: u.cacheRead ?? 0,
1087
+ cost: u.cost?.total ?? 0,
1082
1088
  })
1083
1089
  }
1084
1090
  if (event.type === "compaction_end" && !event.aborted && event.result) {
@@ -1133,11 +1139,7 @@ export async function resumeAgent(
1133
1139
  onToolActivity?: (activity: ToolActivity) => void
1134
1140
  /** Called at the end of each resumed agentic turn with the 1-based count. */
1135
1141
  onTurnEnd?: (turnCount: number) => void
1136
- onAssistantUsage?: (usage: {
1137
- input: number
1138
- output: number
1139
- cacheWrite: number
1140
- }) => void
1142
+ onAssistantUsage?: (usage: LifetimeUsage) => void
1141
1143
  onCompaction?: (info: {
1142
1144
  reason: "manual" | "threshold" | "overflow"
1143
1145
  tokensBefore: number
@@ -1180,6 +1182,8 @@ export async function resumeAgent(
1180
1182
  input: u.input ?? 0,
1181
1183
  output: u.output ?? 0,
1182
1184
  cacheWrite: u.cacheWrite ?? 0,
1185
+ cacheRead: u.cacheRead ?? 0,
1186
+ cost: u.cost?.total ?? 0,
1183
1187
  })
1184
1188
  }
1185
1189
  if (