@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,623 +0,0 @@
1
- import {
2
- analyzeBash,
3
- type BashAnalysis,
4
- type BashCommandAnalysis,
5
- type BashRedirectAnalysis,
6
- } from "./bash.ts";
7
- import type { ToolPattern } from "./types.ts";
8
- import {
9
- expandHomePattern,
10
- normalizePathForMatch,
11
- resolveInputPath,
12
- resolvePathForPolicy,
13
- resolveToolInputPath,
14
- } from "./paths.ts";
15
-
16
- export const MAX_WILDCARD_PATTERN_LENGTH = 4096;
17
- export const MAX_WILDCARD_INPUT_LENGTH = 1024 * 1024;
18
-
19
- const bashPatternAnalyses = new WeakMap<ToolPattern, BashAnalysis>();
20
-
21
- /** Preserve the previous non-Unicode RegExp `/i` case-equivalence rules. */
22
- function canonicalizeCase(value: string): string {
23
- let canonical = "";
24
- for (let index = 0; index < value.length; index += 1) {
25
- const character = value[index] ?? "";
26
- const uppercase = character.toUpperCase();
27
- if (
28
- uppercase.length !== 1 ||
29
- (character.charCodeAt(0) >= 128 && uppercase.charCodeAt(0) < 128)
30
- ) {
31
- canonical += character;
32
- } else {
33
- canonical += uppercase;
34
- }
35
- }
36
- return canonical;
37
- }
38
-
39
- function normalizeToolName(name: string): string {
40
- const lower = name.trim().replace(/^@/, "").toLowerCase();
41
- const aliases: Record<string, string> = {
42
- bash: "bash",
43
- read: "read",
44
- edit: "edit",
45
- write: "write",
46
- grep: "grep",
47
- find: "find",
48
- ls: "ls",
49
- };
50
- return aliases[lower] ?? lower;
51
- }
52
-
53
- /**
54
- * Parse Pi permission entries such as `bash(git push *)`.
55
- *
56
- * Capitalized names such as `Bash(...)` are accepted as a convenience, but Pi's
57
- * actual tool names are lowercase. Scoped entries stay scoped: we do not flatten
58
- * `bash(git status *)` into a blanket `bash` permission.
59
- */
60
- export function parseToolPattern(value: unknown): ToolPattern | undefined {
61
- if (typeof value !== "string") return undefined;
62
- const raw = value.trim();
63
- if (!raw) return undefined;
64
-
65
- const match = raw.match(/^@?([A-Za-z0-9_-]+)(?:\((.*)\))?$/s);
66
- if (!match) return { raw };
67
- const toolName = normalizeToolName(match[1] ?? "");
68
- const argumentPattern = match[2];
69
- const bashPatternAnalysis = toolName === "bash" && argumentPattern
70
- ? analyzeBash(argumentPattern)
71
- : undefined;
72
- const pattern: ToolPattern = { raw, toolName, argumentPattern };
73
- if (bashPatternAnalysis) bashPatternAnalyses.set(pattern, bashPatternAnalysis);
74
- return pattern;
75
- }
76
-
77
- function literalPrefixTable(value: string): number[] {
78
- const table = new Array<number>(value.length).fill(0);
79
- let prefixLength = 0;
80
- for (let index = 1; index < value.length; index += 1) {
81
- while (
82
- prefixLength > 0 && value[index] !== value[prefixLength]
83
- ) {
84
- prefixLength = table[prefixLength - 1] ?? 0;
85
- }
86
- if (value[index] === value[prefixLength]) prefixLength += 1;
87
- table[index] = prefixLength;
88
- }
89
- return table;
90
- }
91
-
92
- function findLiteral(
93
- value: string,
94
- literal: string,
95
- start: number,
96
- end: number,
97
- ): number {
98
- const prefixTable = literalPrefixTable(literal);
99
- let matched = 0;
100
- for (let index = start; index < end; index += 1) {
101
- while (matched > 0 && value[index] !== literal[matched]) {
102
- matched = prefixTable[matched - 1] ?? 0;
103
- }
104
- if (value[index] === literal[matched]) matched += 1;
105
- if (matched === literal.length) return index - literal.length + 1;
106
- }
107
- return -1;
108
- }
109
-
110
- export type WildcardOverflowPolicy = "match" | "no-match";
111
-
112
- /**
113
- * Match a case-insensitive `*` wildcard pattern in linear time.
114
- *
115
- * `*` matches zero or more characters, including newlines and path separators.
116
- * Denial callers use `match` for over-limit values so they fail closed. Allow
117
- * callers use `no-match` so an oversized input cannot broaden an allow rule.
118
- */
119
- export function matchesWildcardPattern(
120
- pattern: string,
121
- value: string,
122
- overflowPolicy: WildcardOverflowPolicy = "match",
123
- ): boolean {
124
- if (
125
- pattern.length > MAX_WILDCARD_PATTERN_LENGTH ||
126
- value.length > MAX_WILDCARD_INPUT_LENGTH
127
- ) {
128
- return overflowPolicy === "match";
129
- }
130
-
131
- const normalizedPattern = canonicalizeCase(pattern);
132
- const normalizedValue = canonicalizeCase(value);
133
- if (!normalizedPattern.includes("*")) {
134
- return normalizedPattern === normalizedValue;
135
- }
136
-
137
- const startsWithWildcard = normalizedPattern.startsWith("*");
138
- const endsWithWildcard = normalizedPattern.endsWith("*");
139
- const literals = normalizedPattern.split("*").filter(Boolean);
140
- if (literals.length === 0) return true;
141
-
142
- let literalIndex = 0;
143
- let valueIndex = 0;
144
- let lastLiteralIndex = literals.length;
145
-
146
- if (!startsWithWildcard) {
147
- const prefix = literals[0] ?? "";
148
- if (!normalizedValue.startsWith(prefix)) return false;
149
- valueIndex = prefix.length;
150
- literalIndex = 1;
151
- }
152
-
153
- let searchEnd = normalizedValue.length;
154
- if (!endsWithWildcard) {
155
- const suffix = literals[literals.length - 1] ?? "";
156
- searchEnd -= suffix.length;
157
- if (
158
- searchEnd < valueIndex ||
159
- !normalizedValue.endsWith(suffix)
160
- ) {
161
- return false;
162
- }
163
- lastLiteralIndex -= 1;
164
- }
165
-
166
- for (; literalIndex < lastLiteralIndex; literalIndex += 1) {
167
- const literal = literals[literalIndex] ?? "";
168
- const found = findLiteral(
169
- normalizedValue,
170
- literal,
171
- valueIndex,
172
- searchEnd,
173
- );
174
- if (found < 0) return false;
175
- valueIndex = found + literal.length;
176
- }
177
-
178
- return true;
179
- }
180
-
181
- export function normalizePermissionPathForMatch(
182
- path: string,
183
- platform: NodeJS.Platform = process.platform,
184
- ): string {
185
- return platform === "win32" ? path.replace(/\\/g, "/") : path;
186
- }
187
-
188
- function pathArgumentsForMatch(
189
- toolName: string,
190
- cwd: string,
191
- value: string,
192
- overflowPolicy: WildcardOverflowPolicy,
193
- ): string[] {
194
- const resolved = resolveToolInputPath(toolName, cwd, value) ?? value;
195
- const canonical = resolvePathForPolicy(resolved);
196
- const candidates = canonical
197
- ? [canonical, normalizePathForMatch(canonical, cwd)]
198
- : [];
199
- if (overflowPolicy === "match") {
200
- candidates.push(resolved, normalizePathForMatch(resolved, cwd));
201
- }
202
- return [...new Set(
203
- candidates.map((candidate) => normalizePermissionPathForMatch(candidate)),
204
- )];
205
- }
206
-
207
- function getPrimaryArguments(
208
- toolName: string,
209
- input: Record<string, unknown>,
210
- cwd: string,
211
- overflowPolicy: WildcardOverflowPolicy,
212
- ): string[] {
213
- if (toolName === "bash" && typeof input.command === "string") {
214
- return [input.command];
215
- }
216
- if (
217
- (toolName === "read" || toolName === "write" || toolName === "edit") &&
218
- typeof input.path === "string"
219
- ) {
220
- return pathArgumentsForMatch(toolName, cwd, input.path, overflowPolicy);
221
- }
222
- if (toolName === "grep" && typeof input.pattern === "string") {
223
- return [input.pattern];
224
- }
225
- if (
226
- (toolName === "find" || toolName === "ls") &&
227
- typeof input.path === "string"
228
- ) {
229
- return pathArgumentsForMatch(toolName, cwd, input.path, overflowPolicy);
230
- }
231
- return [JSON.stringify(input)];
232
- }
233
-
234
- function isPermissionPathTool(toolName: string): boolean {
235
- return toolName === "read" ||
236
- toolName === "write" ||
237
- toolName === "edit" ||
238
- toolName === "find" ||
239
- toolName === "ls";
240
- }
241
-
242
- export function appendPermissionPathPatternSuffix(
243
- scope: string,
244
- suffix: string,
245
- ): string {
246
- const normalizedScope = withoutTrailingSlash(
247
- normalizePermissionPathForMatch(scope),
248
- );
249
- return normalizedScope.endsWith("/")
250
- ? `${normalizedScope}${suffix}`
251
- : `${normalizedScope}/${suffix}`;
252
- }
253
-
254
- function permissionPathPatternVariants(
255
- pattern: string,
256
- cwd: string,
257
- ): string[] {
258
- const expanded = normalizePermissionPathForMatch(expandHomePattern(pattern));
259
- const wildcardIndex = expanded.indexOf("*");
260
- if (wildcardIndex === -1) {
261
- const resolved = resolveInputPath(cwd, expanded);
262
- const canonical = resolved ? resolvePathForPolicy(resolved) : undefined;
263
- return [...new Set(
264
- [expanded, resolved, canonical]
265
- .filter((value): value is string => !!value)
266
- .map((value) => normalizePermissionPathForMatch(value)),
267
- )];
268
- }
269
-
270
- const fixedPrefix = expanded.slice(0, wildcardIndex);
271
- const lastSlash = fixedPrefix.lastIndexOf("/");
272
- if (lastSlash < 0) return [expanded];
273
- const fixedScope = fixedPrefix.slice(0, lastSlash) || "/";
274
- const resolvedScope = resolveInputPath(cwd, fixedScope);
275
- if (!resolvedScope) return [expanded];
276
- const canonicalScope = resolvePathForPolicy(resolvedScope);
277
- const suffix = expanded.slice(lastSlash).replace(/^\/+/, "");
278
- return [...new Set([
279
- expanded,
280
- appendPermissionPathPatternSuffix(resolvedScope, suffix),
281
- ...(canonicalScope
282
- ? [appendPermissionPathPatternSuffix(canonicalScope, suffix)]
283
- : []),
284
- ])];
285
- }
286
-
287
- /**
288
- * Whether a resolved absolute path matches a configured path-denial pattern.
289
- * Patterns support `~`/`$HOME` expansion and `*` globs, where `*` matches any
290
- * characters, including `/`. Matching is case-insensitive and
291
- * conservative-safe: over-matching only blocks more.
292
- */
293
- export function matchesDeniedPath(
294
- resolvedPath: string,
295
- deniedPaths: string[],
296
- ): boolean {
297
- const normalized = resolvedPath.replace(/\\/g, "/").normalize("NFC");
298
- return deniedPaths.some((pattern) =>
299
- deniedPatternVariants(pattern).some((variant) =>
300
- matchesWildcardPattern(variant.normalize("NFC"), normalized)
301
- )
302
- );
303
- }
304
-
305
- function deniedPatternVariants(pattern: string): string[] {
306
- const expanded = expandHomePattern(pattern).replace(/\\/g, "/");
307
- const wildcardIndex = expanded.indexOf("*");
308
- if (wildcardIndex === -1) {
309
- const canonical = resolvePathForPolicy(expanded)?.replace(/\\/g, "/");
310
- return canonical && canonical !== expanded
311
- ? [expanded, canonical]
312
- : [expanded];
313
- }
314
-
315
- const fixedPrefix = expanded.slice(0, wildcardIndex);
316
- const lastSlash = fixedPrefix.lastIndexOf("/");
317
- if (lastSlash < 0) return [expanded];
318
- const fixedScope = fixedPrefix.slice(0, lastSlash) || "/";
319
- const canonicalScope = resolvePathForPolicy(fixedScope)?.replace(/\\/g, "/");
320
- if (!canonicalScope || canonicalScope === fixedScope) return [expanded];
321
- const suffix = expanded.slice(lastSlash).replace(/^\/+/, "");
322
- const canonicalPattern = canonicalScope === "/"
323
- ? `/${suffix}`
324
- : `${withoutTrailingSlash(canonicalScope)}/${suffix}`;
325
- return canonicalPattern === expanded
326
- ? [expanded]
327
- : [expanded, canonicalPattern];
328
- }
329
-
330
- function withoutTrailingSlash(path: string): string {
331
- if (path === "/" || /^[A-Za-z]:\/$/.test(path)) return path;
332
- return path.replace(/\/+$/, "");
333
- }
334
-
335
- function wildcardCanMatchDescendant(root: string, pattern: string): boolean {
336
- const normalizedRoot = withoutTrailingSlash(
337
- canonicalizeCase(root.replace(/\\/g, "/").normalize("NFC")),
338
- );
339
- const prefix = normalizedRoot === "/" || /^[A-Za-z]:\/$/.test(normalizedRoot)
340
- ? normalizedRoot
341
- : `${normalizedRoot}/`;
342
- const normalizedPattern = canonicalizeCase(pattern.normalize("NFC"));
343
- const wildcardIndex = normalizedPattern.indexOf("*");
344
- if (wildcardIndex < 0) {
345
- return normalizedPattern.length > prefix.length &&
346
- normalizedPattern.startsWith(prefix);
347
- }
348
-
349
- const fixedPrefix = normalizedPattern.slice(0, wildcardIndex);
350
- return prefix.startsWith(fixedPrefix) || fixedPrefix.startsWith(prefix);
351
- }
352
-
353
- /**
354
- * Whether a recursive search scope can contain a path matched by `deniedPaths`.
355
- *
356
- * The check asks whether the wildcard pattern can match any path beginning
357
- * with the search-root prefix. It does not scan the search tree.
358
- */
359
- export function recursiveSearchMayReachDeniedPath(
360
- resolvedRoot: string,
361
- deniedPaths: string[],
362
- ): boolean {
363
- if (resolvedRoot.length > MAX_WILDCARD_INPUT_LENGTH) {
364
- return deniedPaths.length > 0;
365
- }
366
- return deniedPaths.some((pattern) => {
367
- if (pattern.length > MAX_WILDCARD_PATTERN_LENGTH) return true;
368
- return deniedPatternVariants(pattern).some((expanded) =>
369
- wildcardCanMatchDescendant(resolvedRoot, expanded)
370
- );
371
- });
372
- }
373
-
374
- function normalizedBashArgumentPattern(pattern: ToolPattern): string {
375
- const patternAnalysis = bashPatternAnalyses.get(pattern);
376
- if (
377
- patternAnalysis &&
378
- patternAnalysis.errors.length === 0 &&
379
- patternAnalysis.redirects.length === 0 &&
380
- isStructurallyPlainSingleCommand(patternAnalysis)
381
- ) {
382
- return patternAnalysis.commands[0]?.text ?? pattern.argumentPattern ?? "";
383
- }
384
- return pattern.argumentPattern ?? "";
385
- }
386
-
387
- function matchesBashArgumentPattern(
388
- argumentPattern: string,
389
- candidate: string,
390
- overflowPolicy: WildcardOverflowPolicy,
391
- ): boolean {
392
- if (matchesWildcardPattern(argumentPattern, candidate, overflowPolicy)) {
393
- return true;
394
- }
395
- if (overflowPolicy !== "match" || !argumentPattern.endsWith(" *")) {
396
- return false;
397
- }
398
- return matchesWildcardPattern(
399
- argumentPattern.slice(0, -2),
400
- candidate,
401
- overflowPolicy,
402
- );
403
- }
404
-
405
- /** Match a scoped permission rule against a concrete tool call. */
406
- export function matchesToolPattern(
407
- pattern: ToolPattern,
408
- toolName: string,
409
- input: Record<string, unknown>,
410
- cwd: string,
411
- overflowPolicy: WildcardOverflowPolicy = "match",
412
- bashAnalysis?: BashAnalysis,
413
- ): boolean {
414
- if (!pattern.toolName) return overflowPolicy === "match";
415
- if (pattern.toolName !== normalizeToolName(toolName)) return false;
416
- if (pattern.argumentPattern === undefined) return true;
417
- if (pattern.argumentPattern.trim() === "") {
418
- return overflowPolicy === "match";
419
- }
420
- if (
421
- toolName === "bash" &&
422
- (bashPatternAnalyses.get(pattern)?.errors.length ?? 0) > 0
423
- ) {
424
- return overflowPolicy === "match";
425
- }
426
- if (toolName === "bash" && bashAnalysis) {
427
- if (bashAnalysis.errors.length > 0) return overflowPolicy === "match";
428
- const candidates = overflowPolicy === "match"
429
- ? [bashAnalysis.source, ...bashAnalysis.commands.map((command) => command.text)]
430
- : [bashAnalysis.source];
431
- const argumentPattern = normalizedBashArgumentPattern(pattern);
432
- return candidates.some((candidate) =>
433
- matchesBashArgumentPattern(argumentPattern, candidate, overflowPolicy)
434
- );
435
- }
436
- const argumentPatterns = isPermissionPathTool(toolName)
437
- ? permissionPathPatternVariants(pattern.argumentPattern, cwd)
438
- : [pattern.argumentPattern];
439
- const primaryArguments = getPrimaryArguments(
440
- toolName,
441
- input,
442
- cwd,
443
- overflowPolicy,
444
- );
445
- return argumentPatterns.some((argumentPattern) =>
446
- primaryArguments.some((primary) =>
447
- matchesWildcardPattern(argumentPattern, primary, overflowPolicy)
448
- )
449
- );
450
- }
451
-
452
- /** Return the normalized Bash command that matched a scoped permission rule. */
453
- export function matchingBashCommandText(
454
- pattern: ToolPattern,
455
- bashAnalysis: BashAnalysis | undefined,
456
- overflowPolicy: WildcardOverflowPolicy = "match",
457
- ): string | undefined {
458
- if (!bashAnalysis || pattern.toolName !== "bash") return undefined;
459
- if (bashAnalysis.errors.length > 0) return undefined;
460
- if (!pattern.argumentPattern) return undefined;
461
- const argumentPattern = normalizedBashArgumentPattern(pattern);
462
- const command = bashAnalysis.commands.find((candidate) =>
463
- matchesBashArgumentPattern(argumentPattern, candidate.text, overflowPolicy)
464
- );
465
- if (command) return command.text;
466
- return matchesBashArgumentPattern(argumentPattern, bashAnalysis.source, overflowPolicy)
467
- ? bashAnalysis.source
468
- : undefined;
469
- }
470
-
471
- function redirectListsMatch(
472
- patternRedirects: BashRedirectAnalysis[],
473
- inputRedirects: BashRedirectAnalysis[],
474
- ): boolean {
475
- if (patternRedirects.length !== inputRedirects.length) return false;
476
- return patternRedirects.every((pattern, index) => {
477
- const input = inputRedirects[index];
478
- if (!input || pattern.heredoc || input.heredoc || input.targetDynamic) {
479
- return false;
480
- }
481
- if (
482
- pattern.operator !== input.operator ||
483
- pattern.fileDescriptor !== input.fileDescriptor ||
484
- pattern.variableName !== input.variableName
485
- ) {
486
- return false;
487
- }
488
- if (pattern.target === undefined) return input.target === undefined;
489
- if (input.target === undefined) return false;
490
- return matchesWildcardPattern(pattern.target, input.target, "no-match");
491
- });
492
- }
493
-
494
- function commandMatchesAllowPattern(
495
- patternCommand: BashCommandAnalysis,
496
- inputCommand: BashCommandAnalysis,
497
- ): boolean {
498
- return matchesWildcardPattern(
499
- patternCommand.text,
500
- inputCommand.text,
501
- "no-match",
502
- ) && redirectListsMatch(patternCommand.redirects, inputCommand.redirects);
503
- }
504
-
505
- function structuresMatch(pattern: BashAnalysis, input: BashAnalysis): boolean {
506
- return pattern.structure.length === input.structure.length &&
507
- pattern.structure.every((token, index) => token === input.structure[index]);
508
- }
509
-
510
- function allRedirectsAreCommandRedirects(analysis: BashAnalysis): boolean {
511
- return analysis.redirects.length === analysis.commands.reduce(
512
- (count, command) => count + command.redirects.length,
513
- 0,
514
- );
515
- }
516
-
517
- function isStructurallyPlainSingleCommand(analysis: BashAnalysis): boolean {
518
- if (analysis.commands.length !== 1) return false;
519
- if (analysis.structure.length !== 3 + analysis.redirects.length) return false;
520
- if (analysis.structure[0] !== "script:1") return false;
521
- if (analysis.structure[1] !== "node:Statement:foreground:0") return false;
522
- if (!/^node:Command:\d+:\d+$/.test(analysis.structure[2] ?? "")) {
523
- return false;
524
- }
525
- return analysis.structure.slice(3).every((token) =>
526
- token.startsWith("redirect:")
527
- );
528
- }
529
-
530
- function supportsPerCommandAllowPatterns(analysis: BashAnalysis): boolean {
531
- return analysis.structure.every((token) =>
532
- token.startsWith("script:") ||
533
- token.startsWith("node:Statement:foreground:") ||
534
- token.startsWith("node:Command:") ||
535
- token.startsWith("node:AndOr:") ||
536
- token.startsWith("node:Pipeline:plain:plain:") ||
537
- token.startsWith("redirect:")
538
- );
539
- }
540
-
541
- /** Whether permission allow rules cover the complete tool call. */
542
- export function matchesAllowedToolPatterns(
543
- patterns: ToolPattern[],
544
- toolName: string,
545
- input: Record<string, unknown>,
546
- cwd: string,
547
- bashAnalysis?: BashAnalysis,
548
- ): boolean {
549
- if (toolName !== "bash" || !bashAnalysis) {
550
- return patterns.some((pattern) =>
551
- matchesToolPattern(pattern, toolName, input, cwd, "no-match")
552
- );
553
- }
554
- if (
555
- bashAnalysis.errors.length > 0 ||
556
- bashAnalysis.commands.length === 0 ||
557
- !bashAnalysis.allowStructureSafe
558
- ) {
559
- return false;
560
- }
561
- if (
562
- bashAnalysis.commands.some((command) =>
563
- command.dynamicName || command.dynamicShellScript
564
- )
565
- ) {
566
- return false;
567
- }
568
-
569
- for (const pattern of patterns) {
570
- if (pattern.toolName !== "bash") continue;
571
- const patternAnalysis = bashPatternAnalyses.get(pattern);
572
- if (
573
- !patternAnalysis ||
574
- patternAnalysis.errors.length > 0 ||
575
- !patternAnalysis.allowStructureSafe ||
576
- isStructurallyPlainSingleCommand(patternAnalysis) ||
577
- patternAnalysis.commands.length !== bashAnalysis.commands.length ||
578
- !structuresMatch(patternAnalysis, bashAnalysis) ||
579
- !redirectListsMatch(patternAnalysis.redirects, bashAnalysis.redirects)
580
- ) {
581
- continue;
582
- }
583
- if (
584
- patternAnalysis.commands.every((patternCommand, index) => {
585
- const inputCommand = bashAnalysis.commands[index];
586
- return !!inputCommand &&
587
- commandMatchesAllowPattern(patternCommand, inputCommand);
588
- })
589
- ) {
590
- return true;
591
- }
592
- }
593
-
594
- const hasBareBashPattern = patterns.some((pattern) =>
595
- pattern.toolName === "bash" && pattern.argumentPattern === undefined
596
- );
597
- if (
598
- !hasBareBashPattern &&
599
- !supportsPerCommandAllowPatterns(bashAnalysis)
600
- ) {
601
- return false;
602
- }
603
- if (!allRedirectsAreCommandRedirects(bashAnalysis)) return false;
604
- return bashAnalysis.commands.every((command) =>
605
- patterns.some((pattern) => {
606
- if (pattern.toolName !== "bash") return false;
607
- if (pattern.argumentPattern === undefined) {
608
- return command.redirects.length === 0;
609
- }
610
- const patternAnalysis = bashPatternAnalyses.get(pattern);
611
- if (
612
- !patternAnalysis ||
613
- patternAnalysis.errors.length > 0 ||
614
- !isStructurallyPlainSingleCommand(patternAnalysis)
615
- ) {
616
- return false;
617
- }
618
- const patternCommand = patternAnalysis.commands[0];
619
- return !!patternCommand &&
620
- commandMatchesAllowPattern(patternCommand, command);
621
- })
622
- );
623
- }