@herbertgao/pi-extensions 2026.9.5 → 2026.9.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 (276) hide show
  1. package/README.md +5 -22
  2. package/THIRD_PARTY_NOTICES.md +0 -4
  3. package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +1 -1
  4. package/node_modules/@herbertgao/sol-pi/package.json +1 -1
  5. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +0 -5
  6. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +3 -1
  7. package/node_modules/@narumitw/pi-btw/README.md +2 -0
  8. package/node_modules/@narumitw/pi-btw/dist/index.ts +284 -365
  9. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
  10. package/node_modules/@narumitw/pi-btw/package.json +52 -53
  11. package/node_modules/@narumitw/pi-btw/src/bring-to-main.ts +494 -547
  12. package/node_modules/@narumitw/pi-btw/src/btw.ts +814 -856
  13. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +673 -674
  14. package/node_modules/@narumitw/pi-btw/src/keybindings.ts +228 -270
  15. package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +309 -318
  16. package/node_modules/@narumitw/pi-btw/src/menu.ts +416 -454
  17. package/node_modules/@narumitw/pi-btw/src/settings.ts +203 -219
  18. package/node_modules/@narumitw/pi-btw/src/side-thread.ts +173 -201
  19. package/node_modules/@narumitw/pi-btw/src/text.ts +21 -23
  20. package/node_modules/@narumitw/pi-btw/src/transcript-markdown.ts +65 -0
  21. package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +611 -662
  22. package/node_modules/pi-lens/CHANGELOG.md +239 -0
  23. package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +3 -0
  24. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +30 -4
  25. package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +2 -0
  26. package/node_modules/pi-lens/dist/clients/bash-file-access.js +26 -0
  27. package/node_modules/pi-lens/dist/clients/biome-client.js +1 -1
  28. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +403 -35
  29. package/node_modules/pi-lens/dist/clients/bootstrap.js +6 -1
  30. package/node_modules/pi-lens/dist/clients/cascade-format.js +200 -4
  31. package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +10 -2
  32. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +16 -1
  33. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +12 -1
  34. package/node_modules/pi-lens/dist/clients/dispatch/ast-grep-catalog.js +65 -0
  35. package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +28 -0
  36. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +9 -2
  37. package/node_modules/pi-lens/dist/clients/dispatch/finding-policy.js +222 -0
  38. package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +389 -13
  39. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +175 -25
  40. package/node_modules/pi-lens/dist/clients/dispatch/rule-ignores.js +62 -0
  41. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +21 -41
  42. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +6 -1
  43. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +7 -7
  44. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -12
  45. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +2 -21
  46. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +1 -1
  47. package/node_modules/pi-lens/dist/clients/dispatch/types.js +4 -1
  48. package/node_modules/pi-lens/dist/clients/disposition-publish.js +1 -0
  49. package/node_modules/pi-lens/dist/clients/effective-config.js +1 -1
  50. package/node_modules/pi-lens/dist/clients/file-kinds.js +26 -1
  51. package/node_modules/pi-lens/dist/clients/file-role.js +21 -21
  52. package/node_modules/pi-lens/dist/clients/file-utils.js +156 -10
  53. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +56 -9
  54. package/node_modules/pi-lens/dist/clients/format-service.js +39 -21
  55. package/node_modules/pi-lens/dist/clients/formatters.js +60 -13
  56. package/node_modules/pi-lens/dist/clients/generation-guard.js +2 -2
  57. package/node_modules/pi-lens/dist/clients/git-guard.js +11 -3
  58. package/node_modules/pi-lens/dist/clients/indent-retarget.js +78 -8
  59. package/node_modules/pi-lens/dist/clients/installer/index.js +333 -114
  60. package/node_modules/pi-lens/dist/clients/instance-reaper-state.js +7 -0
  61. package/node_modules/pi-lens/dist/clients/instance-reaper.js +20 -10
  62. package/node_modules/pi-lens/dist/clients/language-profile.js +23 -1
  63. package/node_modules/pi-lens/dist/clients/language-registry.js +5 -1
  64. package/node_modules/pi-lens/dist/clients/latency-logger.js +4 -1
  65. package/node_modules/pi-lens/dist/clients/lens-engine.js +12 -3
  66. package/node_modules/pi-lens/dist/clients/lens-events.js +2 -1
  67. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +79 -0
  68. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +2 -1
  69. package/node_modules/pi-lens/dist/clients/lsp/client.js +25 -21
  70. package/node_modules/pi-lens/dist/clients/lsp/config.js +2 -2
  71. package/node_modules/pi-lens/dist/clients/lsp/index.js +7 -0
  72. package/node_modules/pi-lens/dist/clients/lsp/launch.js +16 -4
  73. package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -2
  74. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +2 -1
  75. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +5 -3
  76. package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +12 -8
  77. package/node_modules/pi-lens/dist/clients/mcp/session.js +36 -4
  78. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +24 -7
  79. package/node_modules/pi-lens/dist/clients/observed-mutation.js +40 -2
  80. package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +23 -3
  81. package/node_modules/pi-lens/dist/clients/opengrep-client.js +110 -15
  82. package/node_modules/pi-lens/dist/clients/path-utils.js +123 -3
  83. package/node_modules/pi-lens/dist/clients/performance-report.js +5 -1
  84. package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +1 -1
  85. package/node_modules/pi-lens/dist/clients/pipeline.js +74 -5
  86. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +37 -5
  87. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +145 -18
  88. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +4 -1
  89. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +59 -3
  90. package/node_modules/pi-lens/dist/clients/project-lens-config.js +45 -2
  91. package/node_modules/pi-lens/dist/clients/read-guard.js +70 -11
  92. package/node_modules/pi-lens/dist/clients/resource-sampler.js +147 -9
  93. package/node_modules/pi-lens/dist/clients/ruff-client.js +1 -1
  94. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +33 -5
  95. package/node_modules/pi-lens/dist/clients/runtime-context.js +6 -2
  96. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +77 -7
  97. package/node_modules/pi-lens/dist/clients/runtime-session.js +21 -2
  98. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +43 -12
  99. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +330 -85
  100. package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -17
  101. package/node_modules/pi-lens/dist/clients/safe-spawn.js +258 -5
  102. package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +6 -0
  103. package/node_modules/pi-lens/dist/clients/session-event-guard.js +50 -5
  104. package/node_modules/pi-lens/dist/clients/sg-runner.js +23 -11
  105. package/node_modules/pi-lens/dist/clients/sgconfig.js +79 -2
  106. package/node_modules/pi-lens/dist/clients/test-runner-client.js +6 -41
  107. package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +43 -0
  108. package/node_modules/pi-lens/dist/clients/tool-agreement.js +423 -0
  109. package/node_modules/pi-lens/dist/clients/tool-config.js +50 -0
  110. package/node_modules/pi-lens/dist/clients/tool-cwd.js +47 -76
  111. package/node_modules/pi-lens/dist/clients/tool-policy.js +163 -7
  112. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +120 -0
  113. package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +127 -189
  114. package/node_modules/pi-lens/dist/clients/widget-state.js +98 -0
  115. package/node_modules/pi-lens/dist/clients/word-index.js +5 -2
  116. package/node_modules/pi-lens/dist/clients/write-ordering-guard.js +7 -0
  117. package/node_modules/pi-lens/dist/index.js +27416 -24153
  118. package/node_modules/pi-lens/dist/mcp/server.js +5 -2
  119. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +7 -1
  120. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +168 -53
  121. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +244 -72
  122. package/node_modules/pi-lens/docs/audit1.md +5 -5
  123. package/node_modules/pi-lens/docs/dependencies.md +11 -0
  124. package/node_modules/pi-lens/docs/dispositions.md +52 -0
  125. package/node_modules/pi-lens/docs/environment-variables.md +2 -2
  126. package/node_modules/pi-lens/docs/features.md +4 -4
  127. package/node_modules/pi-lens/docs/globalconfig.md +3 -1
  128. package/node_modules/pi-lens/docs/language-coverage.md +1 -0
  129. package/node_modules/pi-lens/docs/pi-lens-fixer.md +53 -94
  130. package/node_modules/pi-lens/docs/pi-lens-investigator.md +43 -38
  131. package/node_modules/pi-lens/docs/pi-lens-retro.md +97 -0
  132. package/node_modules/pi-lens/docs/pi-lens-reviewer.md +53 -66
  133. package/node_modules/pi-lens/docs/release-qa-baseline.md +22 -0
  134. package/node_modules/pi-lens/docs/settings.md +7 -4
  135. package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +1 -1
  136. package/node_modules/pi-lens/docs/usage.md +2 -0
  137. package/node_modules/pi-lens/package.json +1 -1
  138. package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +24 -12
  139. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +40 -0
  140. package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +15 -0
  141. package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +7 -0
  142. package/package.json +6 -17
  143. package/examples/pi-footer.json +0 -275
  144. package/node_modules/@czottmann/pi-automode/CHANGELOG.md +0 -70
  145. package/node_modules/@czottmann/pi-automode/LICENSE.md +0 -21
  146. package/node_modules/@czottmann/pi-automode/README.md +0 -215
  147. package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +0 -39
  148. package/node_modules/@czottmann/pi-automode/docs/adr/ADR-001-permission-precedence-and-trust-boundaries.md +0 -46
  149. package/node_modules/@czottmann/pi-automode/docs/adr/ADR-002-global-config-in-extension-data-directory.md +0 -60
  150. package/node_modules/@czottmann/pi-automode/docs/adr/INDEX.md +0 -6
  151. package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +0 -428
  152. package/node_modules/@czottmann/pi-automode/docs/configuration.md +0 -171
  153. package/node_modules/@czottmann/pi-automode/docs/defaults.md +0 -178
  154. package/node_modules/@czottmann/pi-automode/docs/diagnostics.md +0 -90
  155. package/node_modules/@czottmann/pi-automode/docs/observability-logging.md +0 -160
  156. package/node_modules/@czottmann/pi-automode/examples/automode.local.json +0 -44
  157. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/bash.ts +0 -692
  158. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +0 -852
  159. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +0 -904
  160. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +0 -228
  161. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +0 -954
  162. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +0 -429
  163. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/log.ts +0 -173
  164. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/model-selector.ts +0 -113
  165. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/model.ts +0 -13
  166. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +0 -297
  167. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +0 -623
  168. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/state.ts +0 -102
  169. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/transcript.ts +0 -236
  170. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/types.ts +0 -205
  171. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/utils.ts +0 -54
  172. package/node_modules/@czottmann/pi-automode/extensions/auto-mode.ts +0 -26
  173. package/node_modules/@czottmann/pi-automode/package.json +0 -61
  174. package/node_modules/@czottmann/pi-automode/skills/automode-diagnostics/SKILL.md +0 -63
  175. package/node_modules/@luxusai/pi-hindsight/CHANGELOG.md +0 -376
  176. package/node_modules/@luxusai/pi-hindsight/README.md +0 -92
  177. package/node_modules/@luxusai/pi-hindsight/docs/adr/001-memory-lifecycle-and-scope.md +0 -56
  178. package/node_modules/@luxusai/pi-hindsight/docs/adr/002-explicit-routing-strategy-seam.md +0 -169
  179. package/node_modules/@luxusai/pi-hindsight/docs/adr/003-tui-memory-mode-vocabulary.md +0 -107
  180. package/node_modules/@luxusai/pi-hindsight/docs/adr/004-lifeos-dual-bank-design.md +0 -89
  181. package/node_modules/@luxusai/pi-hindsight/docs/adr/005-domain-banks-and-agent-first-surface.md +0 -189
  182. package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark.webp +0 -0
  183. package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark@2x.webp +0 -0
  184. package/node_modules/@luxusai/pi-hindsight/docs/coding-memory-evaluation.md +0 -54
  185. package/node_modules/@luxusai/pi-hindsight/docs/compatibility.md +0 -75
  186. package/node_modules/@luxusai/pi-hindsight/docs/hindsight-core-functions.md +0 -300
  187. package/node_modules/@luxusai/pi-hindsight/docs/mission-and-mental-model-quality.md +0 -158
  188. package/node_modules/@luxusai/pi-hindsight/docs/next-opt-out-design.md +0 -164
  189. package/node_modules/@luxusai/pi-hindsight/docs/risky-memory-modes.md +0 -139
  190. package/node_modules/@luxusai/pi-hindsight/docs/starter-mental-model-suggestions.md +0 -74
  191. package/node_modules/@luxusai/pi-hindsight/docs/surface-reference.md +0 -261
  192. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-operations.ts +0 -151
  193. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-selection.ts +0 -18
  194. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-settings-presenter.ts +0 -46
  195. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-templates.ts +0 -383
  196. package/node_modules/@luxusai/pi-hindsight/extensions/banks/banking.ts +0 -240
  197. package/node_modules/@luxusai/pi-hindsight/extensions/banks/knowledge-page-seed.ts +0 -176
  198. package/node_modules/@luxusai/pi-hindsight/extensions/banks/retain-strategies.ts +0 -178
  199. package/node_modules/@luxusai/pi-hindsight/extensions/client/client-retry.ts +0 -41
  200. package/node_modules/@luxusai/pi-hindsight/extensions/client/client.ts +0 -386
  201. package/node_modules/@luxusai/pi-hindsight/extensions/client/fetch-compat.ts +0 -39
  202. package/node_modules/@luxusai/pi-hindsight/extensions/client/timeout.ts +0 -34
  203. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-defaults.ts +0 -140
  204. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-model.ts +0 -61
  205. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-registry.ts +0 -925
  206. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-field-paths.ts +0 -247
  207. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-normalize.ts +0 -547
  208. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-writer.ts +0 -480
  209. package/node_modules/@luxusai/pi-hindsight/extensions/config/config.ts +0 -182
  210. package/node_modules/@luxusai/pi-hindsight/extensions/config/setup-gate.ts +0 -86
  211. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-execute.ts +0 -1010
  212. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-parse.ts +0 -175
  213. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-plan.ts +0 -425
  214. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-presentation.ts +0 -210
  215. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-sessions.ts +0 -817
  216. package/node_modules/@luxusai/pi-hindsight/extensions/index.ts +0 -25
  217. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/git-seed.ts +0 -319
  218. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-recall.ts +0 -196
  219. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-retain.ts +0 -189
  220. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-runtime.ts +0 -65
  221. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle.ts +0 -260
  222. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/mental-models.ts +0 -244
  223. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/observation-scopes.ts +0 -59
  224. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-cleanup.ts +0 -82
  225. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-visibility.ts +0 -45
  226. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall.ts +0 -331
  227. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-cursor.ts +0 -354
  228. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-job-builder.ts +0 -66
  229. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-receipts.ts +0 -132
  230. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain.ts +0 -228
  231. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-bank-template-operations.ts +0 -74
  232. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-config-operations.ts +0 -16
  233. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-control-operations.ts +0 -648
  234. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-diagnostics-operations.ts +0 -105
  235. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-identity.ts +0 -68
  236. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-service.ts +0 -71
  237. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-types.ts +0 -13
  238. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-recall-operations.ts +0 -162
  239. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-retain-operations.ts +0 -131
  240. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-scope.ts +0 -104
  241. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-session-operations.ts +0 -37
  242. package/node_modules/@luxusai/pi-hindsight/extensions/operations/operation-catalog.ts +0 -893
  243. package/node_modules/@luxusai/pi-hindsight/extensions/operations/reflect-presenter.ts +0 -35
  244. package/node_modules/@luxusai/pi-hindsight/extensions/operations/scope-migrate.ts +0 -177
  245. package/node_modules/@luxusai/pi-hindsight/extensions/operations/tools.ts +0 -7
  246. package/node_modules/@luxusai/pi-hindsight/extensions/queue/flush-presenter.ts +0 -21
  247. package/node_modules/@luxusai/pi-hindsight/extensions/queue/jsonl-queue-store.ts +0 -112
  248. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-delivery.ts +0 -111
  249. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-lock.ts +0 -214
  250. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-operations.ts +0 -70
  251. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue.ts +0 -392
  252. package/node_modules/@luxusai/pi-hindsight/extensions/tui/bank-template-presentation.ts +0 -45
  253. package/node_modules/@luxusai/pi-hindsight/extensions/tui/commands.ts +0 -9
  254. package/node_modules/@luxusai/pi-hindsight/extensions/tui/guided-setup.ts +0 -860
  255. package/node_modules/@luxusai/pi-hindsight/extensions/tui/prefill-input.ts +0 -105
  256. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-flow.ts +0 -189
  257. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-server-probe.ts +0 -299
  258. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-actions.ts +0 -201
  259. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-facts.ts +0 -47
  260. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-render.ts +0 -239
  261. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-types.ts +0 -50
  262. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui.ts +0 -259
  263. package/node_modules/@luxusai/pi-hindsight/extensions/tui/tool-presenters.ts +0 -77
  264. package/node_modules/@luxusai/pi-hindsight/extensions/types.ts +0 -534
  265. package/node_modules/@luxusai/pi-hindsight/extensions/utils/diagnostics.ts +0 -319
  266. package/node_modules/@luxusai/pi-hindsight/extensions/utils/messages.ts +0 -325
  267. package/node_modules/@luxusai/pi-hindsight/extensions/utils/sanitize.ts +0 -42
  268. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-memory-meta.ts +0 -244
  269. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-operations.ts +0 -56
  270. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session.ts +0 -50
  271. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-fields.ts +0 -167
  272. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-health.ts +0 -207
  273. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status.ts +0 -120
  274. package/node_modules/@luxusai/pi-hindsight/extensions/version.ts +0 -8
  275. package/node_modules/@luxusai/pi-hindsight/package.json +0 -118
  276. package/node_modules/@luxusai/pi-hindsight/skills/hindsight-memory-doctor/SKILL.md +0 -75
@@ -1,390 +1,381 @@
1
1
  import {
2
- copyToClipboard,
3
- type ExtensionAPI,
4
- type ExtensionCommandContext,
5
- type SessionEntry,
6
- type SessionTreeNode,
7
- TreeSelectorComponent,
2
+ copyToClipboard,
3
+ type ExtensionAPI,
4
+ type ExtensionCommandContext,
5
+ type SessionEntry,
6
+ type SessionTreeNode,
7
+ TreeSelectorComponent,
8
8
  } from "@earendil-works/pi-coding-agent";
9
9
  import { type Component, type Focusable, Key, matchesKey } from "@earendil-works/pi-tui";
10
10
  import { showBtwCustomPreservingEditor } from "./menu.js";
11
11
  import { sanitizeSingleLine } from "./text.js";
12
12
 
13
- export type MainEntryPickResult =
14
- | { kind: "selected"; entryId: string }
15
- | { kind: "back" }
16
- | { kind: "closed" };
13
+ export type MainEntryPickResult = { kind: "selected"; entryId: string } | { kind: "back" } | { kind: "closed" };
17
14
 
18
15
  export interface MainThreadTreeSelector extends Component, Focusable {
19
- onCopy?: (text: string | undefined) => void;
20
- setViewLabel?(entryId: string, label: string | undefined, labelTimestamp?: string): void;
21
- dispose?(): void;
16
+ onCopy?: (text: string | undefined) => void;
17
+ setViewLabel?(entryId: string, label: string | undefined, labelTimestamp?: string): void;
18
+ dispose?(): void;
22
19
  }
23
20
 
24
21
  export interface MainThreadTreeSelectorOptions {
25
- tree: SessionTreeNode[];
26
- currentLeafId: string | null;
27
- terminalRows: number;
28
- onSelect: (entryId: string) => void;
29
- onCancel: () => void;
30
- onCopy: (entryId: string | undefined, displayText: string | undefined) => void;
31
- onLabelChange: (entryId: string, label: string | undefined) => void;
22
+ tree: SessionTreeNode[];
23
+ currentLeafId: string | null;
24
+ terminalRows: number;
25
+ onSelect: (entryId: string) => void;
26
+ onCancel: () => void;
27
+ onCopy: (entryId: string | undefined, displayText: string | undefined) => void;
28
+ onLabelChange: (entryId: string, label: string | undefined) => void;
32
29
  }
33
30
 
34
31
  export interface MainThreadTreePickerDependencies {
35
- createSelector?: (options: MainThreadTreeSelectorOptions) => MainThreadTreeSelector;
36
- copyToClipboard?: (text: string, signal: AbortSignal) => Promise<void>;
32
+ createSelector?: (options: MainThreadTreeSelectorOptions) => MainThreadTreeSelector;
33
+ copyToClipboard?: (text: string, signal: AbortSignal) => Promise<void>;
37
34
  }
38
35
 
39
36
  class MainThreadTreePickerComponent implements Component, Focusable {
40
- constructor(
41
- private readonly selector: MainThreadTreeSelector,
42
- private readonly onClose: () => void,
43
- ) {}
37
+ constructor(
38
+ private readonly selector: MainThreadTreeSelector,
39
+ private readonly onClose: () => void,
40
+ ) {}
44
41
 
45
- get focused(): boolean {
46
- return this.selector.focused;
47
- }
42
+ get focused(): boolean {
43
+ return this.selector.focused;
44
+ }
48
45
 
49
- set focused(value: boolean) {
50
- this.selector.focused = value;
51
- }
46
+ set focused(value: boolean) {
47
+ this.selector.focused = value;
48
+ }
52
49
 
53
- get wantsKeyRelease(): boolean | undefined {
54
- return this.selector.wantsKeyRelease;
55
- }
50
+ get wantsKeyRelease(): boolean | undefined {
51
+ return this.selector.wantsKeyRelease;
52
+ }
56
53
 
57
- render(width: number): string[] {
58
- return this.selector.render(width);
59
- }
54
+ render(width: number): string[] {
55
+ return this.selector.render(width);
56
+ }
60
57
 
61
- handleInput(data: string): void {
62
- if (matchesKey(data, Key.ctrl("c"))) {
63
- this.onClose();
64
- return;
65
- }
66
- this.selector.handleInput?.(data);
67
- }
58
+ handleInput(data: string): void {
59
+ if (matchesKey(data, Key.ctrl("c"))) {
60
+ this.onClose();
61
+ return;
62
+ }
63
+ this.selector.handleInput?.(data);
64
+ }
68
65
 
69
- invalidate(): void {
70
- this.selector.invalidate();
71
- }
66
+ invalidate(): void {
67
+ this.selector.invalidate();
68
+ }
72
69
 
73
- dispose(): void {
74
- this.selector.dispose?.();
75
- this.onClose();
76
- }
70
+ dispose(): void {
71
+ this.selector.dispose?.();
72
+ this.onClose();
73
+ }
77
74
  }
78
75
 
79
76
  export async function pickMainEntry(
80
- pi: ExtensionAPI,
81
- ctx: ExtensionCommandContext,
82
- dependencies: MainThreadTreePickerDependencies = {},
77
+ pi: ExtensionAPI,
78
+ ctx: ExtensionCommandContext,
79
+ dependencies: MainThreadTreePickerDependencies = {},
83
80
  ): Promise<MainEntryPickResult> {
84
- let rawTree: SessionTreeNode[];
85
- let currentLeafId: string | null;
86
- try {
87
- rawTree = ctx.sessionManager.getTree();
88
- currentLeafId = ctx.sessionManager.getLeafId();
89
- } catch {
90
- return { kind: "closed" };
91
- }
81
+ let rawTree: SessionTreeNode[];
82
+ let currentLeafId: string | null;
83
+ try {
84
+ rawTree = ctx.sessionManager.getTree();
85
+ currentLeafId = ctx.sessionManager.getLeafId();
86
+ } catch {
87
+ return { kind: "closed" };
88
+ }
92
89
 
93
- if (rawTree.length === 0) {
94
- notifySafely(ctx, "No main-thread entries are available", "warning");
95
- return { kind: "back" };
96
- }
90
+ if (rawTree.length === 0) {
91
+ notifySafely(ctx, "No main-thread entries are available", "warning");
92
+ return { kind: "back" };
93
+ }
97
94
 
98
- const tree = sanitizeTreeForDisplay(rawTree);
99
- const rawCopyText = collectRawCopyText(rawTree);
100
- const savedLabels = collectSavedLabels(rawTree);
101
- const createSelector = dependencies.createSelector ?? createNativeTreeSelector;
102
- const copy = dependencies.copyToClipboard ?? copyText;
103
- const copyControllers = new Set<AbortController>();
104
- const copyTasks = new Set<Promise<void>>();
105
- const abortCopies = () => {
106
- for (const controller of copyControllers) {
107
- controller.abort(new Error("The main-thread tree picker closed"));
108
- }
109
- };
110
- const result = await showBtwCustomPreservingEditor<MainEntryPickResult>(
111
- ctx,
112
- (tui, _theme, _keybindings, done) => {
113
- let settled = false;
114
- let selector: MainThreadTreeSelector | undefined;
115
- const finish = (value: MainEntryPickResult) => {
116
- if (settled) return;
117
- settled = true;
118
- abortCopies();
119
- done(value);
120
- };
121
- const onCopy = (entryId: string | undefined, displayText: string | undefined) => {
122
- if (settled) return;
123
- const text = entryId ? rawCopyText.get(entryId) : displayText;
124
- if (!text) {
125
- notifySafely(ctx, "Selected entry has no text to copy", "warning");
126
- return;
127
- }
128
- const controller = new AbortController();
129
- copyControllers.add(controller);
130
- let operation: Promise<void>;
131
- try {
132
- operation = copy(text, controller.signal);
133
- } catch (error: unknown) {
134
- operation = Promise.reject(error);
135
- }
136
- let task!: Promise<void>;
137
- task = operation
138
- .then(() => {
139
- if (!settled) notifySafely(ctx, "Copied selected message", "info");
140
- })
141
- .catch((error: unknown) => {
142
- if (!settled && !controller.signal.aborted) {
143
- notifySafely(ctx, `Could not copy selected message: ${formatError(error)}`, "error");
144
- }
145
- })
146
- .finally(() => {
147
- copyControllers.delete(controller);
148
- copyTasks.delete(task);
149
- });
150
- copyTasks.add(task);
151
- };
152
- const restoreLabel = (entryId: string) => {
153
- const previous = savedLabels.get(entryId);
154
- selector?.setViewLabel?.(entryId, previous?.label, previous?.labelTimestamp);
155
- tui.requestRender();
156
- };
157
- const onLabelChange = (entryId: string, label: string | undefined) => {
158
- if (settled) return;
159
- try {
160
- if (!ctx.sessionManager.getEntry(entryId)) {
161
- restoreLabel(entryId);
162
- notifySafely(ctx, "The selected main-thread entry is no longer available", "warning");
163
- return;
164
- }
165
- const persistedLabel = label === undefined ? undefined : sanitizeSingleLine(label);
166
- pi.setLabel(entryId, persistedLabel);
167
- savedLabels.set(entryId, { label: persistedLabel });
168
- selector?.setViewLabel?.(entryId, persistedLabel);
169
- tui.requestRender();
170
- } catch (error: unknown) {
171
- restoreLabel(entryId);
172
- notifySafely(ctx, `Could not update tree label: ${formatError(error)}`, "error");
173
- }
174
- };
175
- selector = createSelector({
176
- tree,
177
- currentLeafId,
178
- terminalRows: tui.terminal.rows,
179
- onSelect: (entryId) => finish({ kind: "selected", entryId }),
180
- onCancel: () => finish({ kind: "back" }),
181
- onCopy,
182
- onLabelChange,
183
- });
184
- return new MainThreadTreePickerComponent(selector, () => finish({ kind: "closed" }));
185
- },
186
- );
187
- abortCopies();
188
- await Promise.allSettled([...copyTasks]);
95
+ const tree = sanitizeTreeForDisplay(rawTree);
96
+ const rawCopyText = collectRawCopyText(rawTree);
97
+ const savedLabels = collectSavedLabels(rawTree);
98
+ const createSelector = dependencies.createSelector ?? createNativeTreeSelector;
99
+ const copy = dependencies.copyToClipboard ?? copyText;
100
+ const copyControllers = new Set<AbortController>();
101
+ const copyTasks = new Set<Promise<void>>();
102
+ const abortCopies = () => {
103
+ for (const controller of copyControllers) {
104
+ controller.abort(new Error("The main-thread tree picker closed"));
105
+ }
106
+ };
107
+ const result = await showBtwCustomPreservingEditor<MainEntryPickResult>(ctx, (tui, _theme, _keybindings, done) => {
108
+ let settled = false;
109
+ let selector: MainThreadTreeSelector | undefined;
110
+ const finish = (value: MainEntryPickResult) => {
111
+ if (settled) return;
112
+ settled = true;
113
+ abortCopies();
114
+ done(value);
115
+ };
116
+ const onCopy = (entryId: string | undefined, displayText: string | undefined) => {
117
+ if (settled) return;
118
+ const text = entryId ? rawCopyText.get(entryId) : displayText;
119
+ if (!text) {
120
+ notifySafely(ctx, "Selected entry has no text to copy", "warning");
121
+ return;
122
+ }
123
+ const controller = new AbortController();
124
+ copyControllers.add(controller);
125
+ let operation: Promise<void>;
126
+ try {
127
+ operation = copy(text, controller.signal);
128
+ } catch (error: unknown) {
129
+ operation = Promise.reject(error);
130
+ }
131
+ let task!: Promise<void>;
132
+ task = operation
133
+ .then(() => {
134
+ if (!settled) notifySafely(ctx, "Copied selected message", "info");
135
+ })
136
+ .catch((error: unknown) => {
137
+ if (!settled && !controller.signal.aborted) {
138
+ notifySafely(ctx, `Could not copy selected message: ${formatError(error)}`, "error");
139
+ }
140
+ })
141
+ .finally(() => {
142
+ copyControllers.delete(controller);
143
+ copyTasks.delete(task);
144
+ });
145
+ copyTasks.add(task);
146
+ };
147
+ const restoreLabel = (entryId: string) => {
148
+ const previous = savedLabels.get(entryId);
149
+ selector?.setViewLabel?.(entryId, previous?.label, previous?.labelTimestamp);
150
+ tui.requestRender();
151
+ };
152
+ const onLabelChange = (entryId: string, label: string | undefined) => {
153
+ if (settled) return;
154
+ try {
155
+ if (!ctx.sessionManager.getEntry(entryId)) {
156
+ restoreLabel(entryId);
157
+ notifySafely(ctx, "The selected main-thread entry is no longer available", "warning");
158
+ return;
159
+ }
160
+ const persistedLabel = label === undefined ? undefined : sanitizeSingleLine(label);
161
+ pi.setLabel(entryId, persistedLabel);
162
+ savedLabels.set(entryId, { label: persistedLabel });
163
+ selector?.setViewLabel?.(entryId, persistedLabel);
164
+ tui.requestRender();
165
+ } catch (error: unknown) {
166
+ restoreLabel(entryId);
167
+ notifySafely(ctx, `Could not update tree label: ${formatError(error)}`, "error");
168
+ }
169
+ };
170
+ selector = createSelector({
171
+ tree,
172
+ currentLeafId,
173
+ terminalRows: tui.terminal.rows,
174
+ onSelect: (entryId) => finish({ kind: "selected", entryId }),
175
+ onCancel: () => finish({ kind: "back" }),
176
+ onCopy,
177
+ onLabelChange,
178
+ });
179
+ return new MainThreadTreePickerComponent(selector, () => finish({ kind: "closed" }));
180
+ });
181
+ abortCopies();
182
+ await Promise.allSettled([...copyTasks]);
189
183
 
190
- return result ?? { kind: "closed" };
184
+ return result ?? { kind: "closed" };
191
185
  }
192
186
 
193
187
  function createNativeTreeSelector(options: MainThreadTreeSelectorOptions): MainThreadTreeSelector {
194
- const selector = new TreeSelectorComponent(
195
- options.tree,
196
- options.currentLeafId,
197
- options.terminalRows,
198
- options.onSelect,
199
- options.onCancel,
200
- options.onLabelChange,
201
- );
202
- selector.onCopy = (displayText) =>
203
- options.onCopy(selector.getTreeList().getSelectedNode()?.entry.id, displayText);
204
- const result = selector as MainThreadTreeSelector;
205
- result.setViewLabel = (entryId, label, labelTimestamp) =>
206
- selector.getTreeList().updateNodeLabel(entryId, label, labelTimestamp);
207
- return result;
188
+ const selector = new TreeSelectorComponent(
189
+ options.tree,
190
+ options.currentLeafId,
191
+ options.terminalRows,
192
+ options.onSelect,
193
+ options.onCancel,
194
+ options.onLabelChange,
195
+ );
196
+ selector.onCopy = (displayText) => options.onCopy(selector.getTreeList().getSelectedNode()?.entry.id, displayText);
197
+ const result = selector as MainThreadTreeSelector;
198
+ result.setViewLabel = (entryId, label, labelTimestamp) =>
199
+ selector.getTreeList().updateNodeLabel(entryId, label, labelTimestamp);
200
+ return result;
208
201
  }
209
202
 
210
203
  function sanitizeTreeForDisplay(tree: readonly SessionTreeNode[]): SessionTreeNode[] {
211
- return tree.map((node) => {
212
- const result: SessionTreeNode = {
213
- entry: sanitizeEntryForDisplay(node.entry),
214
- children: sanitizeTreeForDisplay(node.children),
215
- };
216
- if (node.label !== undefined) result.label = sanitizeSingleLine(node.label);
217
- if (node.labelTimestamp !== undefined) {
218
- result.labelTimestamp = sanitizeSingleLine(node.labelTimestamp);
219
- }
220
- return result;
221
- });
204
+ return tree.map((node) => {
205
+ const result: SessionTreeNode = {
206
+ entry: sanitizeEntryForDisplay(node.entry),
207
+ children: sanitizeTreeForDisplay(node.children),
208
+ };
209
+ if (node.label !== undefined) result.label = sanitizeSingleLine(node.label);
210
+ if (node.labelTimestamp !== undefined) {
211
+ result.labelTimestamp = sanitizeSingleLine(node.labelTimestamp);
212
+ }
213
+ return result;
214
+ });
222
215
  }
223
216
 
224
217
  function sanitizeEntryForDisplay(entry: SessionEntry): SessionEntry {
225
- switch (entry.type) {
226
- case "message": {
227
- const message = { ...entry.message } as Record<string, unknown>;
228
- if ("content" in entry.message)
229
- message.content = sanitizeDisplayContent(entry.message.content);
230
- for (const key of ["role", "errorMessage", "command", "toolName"] as const) {
231
- const value = message[key];
232
- if (typeof value === "string") message[key] = sanitizeSingleLine(value);
233
- }
234
- return { ...entry, message } as unknown as SessionEntry;
235
- }
236
- case "custom_message":
237
- return {
238
- ...entry,
239
- customType: sanitizeSingleLine(entry.customType),
240
- content: sanitizeDisplayContent(entry.content) as typeof entry.content,
241
- };
242
- case "compaction":
243
- return { ...entry, summary: sanitizeSingleLine(entry.summary) };
244
- case "branch_summary":
245
- return { ...entry, summary: sanitizeSingleLine(entry.summary) };
246
- case "model_change":
247
- return {
248
- ...entry,
249
- provider: sanitizeSingleLine(entry.provider),
250
- modelId: sanitizeSingleLine(entry.modelId),
251
- };
252
- case "thinking_level_change":
253
- return { ...entry, thinkingLevel: sanitizeSingleLine(entry.thinkingLevel) };
254
- case "custom":
255
- return { ...entry, customType: sanitizeSingleLine(entry.customType) };
256
- case "label":
257
- return {
258
- ...entry,
259
- label: entry.label === undefined ? undefined : sanitizeSingleLine(entry.label),
260
- };
261
- case "session_info":
262
- return {
263
- ...entry,
264
- name: entry.name === undefined ? undefined : sanitizeSingleLine(entry.name),
265
- };
266
- }
218
+ switch (entry.type) {
219
+ case "message": {
220
+ const message = { ...entry.message } as Record<string, unknown>;
221
+ if ("content" in entry.message) message.content = sanitizeDisplayContent(entry.message.content);
222
+ for (const key of ["role", "errorMessage", "command", "toolName"] as const) {
223
+ const value = message[key];
224
+ if (typeof value === "string") message[key] = sanitizeSingleLine(value);
225
+ }
226
+ return { ...entry, message } as unknown as SessionEntry;
227
+ }
228
+ case "custom_message":
229
+ return {
230
+ ...entry,
231
+ customType: sanitizeSingleLine(entry.customType),
232
+ content: sanitizeDisplayContent(entry.content) as typeof entry.content,
233
+ };
234
+ case "compaction":
235
+ return { ...entry, summary: sanitizeSingleLine(entry.summary) };
236
+ case "branch_summary":
237
+ return { ...entry, summary: sanitizeSingleLine(entry.summary) };
238
+ case "model_change":
239
+ return {
240
+ ...entry,
241
+ provider: sanitizeSingleLine(entry.provider),
242
+ modelId: sanitizeSingleLine(entry.modelId),
243
+ };
244
+ case "thinking_level_change":
245
+ return { ...entry, thinkingLevel: sanitizeSingleLine(entry.thinkingLevel) };
246
+ case "custom":
247
+ return { ...entry, customType: sanitizeSingleLine(entry.customType) };
248
+ case "label":
249
+ return {
250
+ ...entry,
251
+ label: entry.label === undefined ? undefined : sanitizeSingleLine(entry.label),
252
+ };
253
+ case "session_info":
254
+ return {
255
+ ...entry,
256
+ name: entry.name === undefined ? undefined : sanitizeSingleLine(entry.name),
257
+ };
258
+ }
267
259
  }
268
260
 
269
261
  function sanitizeDisplayContent(content: unknown): unknown {
270
- if (typeof content === "string") return sanitizeSingleLine(content);
271
- if (!Array.isArray(content)) return content;
272
- return content.map((block) => {
273
- if (block === null || typeof block !== "object" || !("type" in block)) return block;
274
- if (block.type === "text" && "text" in block && typeof block.text === "string") {
275
- return { ...block, text: sanitizeSingleLine(block.text) };
276
- }
277
- if (block.type === "toolCall") {
278
- const copy = { ...block } as Record<string, unknown>;
279
- if (typeof copy.name === "string") copy.name = sanitizeSingleLine(copy.name);
280
- copy.arguments = sanitizeToolArguments(copy.arguments, new WeakMap());
281
- return copy;
282
- }
283
- return block;
284
- });
262
+ if (typeof content === "string") return sanitizeSingleLine(content);
263
+ if (!Array.isArray(content)) return content;
264
+ return content.map((block) => {
265
+ if (block === null || typeof block !== "object" || !("type" in block)) return block;
266
+ if (block.type === "text" && "text" in block && typeof block.text === "string") {
267
+ return { ...block, text: sanitizeSingleLine(block.text) };
268
+ }
269
+ if (block.type === "toolCall") {
270
+ const copy = { ...block } as Record<string, unknown>;
271
+ if (typeof copy.name === "string") copy.name = sanitizeSingleLine(copy.name);
272
+ copy.arguments = sanitizeToolArguments(copy.arguments, new WeakMap());
273
+ return copy;
274
+ }
275
+ return block;
276
+ });
285
277
  }
286
278
 
287
279
  function sanitizeToolArguments(value: unknown, seen: WeakMap<object, unknown>): unknown {
288
- if (typeof value === "string") return sanitizeSingleLine(value);
289
- if (value === null || typeof value !== "object") return value;
290
- const existing = seen.get(value);
291
- if (existing !== undefined) return existing;
292
- if (Array.isArray(value)) {
293
- const result: unknown[] = [];
294
- seen.set(value, result);
295
- for (const item of value) result.push(sanitizeToolArguments(item, seen));
296
- return result;
297
- }
298
- const result: Record<string, unknown> = {};
299
- seen.set(value, result);
300
- for (const [key, item] of Object.entries(value)) {
301
- result[key] = sanitizeToolArguments(item, seen);
302
- }
303
- return result;
280
+ if (typeof value === "string") return sanitizeSingleLine(value);
281
+ if (value === null || typeof value !== "object") return value;
282
+ const existing = seen.get(value);
283
+ if (existing !== undefined) return existing;
284
+ if (Array.isArray(value)) {
285
+ const result: unknown[] = [];
286
+ seen.set(value, result);
287
+ for (const item of value) result.push(sanitizeToolArguments(item, seen));
288
+ return result;
289
+ }
290
+ const result: Record<string, unknown> = {};
291
+ seen.set(value, result);
292
+ for (const [key, item] of Object.entries(value)) {
293
+ result[key] = sanitizeToolArguments(item, seen);
294
+ }
295
+ return result;
304
296
  }
305
297
 
306
298
  function collectRawCopyText(tree: readonly SessionTreeNode[]): Map<string, string> {
307
- const result = new Map<string, string>();
308
- const visit = (nodes: readonly SessionTreeNode[]) => {
309
- for (const node of nodes) {
310
- const text = getRawCopyText(node.entry);
311
- if (text !== undefined) result.set(node.entry.id, text);
312
- visit(node.children);
313
- }
314
- };
315
- visit(tree);
316
- return result;
299
+ const result = new Map<string, string>();
300
+ const visit = (nodes: readonly SessionTreeNode[]) => {
301
+ for (const node of nodes) {
302
+ const text = getRawCopyText(node.entry);
303
+ if (text !== undefined) result.set(node.entry.id, text);
304
+ visit(node.children);
305
+ }
306
+ };
307
+ visit(tree);
308
+ return result;
317
309
  }
318
310
 
319
311
  function getRawCopyText(entry: SessionEntry): string | undefined {
320
- let text: string | undefined;
321
- if (entry.type === "message") {
322
- if (entry.message.role === "bashExecution") text = entry.message.command;
323
- else if ("content" in entry.message) {
324
- text = extractRawText(entry.message.content);
325
- if (!text && entry.message.role === "assistant") text = entry.message.errorMessage;
326
- }
327
- } else if (entry.type === "custom_message") text = extractRawText(entry.content);
328
- else if (entry.type === "compaction" || entry.type === "branch_summary") text = entry.summary;
329
- return text?.trim() ? text : undefined;
312
+ let text: string | undefined;
313
+ if (entry.type === "message") {
314
+ if (entry.message.role === "bashExecution") text = entry.message.command;
315
+ else if ("content" in entry.message) {
316
+ text = extractRawText(entry.message.content);
317
+ if (!text && entry.message.role === "assistant") text = entry.message.errorMessage;
318
+ }
319
+ } else if (entry.type === "custom_message") text = extractRawText(entry.content);
320
+ else if (entry.type === "compaction" || entry.type === "branch_summary") text = entry.summary;
321
+ return text?.trim() ? text : undefined;
330
322
  }
331
323
 
332
324
  function extractRawText(content: unknown): string {
333
- if (typeof content === "string") return content;
334
- if (!Array.isArray(content)) return "";
335
- return content
336
- .filter(
337
- (block): block is { type: "text"; text: string } =>
338
- block !== null &&
339
- typeof block === "object" &&
340
- "type" in block &&
341
- block.type === "text" &&
342
- "text" in block &&
343
- typeof block.text === "string",
344
- )
345
- .map((block) => block.text)
346
- .join("");
325
+ if (typeof content === "string") return content;
326
+ if (!Array.isArray(content)) return "";
327
+ return content
328
+ .filter(
329
+ (block): block is { type: "text"; text: string } =>
330
+ block !== null &&
331
+ typeof block === "object" &&
332
+ "type" in block &&
333
+ block.type === "text" &&
334
+ "text" in block &&
335
+ typeof block.text === "string",
336
+ )
337
+ .map((block) => block.text)
338
+ .join("");
347
339
  }
348
340
 
349
341
  interface SavedLabel {
350
- label: string | undefined;
351
- labelTimestamp?: string;
342
+ label: string | undefined;
343
+ labelTimestamp?: string;
352
344
  }
353
345
 
354
346
  function collectSavedLabels(tree: readonly SessionTreeNode[]): Map<string, SavedLabel> {
355
- const result = new Map<string, SavedLabel>();
356
- const visit = (nodes: readonly SessionTreeNode[]) => {
357
- for (const node of nodes) {
358
- result.set(node.entry.id, {
359
- label: node.label === undefined ? undefined : sanitizeSingleLine(node.label),
360
- labelTimestamp:
361
- node.labelTimestamp === undefined ? undefined : sanitizeSingleLine(node.labelTimestamp),
362
- });
363
- visit(node.children);
364
- }
365
- };
366
- visit(tree);
367
- return result;
347
+ const result = new Map<string, SavedLabel>();
348
+ const visit = (nodes: readonly SessionTreeNode[]) => {
349
+ for (const node of nodes) {
350
+ result.set(node.entry.id, {
351
+ label: node.label === undefined ? undefined : sanitizeSingleLine(node.label),
352
+ labelTimestamp: node.labelTimestamp === undefined ? undefined : sanitizeSingleLine(node.labelTimestamp),
353
+ });
354
+ visit(node.children);
355
+ }
356
+ };
357
+ visit(tree);
358
+ return result;
368
359
  }
369
360
 
370
361
  async function copyText(text: string, signal: AbortSignal): Promise<void> {
371
- signal.throwIfAborted();
372
- await copyToClipboard(text);
373
- signal.throwIfAborted();
362
+ signal.throwIfAborted();
363
+ await copyToClipboard(text);
364
+ signal.throwIfAborted();
374
365
  }
375
366
 
376
367
  function notifySafely(
377
- ctx: ExtensionCommandContext,
378
- message: string,
379
- level: Parameters<ExtensionCommandContext["ui"]["notify"]>[1],
368
+ ctx: ExtensionCommandContext,
369
+ message: string,
370
+ level: Parameters<ExtensionCommandContext["ui"]["notify"]>[1],
380
371
  ): void {
381
- try {
382
- ctx.ui.notify(sanitizeSingleLine(message), level);
383
- } catch {
384
- // The command context may have been replaced while the selector was open.
385
- }
372
+ try {
373
+ ctx.ui.notify(sanitizeSingleLine(message), level);
374
+ } catch {
375
+ // The command context may have been replaced while the selector was open.
376
+ }
386
377
  }
387
378
 
388
379
  function formatError(error: unknown): string {
389
- return error instanceof Error ? error.message : String(error);
380
+ return error instanceof Error ? error.message : String(error);
390
381
  }