@caupulican/pi-adaptative 0.81.37 → 0.81.39

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 (451) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +1 -1
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/README.md +18 -1
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +131 -0
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -0
  6. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +196 -0
  7. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -0
  8. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +308 -0
  9. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +22 -2
  10. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
  11. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +585 -24
  12. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
  13. package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +749 -27
  14. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/__init__.py +43 -0
  15. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/fs.py +270 -0
  16. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/search.py +252 -0
  17. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/strings.py +399 -0
  18. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/text.py +575 -0
  19. package/dist/bundled-resources/runtimes/pi-shell-engine/context.py +52 -0
  20. package/dist/bundled-resources/runtimes/pi-shell-engine/errors.py +49 -0
  21. package/dist/bundled-resources/runtimes/pi-shell-engine/exec.py +734 -0
  22. package/dist/bundled-resources/runtimes/pi-shell-engine/expand.py +238 -0
  23. package/dist/bundled-resources/runtimes/pi-shell-engine/main.py +132 -0
  24. package/dist/bundled-resources/runtimes/pi-shell-engine/nodes.py +116 -0
  25. package/dist/bundled-resources/runtimes/pi-shell-engine/parser.py +287 -0
  26. package/dist/bundled-resources/runtimes/pi-shell-engine/proc.py +137 -0
  27. package/dist/bundled-resources/runtimes/pi-shell-engine/state.py +100 -0
  28. package/dist/bundled-resources/runtimes/pi-shell-engine/tokens.py +579 -0
  29. package/dist/bundled-resources/skills/tool-call-repair/SKILL.md +19 -9
  30. package/dist/bundled-resources/skills/tool-call-repair/references/failure-grammar.md +22 -5
  31. package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +5 -5
  32. package/dist/bundled-resources/skills/tool-call-repair/references/text-protocol-grammar.md +28 -7
  33. package/dist/cli/args.d.ts +3 -0
  34. package/dist/cli/args.d.ts.map +1 -1
  35. package/dist/cli/args.js +15 -0
  36. package/dist/cli/args.js.map +1 -1
  37. package/dist/core/agent-paths.d.ts +49 -0
  38. package/dist/core/agent-paths.d.ts.map +1 -0
  39. package/dist/core/agent-paths.js +107 -0
  40. package/dist/core/agent-paths.js.map +1 -0
  41. package/dist/core/agent-session-services.d.ts.map +1 -1
  42. package/dist/core/agent-session-services.js +3 -3
  43. package/dist/core/agent-session-services.js.map +1 -1
  44. package/dist/core/agent-session.d.ts +234 -17
  45. package/dist/core/agent-session.d.ts.map +1 -1
  46. package/dist/core/agent-session.js +484 -62
  47. package/dist/core/agent-session.js.map +1 -1
  48. package/dist/core/autonomy/contracts.d.ts +9 -0
  49. package/dist/core/autonomy/contracts.d.ts.map +1 -1
  50. package/dist/core/autonomy/contracts.js.map +1 -1
  51. package/dist/core/autonomy/lane-tracker.d.ts +10 -1
  52. package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
  53. package/dist/core/autonomy/lane-tracker.js +5 -1
  54. package/dist/core/autonomy/lane-tracker.js.map +1 -1
  55. package/dist/core/background-lane-controller.d.ts +122 -6
  56. package/dist/core/background-lane-controller.d.ts.map +1 -1
  57. package/dist/core/background-lane-controller.js +447 -90
  58. package/dist/core/background-lane-controller.js.map +1 -1
  59. package/dist/core/bash-execution-controller.d.ts +4 -0
  60. package/dist/core/bash-execution-controller.d.ts.map +1 -1
  61. package/dist/core/bash-execution-controller.js +7 -1
  62. package/dist/core/bash-execution-controller.js.map +1 -1
  63. package/dist/core/compaction-support.d.ts +13 -3
  64. package/dist/core/compaction-support.d.ts.map +1 -1
  65. package/dist/core/compaction-support.js +43 -7
  66. package/dist/core/compaction-support.js.map +1 -1
  67. package/dist/core/context/context-audit.d.ts +33 -1
  68. package/dist/core/context/context-audit.d.ts.map +1 -1
  69. package/dist/core/context/context-audit.js +31 -5
  70. package/dist/core/context/context-audit.js.map +1 -1
  71. package/dist/core/context/sqlite-runtime-index.d.ts.map +1 -1
  72. package/dist/core/context/sqlite-runtime-index.js +13 -7
  73. package/dist/core/context/sqlite-runtime-index.js.map +1 -1
  74. package/dist/core/context-gc.d.ts.map +1 -1
  75. package/dist/core/context-gc.js +16 -1
  76. package/dist/core/context-gc.js.map +1 -1
  77. package/dist/core/context-pipeline.d.ts +26 -4
  78. package/dist/core/context-pipeline.d.ts.map +1 -1
  79. package/dist/core/context-pipeline.js +137 -14
  80. package/dist/core/context-pipeline.js.map +1 -1
  81. package/dist/core/cost-guard.d.ts +19 -3
  82. package/dist/core/cost-guard.d.ts.map +1 -1
  83. package/dist/core/cost-guard.js +18 -3
  84. package/dist/core/cost-guard.js.map +1 -1
  85. package/dist/core/delegation/session-worker-result.d.ts +34 -4
  86. package/dist/core/delegation/session-worker-result.d.ts.map +1 -1
  87. package/dist/core/delegation/session-worker-result.js +64 -4
  88. package/dist/core/delegation/session-worker-result.js.map +1 -1
  89. package/dist/core/delegation/worker-actions.d.ts.map +1 -1
  90. package/dist/core/delegation/worker-actions.js +1 -1
  91. package/dist/core/delegation/worker-actions.js.map +1 -1
  92. package/dist/core/delegation/worker-result.d.ts +42 -1
  93. package/dist/core/delegation/worker-result.d.ts.map +1 -1
  94. package/dist/core/delegation/worker-result.js +68 -0
  95. package/dist/core/delegation/worker-result.js.map +1 -1
  96. package/dist/core/extensions/loader.d.ts.map +1 -1
  97. package/dist/core/extensions/loader.js +23 -7
  98. package/dist/core/extensions/loader.js.map +1 -1
  99. package/dist/core/extensions/runner.d.ts.map +1 -1
  100. package/dist/core/extensions/runner.js +1 -0
  101. package/dist/core/extensions/runner.js.map +1 -1
  102. package/dist/core/extensions/types.d.ts +51 -0
  103. package/dist/core/extensions/types.d.ts.map +1 -1
  104. package/dist/core/extensions/types.js.map +1 -1
  105. package/dist/core/goal-loop-controller.d.ts +17 -1
  106. package/dist/core/goal-loop-controller.d.ts.map +1 -1
  107. package/dist/core/goal-loop-controller.js +79 -11
  108. package/dist/core/goal-loop-controller.js.map +1 -1
  109. package/dist/core/goals/goal-continuation-controller.d.ts +48 -2
  110. package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
  111. package/dist/core/goals/goal-continuation-controller.js +77 -0
  112. package/dist/core/goals/goal-continuation-controller.js.map +1 -1
  113. package/dist/core/goals/goal-continuation-defaults.d.ts +39 -0
  114. package/dist/core/goals/goal-continuation-defaults.d.ts.map +1 -1
  115. package/dist/core/goals/goal-continuation-defaults.js +42 -0
  116. package/dist/core/goals/goal-continuation-defaults.js.map +1 -1
  117. package/dist/core/goals/goal-continuation-prompt.d.ts +4 -0
  118. package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
  119. package/dist/core/goals/goal-continuation-prompt.js +51 -10
  120. package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
  121. package/dist/core/goals/goal-runtime-snapshot.d.ts +101 -2
  122. package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
  123. package/dist/core/goals/goal-runtime-snapshot.js +87 -4
  124. package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
  125. package/dist/core/goals/goal-state.d.ts +89 -1
  126. package/dist/core/goals/goal-state.d.ts.map +1 -1
  127. package/dist/core/goals/goal-state.js +71 -5
  128. package/dist/core/goals/goal-state.js.map +1 -1
  129. package/dist/core/goals/goal-tool-core.d.ts +56 -2
  130. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  131. package/dist/core/goals/goal-tool-core.js +111 -5
  132. package/dist/core/goals/goal-tool-core.js.map +1 -1
  133. package/dist/core/goals/session-goal-state.d.ts +11 -2
  134. package/dist/core/goals/session-goal-state.d.ts.map +1 -1
  135. package/dist/core/goals/session-goal-state.js +32 -17
  136. package/dist/core/goals/session-goal-state.js.map +1 -1
  137. package/dist/core/keybindings.d.ts +10 -0
  138. package/dist/core/keybindings.d.ts.map +1 -1
  139. package/dist/core/keybindings.js +10 -2
  140. package/dist/core/keybindings.js.map +1 -1
  141. package/dist/core/learning/observation-store.d.ts +12 -3
  142. package/dist/core/learning/observation-store.d.ts.map +1 -1
  143. package/dist/core/learning/observation-store.js +30 -15
  144. package/dist/core/learning/observation-store.js.map +1 -1
  145. package/dist/core/learning/skill-curator.d.ts +5 -1
  146. package/dist/core/learning/skill-curator.d.ts.map +1 -1
  147. package/dist/core/learning/skill-curator.js +21 -19
  148. package/dist/core/learning/skill-curator.js.map +1 -1
  149. package/dist/core/local-runtime-controller.d.ts +65 -3
  150. package/dist/core/local-runtime-controller.d.ts.map +1 -1
  151. package/dist/core/local-runtime-controller.js +186 -26
  152. package/dist/core/local-runtime-controller.js.map +1 -1
  153. package/dist/core/memory/providers/file-store.d.ts +1 -1
  154. package/dist/core/memory/providers/file-store.d.ts.map +1 -1
  155. package/dist/core/memory/providers/file-store.js +6 -6
  156. package/dist/core/memory/providers/file-store.js.map +1 -1
  157. package/dist/core/model-capability.d.ts +34 -0
  158. package/dist/core/model-capability.d.ts.map +1 -1
  159. package/dist/core/model-capability.js +42 -1
  160. package/dist/core/model-capability.js.map +1 -1
  161. package/dist/core/model-router/tool-escalation.d.ts +15 -0
  162. package/dist/core/model-router/tool-escalation.d.ts.map +1 -1
  163. package/dist/core/model-router/tool-escalation.js +23 -1
  164. package/dist/core/model-router/tool-escalation.js.map +1 -1
  165. package/dist/core/model-router-controller.d.ts +34 -7
  166. package/dist/core/model-router-controller.d.ts.map +1 -1
  167. package/dist/core/model-router-controller.js +95 -16
  168. package/dist/core/model-router-controller.js.map +1 -1
  169. package/dist/core/models/adaptation-store.d.ts +7 -0
  170. package/dist/core/models/adaptation-store.d.ts.map +1 -1
  171. package/dist/core/models/adaptation-store.js +47 -11
  172. package/dist/core/models/adaptation-store.js.map +1 -1
  173. package/dist/core/models/default-model-suggestions.d.ts.map +1 -1
  174. package/dist/core/models/default-model-suggestions.js +17 -0
  175. package/dist/core/models/default-model-suggestions.js.map +1 -1
  176. package/dist/core/models/fitness-store.d.ts +3 -0
  177. package/dist/core/models/fitness-store.d.ts.map +1 -1
  178. package/dist/core/models/fitness-store.js +11 -2
  179. package/dist/core/models/fitness-store.js.map +1 -1
  180. package/dist/core/models/llamacpp-runtime.d.ts +180 -0
  181. package/dist/core/models/llamacpp-runtime.d.ts.map +1 -0
  182. package/dist/core/models/llamacpp-runtime.js +475 -0
  183. package/dist/core/models/llamacpp-runtime.js.map +1 -0
  184. package/dist/core/models/local-registration.d.ts +40 -0
  185. package/dist/core/models/local-registration.d.ts.map +1 -1
  186. package/dist/core/models/local-registration.js +94 -5
  187. package/dist/core/models/local-registration.js.map +1 -1
  188. package/dist/core/models/local-runtime.d.ts.map +1 -1
  189. package/dist/core/models/local-runtime.js +9 -7
  190. package/dist/core/models/local-runtime.js.map +1 -1
  191. package/dist/core/models/model-ref.d.ts +7 -0
  192. package/dist/core/models/model-ref.d.ts.map +1 -1
  193. package/dist/core/models/model-ref.js +26 -0
  194. package/dist/core/models/model-ref.js.map +1 -1
  195. package/dist/core/models/needle-runtime.d.ts +257 -0
  196. package/dist/core/models/needle-runtime.d.ts.map +1 -0
  197. package/dist/core/models/needle-runtime.js +519 -0
  198. package/dist/core/models/needle-runtime.js.map +1 -0
  199. package/dist/core/models/prism-llamacpp-lifecycle.d.ts +89 -0
  200. package/dist/core/models/prism-llamacpp-lifecycle.d.ts.map +1 -0
  201. package/dist/core/models/prism-llamacpp-lifecycle.js +121 -0
  202. package/dist/core/models/prism-llamacpp-lifecycle.js.map +1 -0
  203. package/dist/core/package-manager.d.ts.map +1 -1
  204. package/dist/core/package-manager.js +11 -10
  205. package/dist/core/package-manager.js.map +1 -1
  206. package/dist/core/process-matrix/codes.d.ts +72 -0
  207. package/dist/core/process-matrix/codes.d.ts.map +1 -0
  208. package/dist/core/process-matrix/codes.js +15 -0
  209. package/dist/core/process-matrix/codes.js.map +1 -0
  210. package/dist/core/process-matrix/runtime.d.ts +63 -0
  211. package/dist/core/process-matrix/runtime.d.ts.map +1 -0
  212. package/dist/core/process-matrix/runtime.js +310 -0
  213. package/dist/core/process-matrix/runtime.js.map +1 -0
  214. package/dist/core/process-matrix/store.d.ts +22 -0
  215. package/dist/core/process-matrix/store.d.ts.map +1 -0
  216. package/dist/core/process-matrix/store.js +80 -0
  217. package/dist/core/process-matrix/store.js.map +1 -0
  218. package/dist/core/process-matrix/supervisor.d.ts +72 -0
  219. package/dist/core/process-matrix/supervisor.d.ts.map +1 -0
  220. package/dist/core/process-matrix/supervisor.js +130 -0
  221. package/dist/core/process-matrix/supervisor.js.map +1 -0
  222. package/dist/core/profile-registry.d.ts +7 -0
  223. package/dist/core/profile-registry.d.ts.map +1 -1
  224. package/dist/core/profile-registry.js +20 -0
  225. package/dist/core/profile-registry.js.map +1 -1
  226. package/dist/core/python-runtime.d.ts.map +1 -1
  227. package/dist/core/python-runtime.js +3 -3
  228. package/dist/core/python-runtime.js.map +1 -1
  229. package/dist/core/reflection-controller.d.ts +29 -5
  230. package/dist/core/reflection-controller.d.ts.map +1 -1
  231. package/dist/core/reflection-controller.js +215 -126
  232. package/dist/core/reflection-controller.js.map +1 -1
  233. package/dist/core/reload-blockers.d.ts +36 -0
  234. package/dist/core/reload-blockers.d.ts.map +1 -1
  235. package/dist/core/reload-blockers.js +44 -0
  236. package/dist/core/reload-blockers.js.map +1 -1
  237. package/dist/core/resource-loader.d.ts.map +1 -1
  238. package/dist/core/resource-loader.js +8 -7
  239. package/dist/core/resource-loader.js.map +1 -1
  240. package/dist/core/runtime-builder.d.ts +58 -5
  241. package/dist/core/runtime-builder.d.ts.map +1 -1
  242. package/dist/core/runtime-builder.js +209 -25
  243. package/dist/core/runtime-builder.js.map +1 -1
  244. package/dist/core/scout-controller.d.ts +6 -0
  245. package/dist/core/scout-controller.d.ts.map +1 -1
  246. package/dist/core/scout-controller.js +66 -52
  247. package/dist/core/scout-controller.js.map +1 -1
  248. package/dist/core/sdk.d.ts.map +1 -1
  249. package/dist/core/sdk.js +3 -3
  250. package/dist/core/sdk.js.map +1 -1
  251. package/dist/core/session-role.d.ts +31 -0
  252. package/dist/core/session-role.d.ts.map +1 -0
  253. package/dist/core/session-role.js +52 -0
  254. package/dist/core/session-role.js.map +1 -0
  255. package/dist/core/settings-manager.d.ts +42 -3
  256. package/dist/core/settings-manager.d.ts.map +1 -1
  257. package/dist/core/settings-manager.js +94 -60
  258. package/dist/core/settings-manager.js.map +1 -1
  259. package/dist/core/system-prompt-builder.d.ts +12 -0
  260. package/dist/core/system-prompt-builder.d.ts.map +1 -1
  261. package/dist/core/system-prompt-builder.js +6 -0
  262. package/dist/core/system-prompt-builder.js.map +1 -1
  263. package/dist/core/system-prompt.d.ts +14 -1
  264. package/dist/core/system-prompt.d.ts.map +1 -1
  265. package/dist/core/system-prompt.js +20 -3
  266. package/dist/core/system-prompt.js.map +1 -1
  267. package/dist/core/tasks/session-task-state.d.ts +11 -2
  268. package/dist/core/tasks/session-task-state.d.ts.map +1 -1
  269. package/dist/core/tasks/session-task-state.js +27 -11
  270. package/dist/core/tasks/session-task-state.js.map +1 -1
  271. package/dist/core/tasks/task-contract-monitor.d.ts +45 -0
  272. package/dist/core/tasks/task-contract-monitor.d.ts.map +1 -0
  273. package/dist/core/tasks/task-contract-monitor.js +56 -0
  274. package/dist/core/tasks/task-contract-monitor.js.map +1 -0
  275. package/dist/core/tasks/task-state.d.ts +8 -0
  276. package/dist/core/tasks/task-state.d.ts.map +1 -1
  277. package/dist/core/tasks/task-state.js +28 -1
  278. package/dist/core/tasks/task-state.js.map +1 -1
  279. package/dist/core/tool-gate-controller.d.ts.map +1 -1
  280. package/dist/core/tool-gate-controller.js +5 -0
  281. package/dist/core/tool-gate-controller.js.map +1 -1
  282. package/dist/core/tool-recovery-log-records.d.ts +7 -0
  283. package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
  284. package/dist/core/tool-recovery-log-records.js +14 -6
  285. package/dist/core/tool-recovery-log-records.js.map +1 -1
  286. package/dist/core/tool-selection/promotion.d.ts +54 -0
  287. package/dist/core/tool-selection/promotion.d.ts.map +1 -0
  288. package/dist/core/tool-selection/promotion.js +81 -0
  289. package/dist/core/tool-selection/promotion.js.map +1 -0
  290. package/dist/core/tool-selection/tool-performance-store.d.ts +37 -0
  291. package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -1
  292. package/dist/core/tool-selection/tool-performance-store.js +87 -3
  293. package/dist/core/tool-selection/tool-performance-store.js.map +1 -1
  294. package/dist/core/tool-selection/tool-selection-controller.d.ts +45 -0
  295. package/dist/core/tool-selection/tool-selection-controller.d.ts.map +1 -1
  296. package/dist/core/tool-selection/tool-selection-controller.js +96 -0
  297. package/dist/core/tool-selection/tool-selection-controller.js.map +1 -1
  298. package/dist/core/tools/bash.d.ts +18 -0
  299. package/dist/core/tools/bash.d.ts.map +1 -1
  300. package/dist/core/tools/bash.js +97 -18
  301. package/dist/core/tools/bash.js.map +1 -1
  302. package/dist/core/tools/delegate-status.d.ts +14 -0
  303. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  304. package/dist/core/tools/delegate-status.js +82 -7
  305. package/dist/core/tools/delegate-status.js.map +1 -1
  306. package/dist/core/tools/delegate.d.ts.map +1 -1
  307. package/dist/core/tools/delegate.js +25 -8
  308. package/dist/core/tools/delegate.js.map +1 -1
  309. package/dist/core/tools/find.d.ts.map +1 -1
  310. package/dist/core/tools/find.js +52 -44
  311. package/dist/core/tools/find.js.map +1 -1
  312. package/dist/core/tools/goal.d.ts +94 -3
  313. package/dist/core/tools/goal.d.ts.map +1 -1
  314. package/dist/core/tools/goal.js +165 -15
  315. package/dist/core/tools/goal.js.map +1 -1
  316. package/dist/core/tools/grep.d.ts.map +1 -1
  317. package/dist/core/tools/grep.js +5 -4
  318. package/dist/core/tools/grep.js.map +1 -1
  319. package/dist/core/tools/model-fitness.d.ts +7 -0
  320. package/dist/core/tools/model-fitness.d.ts.map +1 -1
  321. package/dist/core/tools/model-fitness.js +2 -2
  322. package/dist/core/tools/model-fitness.js.map +1 -1
  323. package/dist/core/tools/render-utils.d.ts.map +1 -1
  324. package/dist/core/tools/render-utils.js +1 -1
  325. package/dist/core/tools/render-utils.js.map +1 -1
  326. package/dist/core/tools/shell-contract-router.d.ts +6 -1
  327. package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
  328. package/dist/core/tools/shell-contract-router.js +69 -13
  329. package/dist/core/tools/shell-contract-router.js.map +1 -1
  330. package/dist/core/tools/shell-session.d.ts +89 -0
  331. package/dist/core/tools/shell-session.d.ts.map +1 -0
  332. package/dist/core/tools/shell-session.js +432 -0
  333. package/dist/core/tools/shell-session.js.map +1 -0
  334. package/dist/core/tools/task-steps.d.ts +4 -0
  335. package/dist/core/tools/task-steps.d.ts.map +1 -1
  336. package/dist/core/tools/task-steps.js +63 -8
  337. package/dist/core/tools/task-steps.js.map +1 -1
  338. package/dist/core/tools/tmux-dispatch.d.ts +86 -0
  339. package/dist/core/tools/tmux-dispatch.d.ts.map +1 -0
  340. package/dist/core/tools/tmux-dispatch.js +91 -0
  341. package/dist/core/tools/tmux-dispatch.js.map +1 -0
  342. package/dist/core/tools/windows-shell-engine.d.ts +42 -0
  343. package/dist/core/tools/windows-shell-engine.d.ts.map +1 -0
  344. package/dist/core/tools/windows-shell-engine.js +153 -0
  345. package/dist/core/tools/windows-shell-engine.js.map +1 -0
  346. package/dist/core/tools/windows-shell-state.d.ts +40 -0
  347. package/dist/core/tools/windows-shell-state.d.ts.map +1 -0
  348. package/dist/core/tools/windows-shell-state.js +59 -0
  349. package/dist/core/tools/windows-shell-state.js.map +1 -0
  350. package/dist/core/tools/worktree-sync.d.ts +24 -0
  351. package/dist/core/tools/worktree-sync.d.ts.map +1 -0
  352. package/dist/core/tools/worktree-sync.js +338 -0
  353. package/dist/core/tools/worktree-sync.js.map +1 -0
  354. package/dist/core/trust-manager.d.ts +4 -1
  355. package/dist/core/trust-manager.d.ts.map +1 -1
  356. package/dist/core/trust-manager.js +20 -2
  357. package/dist/core/trust-manager.js.map +1 -1
  358. package/dist/core/util/atomic-file.d.ts +55 -0
  359. package/dist/core/util/atomic-file.d.ts.map +1 -0
  360. package/dist/core/util/atomic-file.js +255 -0
  361. package/dist/core/util/atomic-file.js.map +1 -0
  362. package/dist/core/util/minimatch-cache.d.ts +33 -0
  363. package/dist/core/util/minimatch-cache.d.ts.map +1 -0
  364. package/dist/core/util/minimatch-cache.js +0 -0
  365. package/dist/core/util/minimatch-cache.js.map +1 -0
  366. package/dist/core/worktree-sync/codes.d.ts +227 -0
  367. package/dist/core/worktree-sync/codes.d.ts.map +1 -0
  368. package/dist/core/worktree-sync/codes.js +14 -0
  369. package/dist/core/worktree-sync/codes.js.map +1 -0
  370. package/dist/core/worktree-sync/git-engine.d.ts +156 -0
  371. package/dist/core/worktree-sync/git-engine.d.ts.map +1 -0
  372. package/dist/core/worktree-sync/git-engine.js +1191 -0
  373. package/dist/core/worktree-sync/git-engine.js.map +1 -0
  374. package/dist/core/worktree-sync/lane-gate.d.ts +75 -0
  375. package/dist/core/worktree-sync/lane-gate.d.ts.map +1 -0
  376. package/dist/core/worktree-sync/lane-gate.js +360 -0
  377. package/dist/core/worktree-sync/lane-gate.js.map +1 -0
  378. package/dist/core/worktree-sync/runtime.d.ts +47 -0
  379. package/dist/core/worktree-sync/runtime.d.ts.map +1 -0
  380. package/dist/core/worktree-sync/runtime.js +96 -0
  381. package/dist/core/worktree-sync/runtime.js.map +1 -0
  382. package/dist/core/worktree-sync/store.d.ts +69 -0
  383. package/dist/core/worktree-sync/store.d.ts.map +1 -0
  384. package/dist/core/worktree-sync/store.js +247 -0
  385. package/dist/core/worktree-sync/store.js.map +1 -0
  386. package/dist/core/worktree-sync/watcher.d.ts +29 -0
  387. package/dist/core/worktree-sync/watcher.d.ts.map +1 -0
  388. package/dist/core/worktree-sync/watcher.js +93 -0
  389. package/dist/core/worktree-sync/watcher.js.map +1 -0
  390. package/dist/main.d.ts.map +1 -1
  391. package/dist/main.js +94 -0
  392. package/dist/main.js.map +1 -1
  393. package/dist/migrations.d.ts +9 -0
  394. package/dist/migrations.d.ts.map +1 -1
  395. package/dist/migrations.js +38 -0
  396. package/dist/migrations.js.map +1 -1
  397. package/dist/modes/interactive/auto-learn-controller.d.ts +16 -1
  398. package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -1
  399. package/dist/modes/interactive/auto-learn-controller.js +50 -8
  400. package/dist/modes/interactive/auto-learn-controller.js.map +1 -1
  401. package/dist/modes/interactive/components/profile-resource-editor.d.ts.map +1 -1
  402. package/dist/modes/interactive/components/profile-resource-editor.js +23 -1
  403. package/dist/modes/interactive/components/profile-resource-editor.js.map +1 -1
  404. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  405. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  406. package/dist/modes/interactive/interactive-mode.js +4 -0
  407. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  408. package/dist/modes/interactive/local-model-commands.d.ts +43 -0
  409. package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
  410. package/dist/modes/interactive/local-model-commands.js +290 -3
  411. package/dist/modes/interactive/local-model-commands.js.map +1 -1
  412. package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
  413. package/dist/modes/interactive/session-flow-commands.js +24 -4
  414. package/dist/modes/interactive/session-flow-commands.js.map +1 -1
  415. package/dist/utils/fs-watch.d.ts +11 -0
  416. package/dist/utils/fs-watch.d.ts.map +1 -1
  417. package/dist/utils/fs-watch.js +20 -2
  418. package/dist/utils/fs-watch.js.map +1 -1
  419. package/dist/utils/highlight-js-languages.d.ts +4 -0
  420. package/dist/utils/highlight-js-languages.d.ts.map +1 -0
  421. package/dist/utils/highlight-js-languages.js +573 -0
  422. package/dist/utils/highlight-js-languages.js.map +1 -0
  423. package/dist/utils/shell.d.ts +7 -1
  424. package/dist/utils/shell.d.ts.map +1 -1
  425. package/dist/utils/shell.js +39 -9
  426. package/dist/utils/shell.js.map +1 -1
  427. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  428. package/dist/utils/syntax-highlight.js +53 -5
  429. package/dist/utils/syntax-highlight.js.map +1 -1
  430. package/dist/utils/tools-manager.d.ts.map +1 -1
  431. package/dist/utils/tools-manager.js +112 -1
  432. package/dist/utils/tools-manager.js.map +1 -1
  433. package/docs/development.md +2 -0
  434. package/docs/packages.md +1 -1
  435. package/docs/process-matrix.md +120 -0
  436. package/docs/settings.md +5 -2
  437. package/docs/tmux-agent-manager.md +85 -2
  438. package/docs/windows.md +52 -3
  439. package/docs/work-directory.md +29 -0
  440. package/docs/worktree-sync.md +250 -0
  441. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  442. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  443. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  444. package/examples/extensions/sandbox/package-lock.json +2 -2
  445. package/examples/extensions/sandbox/package.json +1 -1
  446. package/examples/extensions/with-deps/package-lock.json +2 -2
  447. package/examples/extensions/with-deps/package.json +1 -1
  448. package/npm-shrinkwrap.json +12 -12
  449. package/package.json +10 -4
  450. package/docs/integration-sweep-builder-blueprint-2026-07-09.md +0 -365
  451. package/docs/integration-sweep-resume-2026-07-09.md +0 -407
@@ -0,0 +1,579 @@
1
+ """Tokenizer: source `str` -> `list[Token]`; resolves quoting into word segments.
2
+
3
+ Splits Bash source into WORD tokens (each carrying an ordered `list[Segment]` already
4
+ broken by quoting/expansion markers) and OPERATOR tokens (the fixed lexeme set from
5
+ windows-shell-workpackages-2026-07-19.md §1.1/§3 WP-A). Never returns a partial or
6
+ guessed token stream: anything outside the frozen grammar raises `UnsupportedConstruct`
7
+ with a catalog id and an actionable message naming the construct.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import re
13
+ from dataclasses import dataclass
14
+
15
+ from errors import UnsupportedConstruct
16
+ from nodes import CmdSub, DQ, Lit, Param, Raw, Segment, Tilde, Word
17
+
18
+ _IDENT_START_RE = re.compile(r"[A-Za-z_]")
19
+ _IDENT_RE = re.compile(r"[A-Za-z_][A-Za-z0-9_]*")
20
+ _ANSI_C_MAP = {
21
+ "\\": "\\",
22
+ "a": "\a",
23
+ "b": "\b",
24
+ "c": "", # \c stops output; treated as empty here (bounded, no truncation semantics)
25
+ "e": "\x1b",
26
+ "f": "\f",
27
+ "n": "\n",
28
+ "r": "\r",
29
+ "t": "\t",
30
+ "v": "\v",
31
+ }
32
+
33
+
34
+ @dataclass
35
+ class Token:
36
+ kind: str # "WORD" | "OP"
37
+ text: str | None = None # OP: exact operator text (e.g. ">>", "2>&1", "\n")
38
+ segments: list[Segment] | None = None # WORD: ordered segments
39
+
40
+
41
+ def _unterminated(what: str) -> UnsupportedConstruct:
42
+ # Not part of the frozen §2.3 catalog: a defensive, never-crash refusal for
43
+ # genuinely malformed input (unbalanced quote/paren/brace). No acceptance test
44
+ # requires this id; flagged for architect review in the WP-A report.
45
+ return UnsupportedConstruct("malformed-syntax", f"Unterminated {what}: the command has an unbalanced quote or bracket.")
46
+
47
+
48
+ def _ansi_c_unescape(text: str) -> str:
49
+ out: list[str] = []
50
+ i = 0
51
+ n = len(text)
52
+ while i < n:
53
+ c = text[i]
54
+ if c != "\\" or i + 1 >= n:
55
+ out.append(c)
56
+ i += 1
57
+ continue
58
+ nxt = text[i + 1]
59
+ if nxt in _ANSI_C_MAP:
60
+ out.append(_ANSI_C_MAP[nxt])
61
+ i += 2
62
+ continue
63
+ if nxt == "0":
64
+ j = i + 2
65
+ digits = ""
66
+ while j < n and len(digits) < 3 and text[j] in "01234567":
67
+ digits += text[j]
68
+ j += 1
69
+ out.append(chr(int(digits, 8)) if digits else "\0")
70
+ i = j
71
+ continue
72
+ if nxt == "x":
73
+ j = i + 2
74
+ digits = ""
75
+ while j < n and len(digits) < 2 and text[j] in "0123456789abcdefABCDEF":
76
+ digits += text[j]
77
+ j += 1
78
+ out.append(chr(int(digits, 16)) if digits else "x")
79
+ i = j
80
+ continue
81
+ out.append(nxt)
82
+ i += 2
83
+ return "".join(out)
84
+
85
+
86
+ def _find_closing_paren(src: str, pos: int) -> int:
87
+ """`pos` is the index right after the opening '('. Returns the index of the matching ')'."""
88
+ n = len(src)
89
+ depth = 1
90
+ i = pos
91
+ while i < n:
92
+ c = src[i]
93
+ if c == "\\" and i + 1 < n:
94
+ i += 2
95
+ continue
96
+ if c == "'":
97
+ j = src.find("'", i + 1)
98
+ if j == -1:
99
+ raise _unterminated("single quote")
100
+ i = j + 1
101
+ continue
102
+ if c == '"':
103
+ i = _skip_double_quote(src, i + 1)
104
+ continue
105
+ if c == "(":
106
+ depth += 1
107
+ i += 1
108
+ continue
109
+ if c == ")":
110
+ depth -= 1
111
+ if depth == 0:
112
+ return i
113
+ i += 1
114
+ continue
115
+ i += 1
116
+ raise _unterminated("'('")
117
+
118
+
119
+ def _skip_double_quote(src: str, pos: int) -> int:
120
+ """`pos` is the index right after the opening '"'. Returns the index right after the closing '"'."""
121
+ n = len(src)
122
+ i = pos
123
+ while i < n:
124
+ c = src[i]
125
+ if c == "\\" and i + 1 < n:
126
+ i += 2
127
+ continue
128
+ if c == '"':
129
+ return i + 1
130
+ i += 1
131
+ raise _unterminated('double quote')
132
+
133
+
134
+ def _find_closing_brace(src: str, pos: int) -> int:
135
+ """`pos` is the index right after the opening '{'. Returns the index of the matching '}'."""
136
+ n = len(src)
137
+ depth = 1
138
+ i = pos
139
+ while i < n:
140
+ c = src[i]
141
+ if c == "\\" and i + 1 < n:
142
+ i += 2
143
+ continue
144
+ if c == "'":
145
+ j = src.find("'", i + 1)
146
+ if j == -1:
147
+ raise _unterminated("single quote")
148
+ i = j + 1
149
+ continue
150
+ if c == '"':
151
+ i = _skip_double_quote(src, i + 1)
152
+ continue
153
+ if src[i : i + 2] == "${":
154
+ depth += 1
155
+ i += 2
156
+ continue
157
+ if src[i : i + 2] == "$(":
158
+ i = _find_closing_paren(src, i + 2) + 1
159
+ continue
160
+ if c == "}":
161
+ depth -= 1
162
+ if depth == 0:
163
+ return i
164
+ i += 1
165
+ continue
166
+ i += 1
167
+ raise _unterminated("'{'")
168
+
169
+
170
+ def _scan_param_arg_word(text: str) -> Word:
171
+ """Scan a `${VAR:-arg}`-style default/assign/alt/err argument into a `Word`.
172
+
173
+ Unlike `_scan_word`, this consumes the ENTIRE `text` (already delimited by the matching
174
+ closing brace found by `_find_closing_brace`): whitespace inside is literal content within
175
+ Raw segments, not a word-boundary terminator (bash: `${V:-a b}` -> the default word is the
176
+ full "a b", not just "a"). Quoting and $-forms inside are still parsed as segments.
177
+ """
178
+ n = len(text)
179
+ segments: list[Segment] = []
180
+ buf: list[str] = []
181
+ i = 0
182
+
183
+ def flush() -> None:
184
+ if buf:
185
+ segments.append(Raw(text="".join(buf)))
186
+ buf.clear()
187
+
188
+ while i < n:
189
+ c = text[i]
190
+ if c == "\\":
191
+ if i + 1 < n:
192
+ flush()
193
+ segments.append(Lit(text=text[i + 1]))
194
+ i += 2
195
+ else:
196
+ buf.append(c)
197
+ i += 1
198
+ continue
199
+ if c == "'":
200
+ j = text.find("'", i + 1)
201
+ if j == -1:
202
+ raise _unterminated("single quote")
203
+ flush()
204
+ segments.append(Lit(text=text[i + 1 : j]))
205
+ i = j + 1
206
+ continue
207
+ if c == '"':
208
+ flush()
209
+ dq_segments, newpos = _scan_dq_segments(text, i + 1)
210
+ segments.append(DQ(segments=dq_segments))
211
+ i = newpos
212
+ continue
213
+ if c == "$" and text[i + 1 : i + 2] == "'":
214
+ j = i + 2
215
+ raw_chars: list[str] = []
216
+ while j < n and text[j] != "'":
217
+ if text[j] == "\\" and j + 1 < n:
218
+ raw_chars.append(text[j])
219
+ raw_chars.append(text[j + 1])
220
+ j += 2
221
+ else:
222
+ raw_chars.append(text[j])
223
+ j += 1
224
+ if j >= n:
225
+ raise _unterminated("$'...' quote")
226
+ flush()
227
+ segments.append(Lit(text=_ansi_c_unescape("".join(raw_chars))))
228
+ i = j + 1
229
+ continue
230
+ if c == "$":
231
+ seg, newpos = _scan_dollar_form(text, i)
232
+ if isinstance(seg, Lit) and seg.text == "$" and newpos == i + 1:
233
+ buf.append("$")
234
+ i = newpos
235
+ continue
236
+ flush()
237
+ segments.append(seg)
238
+ i = newpos
239
+ continue
240
+ if c == "`":
241
+ j = i + 1
242
+ while j < n and text[j] != "`":
243
+ if text[j] == "\\" and j + 1 < n:
244
+ j += 2
245
+ else:
246
+ j += 1
247
+ if j >= n:
248
+ raise _unterminated("backtick")
249
+ flush()
250
+ segments.append(CmdSub(src=text[i + 1 : j]))
251
+ i = j + 1
252
+ continue
253
+ buf.append(c)
254
+ i += 1
255
+ flush()
256
+ return Word(segments=segments)
257
+
258
+
259
+ def _parse_param_brace_content(content: str) -> Param:
260
+ if content.startswith("#"):
261
+ return Param(name=content[1:], op="#len", arg=None)
262
+ m = _IDENT_RE.match(content)
263
+ name = m.group(0) if m else ""
264
+ rest = content[len(name) :]
265
+ for candidate in (":-", ":=", ":+", ":?"):
266
+ if rest.startswith(candidate):
267
+ arg_text = rest[len(candidate) :]
268
+ # Scan the FULL remainder into one Word: the default/alt/assign/err argument runs
269
+ # up to the already-matched closing brace, so whitespace inside it is literal text
270
+ # within Raw segments (bash: `${V:-a b}` -> default word is "a b", not just "a").
271
+ # Do not truncate at the first _scan_word word-boundary space.
272
+ arg_word = _scan_param_arg_word(arg_text) if arg_text else Word(segments=[])
273
+ return Param(name=name, op=candidate, arg=arg_word)
274
+ if rest:
275
+ raise UnsupportedConstruct(
276
+ "parameter-expansion",
277
+ f"Unsupported parameter expansion form '${{{content}}}': only ${{VAR}}, ${{VAR:-w}}, "
278
+ "${VAR:=w}, ${VAR:+w}, ${VAR:?w}, and ${#VAR} are supported.",
279
+ )
280
+ return Param(name=name, op=None, arg=None)
281
+
282
+
283
+ def _scan_dollar_form(src: str, pos: int) -> tuple[Segment, int]:
284
+ """`pos` is the index of '$'. Returns (segment, new_pos)."""
285
+ n = len(src)
286
+ nxt = src[pos + 1] if pos + 1 < n else ""
287
+ if nxt == "{":
288
+ close = _find_closing_brace(src, pos + 2)
289
+ return _parse_param_brace_content(src[pos + 2 : close]), close + 1
290
+ if nxt == "(":
291
+ if src[pos + 2 : pos + 3] == "(":
292
+ raise UnsupportedConstruct(
293
+ "arithmetic-expansion", "Arithmetic expansion '$((...))' is not supported."
294
+ )
295
+ close = _find_closing_paren(src, pos + 2)
296
+ return CmdSub(src=src[pos + 2 : close]), close + 1
297
+ if nxt and (_IDENT_START_RE.match(nxt)):
298
+ m = _IDENT_RE.match(src, pos + 1)
299
+ assert m is not None
300
+ return Param(name=m.group(0), op=None, arg=None), m.end()
301
+ # Bare '$' with nothing recognizable following: literal '$'.
302
+ return Lit(text="$"), pos + 1
303
+
304
+
305
+ def _scan_dq_segments(src: str, pos: int) -> tuple[list[Segment], int]:
306
+ """`pos` is the index right after the opening '"'. Returns (segments, new_pos-after-closing-quote)."""
307
+ n = len(src)
308
+ segments: list[Segment] = []
309
+ buf: list[str] = []
310
+ i = pos
311
+
312
+ def flush() -> None:
313
+ if buf:
314
+ segments.append(Lit(text="".join(buf)))
315
+ buf.clear()
316
+
317
+ while i < n:
318
+ c = src[i]
319
+ if c == '"':
320
+ flush()
321
+ return segments, i + 1
322
+ if c == "\\" and i + 1 < n:
323
+ nxt = src[i + 1]
324
+ if nxt in ('"', "\\", "$", "`"):
325
+ buf.append(nxt)
326
+ i += 2
327
+ elif nxt == "\n":
328
+ i += 2
329
+ else:
330
+ buf.append(c)
331
+ buf.append(nxt)
332
+ i += 2
333
+ continue
334
+ if c == "$":
335
+ seg, newpos = _scan_dollar_form(src, i)
336
+ if isinstance(seg, Lit) and seg.text == "$" and newpos == i + 1:
337
+ buf.append("$")
338
+ i = newpos
339
+ continue
340
+ flush()
341
+ segments.append(seg)
342
+ i = newpos
343
+ continue
344
+ if c == "`":
345
+ j = i + 1
346
+ while j < n and src[j] != "`":
347
+ if src[j] == "\\" and j + 1 < n:
348
+ j += 2
349
+ else:
350
+ j += 1
351
+ if j >= n:
352
+ raise _unterminated("backtick")
353
+ flush()
354
+ segments.append(CmdSub(src=src[i + 1 : j]))
355
+ i = j + 1
356
+ continue
357
+ buf.append(c)
358
+ i += 1
359
+ raise _unterminated("double quote")
360
+
361
+
362
+ _WORD_BOUNDARY_CHARS = set("|&;()<> \t\n")
363
+ _EXTGLOB_PREFIX_CHARS = set("@!?*+")
364
+ _DRIVE_PREFIX_RE = re.compile(r"^[A-Za-z]:")
365
+
366
+
367
+ def _scan_word(src: str, pos: int) -> tuple[Word, int]:
368
+ n = len(src)
369
+ segments: list[Segment] = []
370
+ buf: list[str] = []
371
+ i = pos
372
+ at_word_start = True
373
+
374
+ def flush() -> None:
375
+ if buf:
376
+ segments.append(Raw(text="".join(buf)))
377
+ buf.clear()
378
+
379
+ while i < n:
380
+ c = src[i]
381
+ if at_word_start and c == "~":
382
+ j = i + 1
383
+ while j < n and src[j] not in _WORD_BOUNDARY_CHARS and src[j] not in "\"'\\$`/":
384
+ j += 1
385
+ segments.append(Tilde(user=src[i + 1 : j]))
386
+ i = j
387
+ at_word_start = False
388
+ continue
389
+ at_word_start = False
390
+ if c in _WORD_BOUNDARY_CHARS:
391
+ break
392
+ if c in _EXTGLOB_PREFIX_CHARS and src[i + 1 : i + 2] == "(":
393
+ raise UnsupportedConstruct(
394
+ "extended-glob", "Extended glob patterns ('@(...)','!(...)', etc.) are not supported."
395
+ )
396
+ if c == "{":
397
+ j = i + 1
398
+ depth = 1
399
+ has_comma = False
400
+ while j < n and depth > 0:
401
+ if src[j] == "{":
402
+ depth += 1
403
+ elif src[j] == "}":
404
+ depth -= 1
405
+ if depth == 0:
406
+ break
407
+ elif src[j] == "," and depth == 1:
408
+ has_comma = True
409
+ j += 1
410
+ if depth != 0:
411
+ buf.append(c)
412
+ i += 1
413
+ continue
414
+ if has_comma:
415
+ raise UnsupportedConstruct(
416
+ "brace-expansion", "Brace expansion ('{a,b,c}') is not supported; list the values explicitly."
417
+ )
418
+ buf.append(src[i : j + 1])
419
+ i = j + 1
420
+ continue
421
+ if c == "\\":
422
+ # Windows absolute paths: a backslash inside a word already recognized as a
423
+ # drive-letter path ('C:\...') or a UNC path ('\\server\...') is preserved
424
+ # literally rather than treated as a POSIX escape of the next character.
425
+ # Mirrors the TS router's identical heuristic (shell-contract-router.ts).
426
+ buf_text = "".join(buf)
427
+ if _DRIVE_PREFIX_RE.match(buf_text) or buf_text.startswith("\\\\"):
428
+ buf.append(c)
429
+ i += 1
430
+ continue
431
+ if not buf and not segments and src[i + 1 : i + 2] == "\\":
432
+ buf.append("\\\\")
433
+ i += 2
434
+ continue
435
+ if i + 1 < n:
436
+ flush()
437
+ segments.append(Lit(text=src[i + 1]))
438
+ i += 2
439
+ else:
440
+ buf.append(c)
441
+ i += 1
442
+ continue
443
+ if c == "'":
444
+ j = src.find("'", i + 1)
445
+ if j == -1:
446
+ raise _unterminated("single quote")
447
+ flush()
448
+ segments.append(Lit(text=src[i + 1 : j]))
449
+ i = j + 1
450
+ continue
451
+ if c == '"':
452
+ flush()
453
+ dq_segments, newpos = _scan_dq_segments(src, i + 1)
454
+ segments.append(DQ(segments=dq_segments))
455
+ i = newpos
456
+ continue
457
+ if c == "$" and src[i + 1 : i + 2] == "'":
458
+ j = i + 2
459
+ raw_chars: list[str] = []
460
+ while j < n and src[j] != "'":
461
+ if src[j] == "\\" and j + 1 < n:
462
+ raw_chars.append(src[j])
463
+ raw_chars.append(src[j + 1])
464
+ j += 2
465
+ else:
466
+ raw_chars.append(src[j])
467
+ j += 1
468
+ if j >= n:
469
+ raise _unterminated("$'...' quote")
470
+ flush()
471
+ segments.append(Lit(text=_ansi_c_unescape("".join(raw_chars))))
472
+ i = j + 1
473
+ continue
474
+ if c == "$":
475
+ seg, newpos = _scan_dollar_form(src, i)
476
+ if isinstance(seg, Lit) and seg.text == "$" and newpos == i + 1:
477
+ buf.append("$")
478
+ i = newpos
479
+ continue
480
+ flush()
481
+ segments.append(seg)
482
+ i = newpos
483
+ continue
484
+ if c == "`":
485
+ j = i + 1
486
+ while j < n and src[j] != "`":
487
+ if src[j] == "\\" and j + 1 < n:
488
+ j += 2
489
+ else:
490
+ j += 1
491
+ if j >= n:
492
+ raise _unterminated("backtick")
493
+ flush()
494
+ segments.append(CmdSub(src=src[i + 1 : j]))
495
+ i = j + 1
496
+ continue
497
+ buf.append(c)
498
+ i += 1
499
+ flush()
500
+ return Word(segments=segments), i
501
+
502
+
503
+ def _scan_operator(src: str, pos: int) -> tuple[str, int]:
504
+ """`src[pos]` starts an operator character. Returns (operator text, new_pos)."""
505
+ if src[pos : pos + 3] == "<<-":
506
+ raise UnsupportedConstruct("heredoc", "Heredocs ('<<-') are not supported; use a temp file or a literal argument.")
507
+ if src[pos : pos + 3] == "<<<":
508
+ raise UnsupportedConstruct("here-string", "Here-strings ('<<<') are not supported; pipe the value in instead.")
509
+ if src[pos : pos + 2] == "<<":
510
+ raise UnsupportedConstruct("heredoc", "Heredocs ('<<') are not supported; use a temp file or a literal argument.")
511
+ if src[pos : pos + 2] == "&>":
512
+ return "&>", pos + 2
513
+ if src[pos : pos + 2] == "&&":
514
+ return "&&", pos + 2
515
+ if src[pos : pos + 2] == "||":
516
+ return "||", pos + 2
517
+ if src[pos : pos + 2] == ">>":
518
+ return ">>", pos + 2
519
+ if src[pos : pos + 2] == ">&":
520
+ j = pos + 2
521
+ while j < len(src) and src[j].isdigit():
522
+ j += 1
523
+ return src[pos:j], j
524
+ if src[pos] == "<" and src[pos + 1 : pos + 2] == "(":
525
+ raise UnsupportedConstruct("process-substitution", "Process substitution ('<(...)') is not supported.")
526
+ if src[pos] == ">" and src[pos + 1 : pos + 2] == "(":
527
+ raise UnsupportedConstruct("process-substitution", "Process substitution ('>(...)') is not supported.")
528
+ if src[pos] in "|&;(){}<>":
529
+ return src[pos], pos + 1
530
+ raise AssertionError(f"unreachable operator dispatch at {pos!r}")
531
+
532
+
533
+ def tokenize(src: str) -> list[Token]:
534
+ n = len(src)
535
+ tokens: list[Token] = []
536
+ pos = 0
537
+ while pos < n:
538
+ c = src[pos]
539
+ if c in " \t":
540
+ pos += 1
541
+ continue
542
+ if c == "\n":
543
+ tokens.append(Token(kind="OP", text="\n"))
544
+ pos += 1
545
+ continue
546
+ if c == "\\" and src[pos + 1 : pos + 2] == "\n":
547
+ pos += 2
548
+ continue
549
+ # An unquoted # starts a comment only at a token boundary. A # inside a
550
+ # word (for example a#b) and a quoted # are ordinary data.
551
+ if c == "#" and (pos == 0 or src[pos - 1] in " \t\n;|&()"):
552
+ newline = src.find("\n", pos)
553
+ pos = n if newline == -1 else newline
554
+ continue
555
+ if src[pos : pos + 2] == "((":
556
+ raise UnsupportedConstruct("arithmetic-expansion", "Arithmetic command '((...))' is not supported.")
557
+ if c.isdigit():
558
+ j = pos
559
+ while j < n and src[j].isdigit():
560
+ j += 1
561
+ if j < n and src[j] in "<>":
562
+ op_text, newpos = _scan_operator(src, j)
563
+ tokens.append(Token(kind="OP", text=src[pos:j] + op_text))
564
+ pos = newpos
565
+ continue
566
+ if c == "{" and not (pos + 1 >= n or src[pos + 1] in " \t\n"):
567
+ word, newpos = _scan_word(src, pos)
568
+ tokens.append(Token(kind="WORD", segments=word.segments))
569
+ pos = newpos
570
+ continue
571
+ if c in "|&;(){}<>":
572
+ op_text, newpos = _scan_operator(src, pos)
573
+ tokens.append(Token(kind="OP", text=op_text))
574
+ pos = newpos
575
+ continue
576
+ word, newpos = _scan_word(src, pos)
577
+ tokens.append(Token(kind="WORD", segments=word.segments))
578
+ pos = newpos
579
+ return tokens
@@ -43,20 +43,30 @@ compounding saving is the feature.
43
43
  `Check`. Repairs are O(validation-errors), not O(schema): a static
44
44
  `(expect, got)` dispatch Map, precompiled matchers, no RegExp/schema
45
45
  compilation/JSON parse per call except the one a mode explicitly needs.
46
- Bounded work: ≤1 clone, ≤1 transform per failing path, ≤1 sub-Check per
47
- transform, exactly 1 whole-args re-Check, no transform loops. A microbench
48
- fixture GATES this (clean-path cost within noise of a bare Check). Adding
46
+ Bounded work: ≤1 clone, ≤1 transform per failing path per pass, ≤1
47
+ sub-Check per transform, up to `MAX_REPAIR_PASSES` (3, `repairer.ts`)
48
+ whole-args re-Checks a BOUNDED multi-pass, not an unconditional loop: one
49
+ pass's transform can expose an error a fresh validator walk must see (an
50
+ outer json-string-parse turning a stringified object into a real object
51
+ whose own property-case/scalar drift was invisible to the first pass's
52
+ error list). The bound is the deepest TESTED cascade (2 passes) plus one
53
+ margin layer, not an arbitrary ceiling — test-enforced in
54
+ `tool-repair.test.ts`. A microbench fixture GATES this (clean-path cost
55
+ within noise of a bare Check; repaired-path under a fixed budget). Adding
49
56
  the 20th failure mode must cost the hot path nothing.
50
57
  3. **Shape repairs only.** A repair may reshape what the model clearly meant
51
58
  (parse a stringified array, wrap a bare item, drop a null optional). It may
52
59
  never invent a value. Required-but-null, cross-field constraints, and
53
- semantic errors are relational: bounce those to the model. The current
54
- `coercePrimitiveByType` null-to-zero-value behavior violates this rule and
55
- is scheduled to be replaced by the catalogue's null rule.
60
+ semantic errors are relational: bounce those to the model. The catalogue's
61
+ null rule is what's live (`nullOptionalDrop`/`nullRequiredBounce`): an
62
+ optional `null` is dropped; a required `null` bounces with feedback.
63
+ Nothing invents a zero-value substitute.
56
64
  4. **Uniform across schema kinds.** TypeBox tools (built-ins) and plain
57
- JSON-schema tools (MCP, extensions) get the same repair set. Today
58
- built-ins get FEWER repairs (the `hasTypeBoxMetadata` guard skips the
59
- coercion pass); that asymmetry is a defect, not a design.
65
+ JSON-schema tools (MCP, extensions) get the same repair set: every schema
66
+ compiles through the one TypeBox validator (`validation.ts`'s
67
+ `getValidator`, shared with `repairer.ts` per decision D3) regardless of
68
+ its origin, so there is no separate coercion pass that only some tools
69
+ reach.
60
70
  5. **Every repair is check-guarded and ordered.** Apply on a cloned candidate,
61
71
  keep only if the sub-check passes. Within string-where-array-expected, try
62
72
  JSON.parse FIRST and wrap second, or `'["a","b"]'` becomes `['["a","b"]']`.
@@ -41,8 +41,23 @@ Rules that keep this deterministic and safe:
41
41
  stringified array becomes an array, not a wrapped string. Across paths:
42
42
  instance-path order. Root property-key casing repair runs before these per-path
43
43
  transforms because required-property validator errors do not carry the misspelled key path.
44
- - **One re-Check.** After all per-path transforms, Check the whole args once.
45
- Pass → return repaired; failbounce. Never loop transforms.
44
+ - **Bounded multi-pass.** After all per-path transforms, Check the whole args
45
+ once. Pass → return repaired. Failrepeat the walk-transform-Check cycle,
46
+ up to `MAX_REPAIR_PASSES` (3, `repairer.ts`) whole-args re-Checks total;
47
+ still failing after the bound → bounce. This is a sanctioned BOUNDED loop
48
+ (decision D1), not the unconditional retry banned elsewhere in this file: a
49
+ real cascade needs it because one pass's transform can expose an error a
50
+ fresh validator walk must see — e.g. an outer `jsonStringParse` (mode 2)
51
+ turns a stringified object into a real object whose OWN properties
52
+ (`propertyCaseNormalize`, `numberFromString`, ...) were invisible to the
53
+ first pass's error list, since those errors only exist once the outer
54
+ string is a real object. Each pass is still O(validation-errors) via the
55
+ same static dispatch, so total cost across the bound stays small and
56
+ linear; a microbench (D2) gates the repaired-path budget. The bound is the
57
+ deepest TESTED cascade (2 passes, the json-string-parse-then-nested-fixture
58
+ case) plus one margin layer — not an arbitrary ceiling; a test
59
+ (`tool-repair.test.ts`, "repair multi-pass bound (D1)") fails if any tested
60
+ cascade needs more passes than the bound allows.
46
61
  - Modes 2b and 6–11 are the increment past the original four; each is guard-gated so
47
62
  it can only ever turn an invalid call into a valid one, never change a
48
63
  valid call (the hot path never reaches them — see Performance).
@@ -119,9 +134,11 @@ The failure grammar only ever runs on ALREADY-FAILED calls. The hot path
119
134
  at module load. Nothing in the repair path constructs a RegExp, compiles a
120
135
  schema, or parses JSON except the one `JSON.parse` a mode explicitly needs.
121
136
  4. **Bounded work.** At most: one clone of args, one transform per failing
122
- path, one sub-Check per attempted transform, one whole-args re-Check. No
123
- loops over transforms, no backtracking search. Worst case is linear in the
124
- number of validation errors, which is itself tiny.
137
+ path PER PASS, one sub-Check per attempted transform, up to
138
+ `MAX_REPAIR_PASSES` (3) whole-args re-Checks (decision D1's sanctioned
139
+ bounded multi-pass see above; not an unbounded loop, no backtracking
140
+ search). Worst case is linear in the number of validation errors times the
141
+ pass bound, both of which are themselves tiny.
125
142
  5. **Text protocol only for flagged models.** The parser (R38) runs only when
126
143
  a model is configured for text mode; native-tool-call models never invoke
127
144
  it. The primer is generated once per session, not per turn.
@@ -41,7 +41,9 @@ Registry mode names currently in force:
41
41
  - Repair: delete key P from its parent object.
42
42
  - If P IS required: no repair. Bounce. Inventing `0`/`""`/`false` corrupts
43
43
  intent (`limit: null` becoming `limit: 0` changes the program). This
44
- replaces the current `coercePrimitiveByType` null branches.
44
+ replaced the old `coercePrimitiveByType` null-to-zero-value branches, which
45
+ are gone from the code (verified: zero references in `validation.ts` /
46
+ `tool-repair/`).
45
47
 
46
48
  ### 2. json-string-encoded array or object (`jsonStringParse`)
47
49
  - Error signature: expected array (or object) at P, received string.
@@ -102,11 +104,9 @@ touching the live path.
102
104
  |---|---|---|
103
105
  | Streaming args assembly | each provider, `parseStreamingJson(partialJson)`; e.g. `openai-completions.ts` ~:382, `anthropic.ts` ~:623 | tolerant partial parse; no repair here (correct; keep providers dumb) |
104
106
  | Blind pre-repair hook | `Tool.prepareArguments`, only user: `edit.ts` `prepareEditArguments` ~:95 | legacy special case of repair 2 for `edits` only (comment names GLM-5.1); delete once general repair lands |
105
- | Scalar conversion | `validation.ts` ~:294 `Value.Convert` | fine (string "5" to 5 etc.) |
106
- | Custom coercion | `validation.ts` `coerceWithJsonSchema` ~:205 | runs ONLY for non-TypeBox schemas (`hasTypeBoxMetadata` guard ~:297): built-ins get fewer repairs, backwards. null-to-zero-value branches ~:80-145 violate the relational rule |
107
- | Check + error | `validation.ts` ~:311-323 | per-path errors + received args; does NOT echo expected schema fragment |
107
+ | Check + error | `validation.ts` `validateToolArguments` ~:409-467, `getValidator` ~:97 | ONE TypeBox-compiled validator per schema regardless of origin (D5: the old ad-hoc `coerceWithJsonSchema`/`coerceWithUnionSchema`/`Value.Convert` coercion layer and its `hasTypeBoxMetadata` non-TypeBox-only guard are gone from the code — grep confirms zero references); per-path errors + received args feed `analyzer.ts`; does NOT itself echo the expected schema fragment (see gap 3 below) |
108
108
  | Failure feedback | `agent-loop.ts` ~:700-704 | validation error becomes error tool result; model-side retry is the only recovery today |
109
- | Check-guarded pattern precedent | `validation.ts` `coerceWithUnionSchema` ~:193 | clone, coerce, Check; reuse this shape for all repairs |
109
+ | Check-guarded pattern precedent | `repairer.ts` `repairToolArguments` ~:376-420 | clone, transform, sub-Check, keep-iff-passes; every named repair in the registry follows this shape (decision 5) |
110
110
 
111
111
  ## Adjacent gap backlog (separate items, code-anchored)
112
112