@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,692 +0,0 @@
1
- import { basename } from "node:path";
2
- import {
3
- parse,
4
- type ArithmeticExpression,
5
- type Node,
6
- type ParseError,
7
- type ParsedScript,
8
- type Redirect,
9
- type TestExpression,
10
- type Word,
11
- type WordPart,
12
- } from "unbash";
13
-
14
- export type BashAnalysisError = {
15
- message: string;
16
- pos?: number;
17
- };
18
-
19
- export type BashRedirectAnalysis = {
20
- operator: Redirect["operator"];
21
- target?: string;
22
- targetDynamic: boolean;
23
- fileDescriptor?: number;
24
- variableName?: string;
25
- heredoc: boolean;
26
- };
27
-
28
- export type EffectiveCommand = {
29
- name?: string;
30
- args: string[];
31
- argTexts: string[];
32
- argTildeExpansions: boolean[];
33
- unresolvedTransparentDispatch: boolean;
34
- };
35
-
36
- export type BashCommandAnalysis = {
37
- raw: string;
38
- text: string;
39
- name?: string;
40
- words: string[];
41
- args: string[];
42
- argTexts: string[];
43
- effectiveCommand: EffectiveCommand;
44
- redirects: BashRedirectAnalysis[];
45
- redirectTargets: string[];
46
- dynamic: boolean;
47
- dynamicName: boolean;
48
- dynamicShellScript: boolean;
49
- pos: number;
50
- end: number;
51
- };
52
-
53
- export type BashAnalysis = {
54
- source: string;
55
- commands: BashCommandAnalysis[];
56
- redirects: BashRedirectAnalysis[];
57
- redirectTargets: string[];
58
- structure: string[];
59
- allowStructureSafe: boolean;
60
- errors: BashAnalysisError[];
61
- };
62
-
63
- export type BashParser = (source: string) => ParsedScript;
64
-
65
- export const MAX_BASH_SOURCE_LENGTH = 1024 * 1024;
66
- const MAX_NESTED_SHELL_DEPTH = 16;
67
-
68
- function parseError(error: ParseError): BashAnalysisError {
69
- return { message: error.message, pos: error.pos };
70
- }
71
-
72
- function parserException(error: unknown): BashAnalysisError {
73
- return {
74
- message: `Bash parser failed: ${
75
- error instanceof Error ? error.message : String(error)
76
- }`,
77
- };
78
- }
79
-
80
- function wordParts(word: Word): WordPart[] {
81
- return word.parts ?? [];
82
- }
83
-
84
- function wordIsStatic(word: Word): boolean {
85
- const parts = wordParts(word);
86
- if (parts.length === 0) return true;
87
- return parts.every(partIsStatic);
88
- }
89
-
90
- function wordHasTildeExpansion(word: Word): boolean {
91
- if (!word.text.startsWith("~")) return false;
92
- for (const character of word.text.slice(1)) {
93
- if (character === "/") return true;
94
- if (["\\", "'", '"', "$", "`"].includes(character)) return false;
95
- }
96
- return true;
97
- }
98
-
99
- function partIsStatic(part: WordPart): boolean {
100
- switch (part.type) {
101
- case "Literal":
102
- case "SingleQuoted":
103
- case "AnsiCQuoted":
104
- return true;
105
- case "DoubleQuoted":
106
- return part.parts.every((child) => child.type === "Literal");
107
- case "LocaleString":
108
- case "SimpleExpansion":
109
- case "ParameterExpansion":
110
- case "CommandExpansion":
111
- case "ArithmeticExpansion":
112
- case "ProcessSubstitution":
113
- case "ExtendedGlob":
114
- case "BraceExpansion":
115
- return false;
116
- }
117
- }
118
-
119
- function commandName(value: string | undefined): string | undefined {
120
- if (!value) return undefined;
121
- return basename(value).toLowerCase();
122
- }
123
-
124
- type CommandInvocation = {
125
- name?: string;
126
- argumentWords: Word[];
127
- unresolvedTransparentDispatch: boolean;
128
- };
129
-
130
- function unwrapTransparentCommandOnce(
131
- name: string | undefined,
132
- argumentWords: Word[],
133
- ): CommandInvocation {
134
- if (name !== "command" && name !== "exec" && name !== "env") {
135
- return { name, argumentWords, unresolvedTransparentDispatch: false };
136
- }
137
-
138
- let index = 0;
139
- let optionsEnded = false;
140
- while (index < argumentWords.length) {
141
- const word = argumentWords[index];
142
- if (!word || !wordIsStatic(word)) {
143
- return {
144
- argumentWords: [],
145
- unresolvedTransparentDispatch: true,
146
- };
147
- }
148
- const value = word.value;
149
- if (!optionsEnded && value === "--") {
150
- optionsEnded = true;
151
- index += 1;
152
- continue;
153
- }
154
-
155
- if (name === "command" && !optionsEnded) {
156
- if (value === "-p") {
157
- index += 1;
158
- continue;
159
- }
160
- if (value === "-v" || value === "-V" || value.startsWith("-")) {
161
- return { argumentWords: [], unresolvedTransparentDispatch: true };
162
- }
163
- }
164
-
165
- if (name === "exec" && !optionsEnded) {
166
- if (value === "-a") {
167
- const optionValue = argumentWords[index + 1];
168
- if (!optionValue || !wordIsStatic(optionValue)) {
169
- return { argumentWords: [], unresolvedTransparentDispatch: true };
170
- }
171
- index += 2;
172
- continue;
173
- }
174
- if (/^-[cl]+$/.test(value)) {
175
- index += 1;
176
- continue;
177
- }
178
- if (value.startsWith("-")) {
179
- return { argumentWords: [], unresolvedTransparentDispatch: true };
180
- }
181
- }
182
-
183
- if (name === "env") {
184
- if (!optionsEnded && value.startsWith("-")) {
185
- if (
186
- value === "-i" ||
187
- value === "--ignore-environment" ||
188
- value === "-0" ||
189
- value === "--null" ||
190
- value === "-v" ||
191
- value === "--debug"
192
- ) {
193
- index += 1;
194
- continue;
195
- }
196
- if (["-u", "--unset", "-C", "--chdir"].includes(value)) {
197
- const optionValue = argumentWords[index + 1];
198
- if (!optionValue || !wordIsStatic(optionValue)) {
199
- return { argumentWords: [], unresolvedTransparentDispatch: true };
200
- }
201
- index += 2;
202
- continue;
203
- }
204
- if (value.startsWith("--unset=") || value.startsWith("--chdir=")) {
205
- index += 1;
206
- continue;
207
- }
208
- return { argumentWords: [], unresolvedTransparentDispatch: true };
209
- }
210
- if (/^[^=]+=/.test(value)) {
211
- index += 1;
212
- continue;
213
- }
214
- }
215
-
216
- return {
217
- name: commandName(value),
218
- argumentWords: argumentWords.slice(index + 1),
219
- unresolvedTransparentDispatch: false,
220
- };
221
- }
222
-
223
- return { argumentWords: [], unresolvedTransparentDispatch: true };
224
- }
225
-
226
- function effectiveCommandInvocation(
227
- name: string | undefined,
228
- argumentWords: Word[],
229
- ): CommandInvocation {
230
- let invocation: CommandInvocation = {
231
- name,
232
- argumentWords,
233
- unresolvedTransparentDispatch: false,
234
- };
235
- for (let depth = 0; depth < MAX_NESTED_SHELL_DEPTH; depth += 1) {
236
- const next = unwrapTransparentCommandOnce(
237
- invocation.name,
238
- invocation.argumentWords,
239
- );
240
- if (next.unresolvedTransparentDispatch) return next;
241
- if (
242
- next.name === invocation.name &&
243
- next.argumentWords === invocation.argumentWords
244
- ) {
245
- return next;
246
- }
247
- invocation = next;
248
- }
249
- return { argumentWords: [], unresolvedTransparentDispatch: true };
250
- }
251
-
252
- type NestedShell = {
253
- name?: string;
254
- source?: string;
255
- hasScriptArgument: boolean;
256
- };
257
-
258
- function nestedShell(invocation: CommandInvocation): NestedShell | undefined {
259
- if (invocation.unresolvedTransparentDispatch) {
260
- return { hasScriptArgument: true };
261
- }
262
- if (invocation.name === "eval") {
263
- return {
264
- name: "eval",
265
- source:
266
- invocation.argumentWords.length > 0 &&
267
- invocation.argumentWords.every(wordIsStatic)
268
- ? invocation.argumentWords.map((word) => word.value).join(" ")
269
- : undefined,
270
- hasScriptArgument: invocation.argumentWords.length > 0,
271
- };
272
- }
273
- if (invocation.name !== "bash" && invocation.name !== "sh") {
274
- return undefined;
275
- }
276
- const commandOptionIndex = invocation.argumentWords.findIndex((word) =>
277
- /^-[^-]*c/.test(word.value)
278
- );
279
- if (commandOptionIndex < 0) return undefined;
280
- const scriptWord = invocation.argumentWords[commandOptionIndex + 1];
281
- return {
282
- name: invocation.name,
283
- source: scriptWord && wordIsStatic(scriptWord) ? scriptWord.value : undefined,
284
- hasScriptArgument: true,
285
- };
286
- }
287
-
288
- function exhaustiveNode(_node: never): never {
289
- throw new Error(`Unsupported unbash AST node: ${JSON.stringify(_node)}`);
290
- }
291
-
292
- /** Parse one Pi `bash` tool input into normalized executable command views. */
293
- export function analyzeBash(
294
- source: string,
295
- parser: BashParser = parse,
296
- ): BashAnalysis {
297
- const analysis: BashAnalysis = {
298
- source,
299
- commands: [],
300
- redirects: [],
301
- redirectTargets: [],
302
- structure: [],
303
- allowStructureSafe: true,
304
- errors: [],
305
- };
306
- if (source.length > MAX_BASH_SOURCE_LENGTH) {
307
- analysis.errors.push({
308
- message:
309
- `Bash input length ${source.length} exceeds ${MAX_BASH_SOURCE_LENGTH}`,
310
- });
311
- return analysis;
312
- }
313
-
314
- function analyzeRedirect(redirect: Redirect): BashRedirectAnalysis {
315
- return {
316
- operator: redirect.operator,
317
- target: redirect.target?.value,
318
- targetDynamic: !!redirect.target && !wordIsStatic(redirect.target),
319
- fileDescriptor: redirect.fileDescriptor,
320
- variableName: redirect.variableName,
321
- heredoc: redirect.operator === "<<" || redirect.operator === "<<-",
322
- };
323
- }
324
-
325
- function visitRedirect(
326
- redirect: Redirect,
327
- currentSource: string,
328
- depth: number,
329
- ): string | undefined {
330
- const redirectAnalysis = analyzeRedirect(redirect);
331
- analysis.redirects.push(redirectAnalysis);
332
- analysis.structure.push(
333
- `redirect:${redirect.fileDescriptor ?? ""}:${redirect.variableName ?? ""}:${redirect.operator}:${redirectAnalysis.heredoc ? "heredoc" : "file"}`,
334
- );
335
- if (redirect.target) visitWord(redirect.target, currentSource, depth);
336
- if (redirect.body) visitWord(redirect.body, currentSource, depth);
337
- const target = redirect.target?.value;
338
- if (target) analysis.redirectTargets.push(target);
339
- return target;
340
- }
341
-
342
- function visitPart(
343
- part: WordPart,
344
- currentSource: string,
345
- depth: number,
346
- ): void {
347
- switch (part.type) {
348
- case "Literal":
349
- case "SingleQuoted":
350
- case "AnsiCQuoted":
351
- case "SimpleExpansion":
352
- return;
353
- case "DoubleQuoted":
354
- case "LocaleString":
355
- for (const child of part.parts) visitPart(child, currentSource, depth);
356
- return;
357
- case "ParameterExpansion":
358
- for (const indexPart of part.indexParts ?? []) {
359
- visitPart(indexPart, currentSource, depth);
360
- }
361
- if (part.operand) visitWord(part.operand, currentSource, depth);
362
- if (part.slice) {
363
- visitWord(part.slice.offset, currentSource, depth);
364
- if (part.slice.length) {
365
- visitWord(part.slice.length, currentSource, depth);
366
- }
367
- }
368
- if (part.replace) {
369
- visitWord(part.replace.pattern, currentSource, depth);
370
- visitWord(part.replace.replacement, currentSource, depth);
371
- }
372
- return;
373
- case "CommandExpansion":
374
- case "ProcessSubstitution":
375
- analysis.structure.push(
376
- `part:${part.type}:${part.type === "ProcessSubstitution" ? part.operator : ""}`,
377
- );
378
- if (part.script) {
379
- visitScript(part.script, part.script.source ?? currentSource, depth);
380
- }
381
- return;
382
- case "ArithmeticExpansion":
383
- if (part.expression) {
384
- visitArithmetic(part.expression, currentSource, depth);
385
- }
386
- return;
387
- case "ExtendedGlob":
388
- case "BraceExpansion":
389
- for (const nestedPart of part.parts ?? []) {
390
- visitPart(nestedPart, currentSource, depth);
391
- }
392
- return;
393
- }
394
- }
395
-
396
- function visitWord(word: Word, currentSource: string, depth: number): void {
397
- for (const part of wordParts(word)) {
398
- visitPart(part, currentSource, depth);
399
- }
400
- }
401
-
402
- function visitArithmetic(
403
- expression: ArithmeticExpression,
404
- currentSource: string,
405
- depth: number,
406
- ): void {
407
- switch (expression.type) {
408
- case "ArithmeticBinary":
409
- visitArithmetic(expression.left, currentSource, depth);
410
- visitArithmetic(expression.right, currentSource, depth);
411
- return;
412
- case "ArithmeticUnary":
413
- visitArithmetic(expression.operand, currentSource, depth);
414
- return;
415
- case "ArithmeticTernary":
416
- visitArithmetic(expression.test, currentSource, depth);
417
- visitArithmetic(expression.consequent, currentSource, depth);
418
- visitArithmetic(expression.alternate, currentSource, depth);
419
- return;
420
- case "ArithmeticGroup":
421
- visitArithmetic(expression.expression, currentSource, depth);
422
- return;
423
- case "ArithmeticWord":
424
- for (const part of expression.parts ?? []) {
425
- visitPart(part, currentSource, depth);
426
- }
427
- return;
428
- case "ArithmeticCommandExpansion":
429
- analysis.structure.push("part:ArithmeticCommandExpansion");
430
- if (expression.script) {
431
- visitScript(
432
- expression.script,
433
- expression.script.source ?? currentSource,
434
- depth,
435
- );
436
- }
437
- return;
438
- }
439
- }
440
-
441
- function visitTest(
442
- expression: TestExpression,
443
- currentSource: string,
444
- depth: number,
445
- ): void {
446
- switch (expression.type) {
447
- case "TestUnary":
448
- visitWord(expression.operand, currentSource, depth);
449
- return;
450
- case "TestBinary":
451
- visitWord(expression.left, currentSource, depth);
452
- visitWord(expression.right, currentSource, depth);
453
- return;
454
- case "TestLogical":
455
- visitTest(expression.left, currentSource, depth);
456
- visitTest(expression.right, currentSource, depth);
457
- return;
458
- case "TestNot":
459
- visitTest(expression.operand, currentSource, depth);
460
- return;
461
- case "TestGroup":
462
- visitTest(expression.expression, currentSource, depth);
463
- return;
464
- }
465
- }
466
-
467
- function nodeStructureToken(node: Node): string {
468
- switch (node.type) {
469
- case "Command":
470
- return `node:Command:${node.prefix.length}:${node.redirects.length}`;
471
- case "Pipeline":
472
- return `node:Pipeline:${node.negated ? "negated" : "plain"}:${node.time ? "time" : "plain"}:${node.operators.join(",")}`;
473
- case "AndOr":
474
- return `node:AndOr:${node.operators.join(",")}`;
475
- case "If":
476
- return `node:If:${node.else?.type ?? "none"}`;
477
- case "For":
478
- case "Select":
479
- return `node:${node.type}:${node.wordlist.length}`;
480
- case "ArithmeticFor":
481
- return `node:ArithmeticFor:${node.initialize ? 1 : 0}:${node.test ? 1 : 0}:${node.update ? 1 : 0}`;
482
- case "While":
483
- return `node:While:${node.kind}`;
484
- case "Function":
485
- return `node:Function:${node.redirects.length}`;
486
- case "Subshell":
487
- case "BraceGroup":
488
- case "TestCommand":
489
- case "ArithmeticCommand":
490
- return `node:${node.type}`;
491
- case "CompoundList":
492
- return `node:CompoundList:${node.commands.length}`;
493
- case "Case":
494
- return `node:Case:${node.items.map((item) => item.terminator ?? "none").join(",")}`;
495
- case "Coproc":
496
- return `node:Coproc:${node.redirects.length}`;
497
- case "Statement":
498
- return `node:Statement:${node.background ? "background" : "foreground"}:${node.redirects.length}`;
499
- default:
500
- return exhaustiveNode(node);
501
- }
502
- }
503
-
504
- function visitNode(node: Node, nodeSource: string, depth: number): void {
505
- analysis.structure.push(nodeStructureToken(node));
506
- if (
507
- node.type === "For" ||
508
- node.type === "Select" ||
509
- node.type === "ArithmeticFor" ||
510
- node.type === "Function" ||
511
- node.type === "Case" ||
512
- node.type === "Coproc" ||
513
- node.type === "TestCommand" ||
514
- node.type === "ArithmeticCommand"
515
- ) {
516
- analysis.allowStructureSafe = false;
517
- }
518
- switch (node.type) {
519
- case "Command": {
520
- const prefixWords = node.prefix.map((prefix) => prefix.text);
521
- const commandWords = node.name ? [node.name, ...node.suffix] : node.suffix;
522
- const renderedWords = [
523
- ...prefixWords,
524
- ...commandWords.map((word) => word.text),
525
- ];
526
- const values = [
527
- ...prefixWords,
528
- ...commandWords.map((word) => word.value),
529
- ];
530
- const redirects = node.redirects.map(analyzeRedirect);
531
- const redirectTargets = redirects
532
- .map((redirect) => redirect.target)
533
- .filter((target): target is string => !!target);
534
- const normalizedName = commandName(node.name?.value);
535
- const invocation = effectiveCommandInvocation(normalizedName, node.suffix);
536
- const wrapper = nestedShell(invocation);
537
- const wrapperSource = wrapper?.source;
538
- analysis.commands.push({
539
- raw: nodeSource.slice(node.pos, node.end),
540
- text: renderedWords.join(" "),
541
- name: normalizedName,
542
- words: values,
543
- args: node.suffix.map((word) => word.value),
544
- argTexts: node.suffix.map((word) => word.text),
545
- effectiveCommand: {
546
- name: invocation.name,
547
- args: invocation.argumentWords.map((word) => word.value),
548
- argTexts: invocation.argumentWords.map((word) => word.text),
549
- argTildeExpansions:
550
- invocation.argumentWords.map(wordHasTildeExpansion),
551
- unresolvedTransparentDispatch:
552
- invocation.unresolvedTransparentDispatch,
553
- },
554
- redirects,
555
- redirectTargets,
556
- dynamic: commandWords.some((word) => !wordIsStatic(word)),
557
- dynamicName: !!node.name && !wordIsStatic(node.name),
558
- dynamicShellScript:
559
- !!wrapper?.hasScriptArgument && wrapperSource === undefined,
560
- pos: node.pos,
561
- end: node.end,
562
- });
563
-
564
- for (const redirect of node.redirects) {
565
- visitRedirect(redirect, nodeSource, depth);
566
- }
567
- if (node.name) visitWord(node.name, nodeSource, depth);
568
- for (const prefix of node.prefix) {
569
- if (prefix.value) visitWord(prefix.value, nodeSource, depth);
570
- for (const word of prefix.array ?? []) {
571
- visitWord(word, nodeSource, depth);
572
- }
573
- for (const part of prefix.indexParts ?? []) {
574
- visitPart(part, nodeSource, depth);
575
- }
576
- }
577
- for (const word of node.suffix) visitWord(word, nodeSource, depth);
578
-
579
- if (wrapperSource !== undefined) {
580
- analysis.structure.push(`wrapper:${wrapper?.name ?? normalizedName}`);
581
- if (depth >= MAX_NESTED_SHELL_DEPTH) {
582
- analysis.errors.push({
583
- message: `Nested shell depth exceeds ${MAX_NESTED_SHELL_DEPTH}`,
584
- });
585
- } else {
586
- try {
587
- visitScript(parser(wrapperSource), wrapperSource, depth + 1);
588
- } catch (error) {
589
- analysis.errors.push(parserException(error));
590
- }
591
- }
592
- }
593
- return;
594
- }
595
- case "Pipeline":
596
- case "AndOr":
597
- for (const command of node.commands) visitNode(command, nodeSource, depth);
598
- return;
599
- case "If":
600
- visitNode(node.clause, nodeSource, depth);
601
- visitNode(node.then, nodeSource, depth);
602
- if (node.else) visitNode(node.else, nodeSource, depth);
603
- return;
604
- case "For":
605
- case "Select":
606
- visitWord(node.name, nodeSource, depth);
607
- for (const word of node.wordlist) {
608
- visitWord(word, nodeSource, depth);
609
- }
610
- visitNode(node.body, nodeSource, depth);
611
- return;
612
- case "ArithmeticFor":
613
- if (node.initialize) visitArithmetic(node.initialize, nodeSource, depth);
614
- if (node.test) visitArithmetic(node.test, nodeSource, depth);
615
- if (node.update) visitArithmetic(node.update, nodeSource, depth);
616
- visitNode(node.body, nodeSource, depth);
617
- return;
618
- case "While":
619
- visitNode(node.clause, nodeSource, depth);
620
- visitNode(node.body, nodeSource, depth);
621
- return;
622
- case "Function":
623
- visitWord(node.name, nodeSource, depth);
624
- for (const redirect of node.redirects) {
625
- visitRedirect(redirect, nodeSource, depth);
626
- }
627
- visitNode(node.body, nodeSource, depth);
628
- return;
629
- case "Subshell":
630
- case "BraceGroup":
631
- visitNode(node.body, nodeSource, depth);
632
- return;
633
- case "CompoundList":
634
- for (const statement of node.commands) {
635
- visitNode(statement, nodeSource, depth);
636
- }
637
- return;
638
- case "Case":
639
- visitWord(node.word, nodeSource, depth);
640
- for (const item of node.items) {
641
- for (const pattern of item.pattern) {
642
- visitWord(pattern, nodeSource, depth);
643
- }
644
- visitNode(item.body, nodeSource, depth);
645
- }
646
- return;
647
- case "Coproc":
648
- if (node.name) visitWord(node.name, nodeSource, depth);
649
- for (const redirect of node.redirects) {
650
- visitRedirect(redirect, nodeSource, depth);
651
- }
652
- visitNode(node.body, nodeSource, depth);
653
- return;
654
- case "TestCommand":
655
- visitTest(node.expression, nodeSource, depth);
656
- return;
657
- case "ArithmeticCommand":
658
- if (node.expression) {
659
- visitArithmetic(node.expression, nodeSource, depth);
660
- }
661
- return;
662
- case "Statement":
663
- for (const redirect of node.redirects) {
664
- visitRedirect(redirect, nodeSource, depth);
665
- }
666
- visitNode(node.command, nodeSource, depth);
667
- return;
668
- default:
669
- exhaustiveNode(node);
670
- }
671
- }
672
-
673
- function visitScript(
674
- script: ParsedScript,
675
- scriptSource: string,
676
- depth: number,
677
- ): void {
678
- analysis.structure.push(`script:${script.commands.length}`);
679
- for (const error of script.errors ?? []) analysis.errors.push(parseError(error));
680
- for (const statement of script.commands) {
681
- visitNode(statement, scriptSource, depth);
682
- }
683
- }
684
-
685
- try {
686
- visitScript(parser(source), source, 0);
687
- } catch (error) {
688
- analysis.errors.push(parserException(error));
689
- }
690
-
691
- return analysis;
692
- }