@tacuchi/agent-workflow-cli 25.8.0 → 26.0.0

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 (558) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/README.md +6 -3
  3. package/dist/adapters/git-cli.js +225 -17
  4. package/dist/adapters/git-cli.js.map +1 -1
  5. package/dist/adapters/node-file-system.js +48 -0
  6. package/dist/adapters/node-file-system.js.map +1 -1
  7. package/dist/application/amend-service.js +51 -14
  8. package/dist/application/amend-service.js.map +1 -1
  9. package/dist/application/branch-resolver.js +6 -3
  10. package/dist/application/branch-resolver.js.map +1 -1
  11. package/dist/application/capability/design-handler.js +218 -43
  12. package/dist/application/capability/design-handler.js.map +1 -1
  13. package/dist/application/capability/dispatcher.js +182 -19
  14. package/dist/application/capability/dispatcher.js.map +1 -1
  15. package/dist/application/capability/durable-effect.js +3 -0
  16. package/dist/application/capability/durable-effect.js.map +1 -1
  17. package/dist/application/capability/readiness.js +8 -54
  18. package/dist/application/capability/readiness.js.map +1 -1
  19. package/dist/application/capability/resolution.js +124 -192
  20. package/dist/application/capability/resolution.js.map +1 -1
  21. package/dist/application/check-branch-service.js +158 -19
  22. package/dist/application/check-branch-service.js.map +1 -1
  23. package/dist/application/checkpoint/markdown.js +2 -2
  24. package/dist/application/checkpoint/markdown.js.map +1 -1
  25. package/dist/application/checkpoint/state-reader.js +12 -0
  26. package/dist/application/checkpoint/state-reader.js.map +1 -1
  27. package/dist/application/checkpoint-service.js +12 -4
  28. package/dist/application/checkpoint-service.js.map +1 -1
  29. package/dist/application/checkpoint-write-service.js +91 -17
  30. package/dist/application/checkpoint-write-service.js.map +1 -1
  31. package/dist/application/claims-ledger.js +137 -11
  32. package/dist/application/claims-ledger.js.map +1 -1
  33. package/dist/application/claims-recovery.js +85 -44
  34. package/dist/application/claims-recovery.js.map +1 -1
  35. package/dist/application/database-tool-catalog.js +33 -0
  36. package/dist/application/database-tool-catalog.js.map +1 -1
  37. package/dist/application/design/consumer-document.js +2 -2
  38. package/dist/application/design/consumer-document.js.map +1 -1
  39. package/dist/application/design/design-content-gate-service.js +20 -2
  40. package/dist/application/design/design-content-gate-service.js.map +1 -1
  41. package/dist/application/design/design-gate-service.js +2 -0
  42. package/dist/application/design/design-gate-service.js.map +1 -1
  43. package/dist/application/design/design-index-service.js +4 -0
  44. package/dist/application/design/design-index-service.js.map +1 -1
  45. package/dist/application/design/design-publish-service.js +1 -4
  46. package/dist/application/design/design-publish-service.js.map +1 -1
  47. package/dist/application/design/design-record-service.js +13 -7
  48. package/dist/application/design/design-record-service.js.map +1 -1
  49. package/dist/application/design/design-resolver-service.js +22 -3
  50. package/dist/application/design/design-resolver-service.js.map +1 -1
  51. package/dist/application/design/design-simple-service.js +24 -5
  52. package/dist/application/design/design-simple-service.js.map +1 -1
  53. package/dist/application/design/digest.js +41 -0
  54. package/dist/application/design/digest.js.map +1 -0
  55. package/dist/application/dev-only-services.js +166 -20
  56. package/dist/application/dev-only-services.js.map +1 -1
  57. package/dist/application/doc-branch-ledger.js +145 -0
  58. package/dist/application/doc-branch-ledger.js.map +1 -0
  59. package/dist/application/docs-canon-service.js +1 -1
  60. package/dist/application/docs-canon-service.js.map +1 -1
  61. package/dist/application/doctor/dist-integrity.js +113 -0
  62. package/dist/application/doctor/dist-integrity.js.map +1 -0
  63. package/dist/application/doctor/hosts.js +5 -2
  64. package/dist/application/doctor/hosts.js.map +1 -1
  65. package/dist/application/doctor/prepare.js +3 -3
  66. package/dist/application/doctor/prepare.js.map +1 -1
  67. package/dist/application/doctor/provider-installation.js +39 -19
  68. package/dist/application/doctor/provider-installation.js.map +1 -1
  69. package/dist/application/doctor/provider-mcps.js +9 -1
  70. package/dist/application/doctor/provider-mcps.js.map +1 -1
  71. package/dist/application/doctor/provider-skills.js +29 -115
  72. package/dist/application/doctor/provider-skills.js.map +1 -1
  73. package/dist/application/doctor/provider-visibility.js +76 -3
  74. package/dist/application/doctor/provider-visibility.js.map +1 -1
  75. package/dist/application/doctor/provider-workspace-block.js +156 -0
  76. package/dist/application/doctor/provider-workspace-block.js.map +1 -0
  77. package/dist/application/doctor/repair-runner.js +36 -39
  78. package/dist/application/doctor/repair-runner.js.map +1 -1
  79. package/dist/application/doctor/report.js +24 -4
  80. package/dist/application/doctor/report.js.map +1 -1
  81. package/dist/application/export-catalog-check.js +200 -0
  82. package/dist/application/export-catalog-check.js.map +1 -0
  83. package/dist/application/export-service.js +716 -79
  84. package/dist/application/export-service.js.map +1 -1
  85. package/dist/application/fix-git-service.js +285 -64
  86. package/dist/application/fix-git-service.js.map +1 -1
  87. package/dist/application/flow/advance.js +202 -25
  88. package/dist/application/flow/advance.js.map +1 -1
  89. package/dist/application/flow/annul-service.js +3 -1
  90. package/dist/application/flow/annul-service.js.map +1 -1
  91. package/dist/application/flow/batch-commit.js +189 -0
  92. package/dist/application/flow/batch-commit.js.map +1 -0
  93. package/dist/application/flow/checkout-observation.js +63 -10
  94. package/dist/application/flow/checkout-observation.js.map +1 -1
  95. package/dist/application/flow/close-artifacts.js +105 -0
  96. package/dist/application/flow/close-artifacts.js.map +1 -0
  97. package/dist/application/flow/close-at-boundary.js +25 -14
  98. package/dist/application/flow/close-at-boundary.js.map +1 -1
  99. package/dist/application/flow/close-document-guidance.js +70 -0
  100. package/dist/application/flow/close-document-guidance.js.map +1 -0
  101. package/dist/application/flow/flow-service.js +46 -3
  102. package/dist/application/flow/flow-service.js.map +1 -1
  103. package/dist/application/flow/internal-actions.js +300 -82
  104. package/dist/application/flow/internal-actions.js.map +1 -1
  105. package/dist/application/flow/internal-drive.js +24 -1
  106. package/dist/application/flow/internal-drive.js.map +1 -1
  107. package/dist/application/flow/plan-entry.js +82 -0
  108. package/dist/application/flow/plan-entry.js.map +1 -0
  109. package/dist/application/flow/prove.js +32 -1
  110. package/dist/application/flow/prove.js.map +1 -1
  111. package/dist/application/flow/quick-checkouts.js +48 -0
  112. package/dist/application/flow/quick-checkouts.js.map +1 -0
  113. package/dist/application/flow/reinfer-batch.js +177 -0
  114. package/dist/application/flow/reinfer-batch.js.map +1 -0
  115. package/dist/application/flow/reopen-run.js +12 -5
  116. package/dist/application/flow/reopen-run.js.map +1 -1
  117. package/dist/application/flow/run-state-service.js +2 -0
  118. package/dist/application/flow/run-state-service.js.map +1 -1
  119. package/dist/application/flow/submit.js +584 -117
  120. package/dist/application/flow/submit.js.map +1 -1
  121. package/dist/application/generate-launch-service.js +16 -6
  122. package/dist/application/generate-launch-service.js.map +1 -1
  123. package/dist/application/git-flow-service.js +34 -3
  124. package/dist/application/git-flow-service.js.map +1 -1
  125. package/dist/application/history-publications.js +24 -0
  126. package/dist/application/history-publications.js.map +1 -1
  127. package/dist/application/history-reconcile-service.js +45 -0
  128. package/dist/application/history-reconcile-service.js.map +1 -0
  129. package/dist/application/history-table.js +61 -12
  130. package/dist/application/history-table.js.map +1 -1
  131. package/dist/application/history-update-service.js +25 -4
  132. package/dist/application/history-update-service.js.map +1 -1
  133. package/dist/application/hook-branch-check.js +25 -3
  134. package/dist/application/hook-branch-check.js.map +1 -1
  135. package/dist/application/hook-git-commit-advisor.js +3 -4
  136. package/dist/application/hook-git-commit-advisor.js.map +1 -1
  137. package/dist/application/hook-turn-start.js +51 -0
  138. package/dist/application/hook-turn-start.js.map +1 -0
  139. package/dist/application/host-memory/codex.js +1 -1
  140. package/dist/application/host-memory/codex.js.map +1 -1
  141. package/dist/application/hub-registry.js +135 -0
  142. package/dist/application/hub-registry.js.map +1 -0
  143. package/dist/application/local-proposal.js +72 -19
  144. package/dist/application/local-proposal.js.map +1 -1
  145. package/dist/application/mcp-host-reader.js +1 -1
  146. package/dist/application/mcp-host-reader.js.map +1 -1
  147. package/dist/application/mcp-host-writer.js +16 -10
  148. package/dist/application/mcp-host-writer.js.map +1 -1
  149. package/dist/application/merge-state-service.js +150 -34
  150. package/dist/application/merge-state-service.js.map +1 -1
  151. package/dist/application/multiroot/claude.js +17 -10
  152. package/dist/application/multiroot/claude.js.map +1 -1
  153. package/dist/application/multiroot/codex.js +17 -11
  154. package/dist/application/multiroot/codex.js.map +1 -1
  155. package/dist/application/multiroot-service.js +52 -28
  156. package/dist/application/multiroot-service.js.map +1 -1
  157. package/dist/application/parsers/execution-batches.js +64 -0
  158. package/dist/application/parsers/execution-batches.js.map +1 -0
  159. package/dist/application/parsers/phases.js +23 -2
  160. package/dist/application/parsers/phases.js.map +1 -1
  161. package/dist/application/parsers/project-block.js +146 -17
  162. package/dist/application/parsers/project-block.js.map +1 -1
  163. package/dist/application/parsers/tasks.js +16 -2
  164. package/dist/application/parsers/tasks.js.map +1 -1
  165. package/dist/application/parsers/toml.js +19 -0
  166. package/dist/application/parsers/toml.js.map +1 -0
  167. package/dist/application/paths-service.js +13 -16
  168. package/dist/application/paths-service.js.map +1 -1
  169. package/dist/application/persist-service.js +118 -5
  170. package/dist/application/persist-service.js.map +1 -1
  171. package/dist/application/plan-exec-batch-service.js +162 -22
  172. package/dist/application/plan-exec-batch-service.js.map +1 -1
  173. package/dist/application/plan-exec-decision-service.js +61 -12
  174. package/dist/application/plan-exec-decision-service.js.map +1 -1
  175. package/dist/application/plan-exec-plan-diff.js +105 -0
  176. package/dist/application/plan-exec-plan-diff.js.map +1 -0
  177. package/dist/application/plan-lint-service.js +33 -5
  178. package/dist/application/plan-lint-service.js.map +1 -1
  179. package/dist/application/plan-passes.js +41 -0
  180. package/dist/application/plan-passes.js.map +1 -0
  181. package/dist/application/preparation-receipts.js +58 -0
  182. package/dist/application/preparation-receipts.js.map +1 -0
  183. package/dist/application/project-md-upsert-service.js +191 -52
  184. package/dist/application/project-md-upsert-service.js.map +1 -1
  185. package/dist/application/project-tab-data.js +40 -10
  186. package/dist/application/project-tab-data.js.map +1 -1
  187. package/dist/application/release-data/artifacts.js +15 -7
  188. package/dist/application/release-data/artifacts.js.map +1 -1
  189. package/dist/application/release-data/bundles.js +52 -6
  190. package/dist/application/release-data/bundles.js.map +1 -1
  191. package/dist/application/release-data/common.js +2 -2
  192. package/dist/application/release-data/common.js.map +1 -1
  193. package/dist/application/release-data/rollback.js +7 -0
  194. package/dist/application/release-data/rollback.js.map +1 -0
  195. package/dist/application/release-data/sessions.js +2 -2
  196. package/dist/application/release-data/sessions.js.map +1 -1
  197. package/dist/application/release-pass-ledger.js +1 -1
  198. package/dist/application/render/history-row.js +2 -0
  199. package/dist/application/render/history-row.js.map +1 -1
  200. package/dist/application/render/project-block.js +28 -11
  201. package/dist/application/render/project-block.js.map +1 -1
  202. package/dist/application/reseal-service.js +1 -0
  203. package/dist/application/reseal-service.js.map +1 -1
  204. package/dist/application/resume-service.js +55 -8
  205. package/dist/application/resume-service.js.map +1 -1
  206. package/dist/application/retirement/apply.js +25 -7
  207. package/dist/application/retirement/apply.js.map +1 -1
  208. package/dist/application/retirement/attribution.js +122 -50
  209. package/dist/application/retirement/attribution.js.map +1 -1
  210. package/dist/application/retirement/prepare.js +17 -11
  211. package/dist/application/retirement/prepare.js.map +1 -1
  212. package/dist/application/retirement/preview.js +2 -1
  213. package/dist/application/retirement/preview.js.map +1 -1
  214. package/dist/application/self/clean-legacy.js +1 -2
  215. package/dist/application/self/clean-legacy.js.map +1 -1
  216. package/dist/application/self/codex-plugin.js +1 -1
  217. package/dist/application/self/codex-plugin.js.map +1 -1
  218. package/dist/application/self/host-states.js +3 -3
  219. package/dist/application/self/host-states.js.map +1 -1
  220. package/dist/application/self/install-hooks.js +1 -1
  221. package/dist/application/self/install-hooks.js.map +1 -1
  222. package/dist/application/self/install-skill.js +5 -49
  223. package/dist/application/self/install-skill.js.map +1 -1
  224. package/dist/application/self/mcp-config.js +19 -11
  225. package/dist/application/self/mcp-config.js.map +1 -1
  226. package/dist/application/self/opencode-plugin.js +1 -0
  227. package/dist/application/self/opencode-plugin.js.map +1 -1
  228. package/dist/application/self/skill-files.js +29 -0
  229. package/dist/application/self/skill-files.js.map +1 -0
  230. package/dist/application/self/uninstall.js +1 -1
  231. package/dist/application/self/uninstall.js.map +1 -1
  232. package/dist/application/semantic-operation/protocol.js +66 -5
  233. package/dist/application/semantic-operation/protocol.js.map +1 -1
  234. package/dist/application/session-archive-service.js +113 -0
  235. package/dist/application/session-archive-service.js.map +1 -0
  236. package/dist/application/session-binding-service.js +35 -0
  237. package/dist/application/session-binding-service.js.map +1 -1
  238. package/dist/application/session-close-service.js +390 -54
  239. package/dist/application/session-close-service.js.map +1 -1
  240. package/dist/application/session-create-service.js +97 -5
  241. package/dist/application/session-create-service.js.map +1 -1
  242. package/dist/application/session-custody-recorder.js +15 -12
  243. package/dist/application/session-custody-recorder.js.map +1 -1
  244. package/dist/application/session-custody-service.js +1 -0
  245. package/dist/application/session-custody-service.js.map +1 -1
  246. package/dist/application/session-narrative.js +42 -12
  247. package/dist/application/session-narrative.js.map +1 -1
  248. package/dist/application/session-pause-service.js +46 -0
  249. package/dist/application/session-pause-service.js.map +1 -0
  250. package/dist/application/session-resolver.js +36 -11
  251. package/dist/application/session-resolver.js.map +1 -1
  252. package/dist/application/session-resume-service.js +134 -13
  253. package/dist/application/session-resume-service.js.map +1 -1
  254. package/dist/application/sessions-service.js +4 -0
  255. package/dist/application/sessions-service.js.map +1 -1
  256. package/dist/application/sessions-sweep-service.js +77 -0
  257. package/dist/application/sessions-sweep-service.js.map +1 -0
  258. package/dist/application/settle-service.js +3 -1
  259. package/dist/application/settle-service.js.map +1 -1
  260. package/dist/application/skills-resolver-service.js +6 -92
  261. package/dist/application/skills-resolver-service.js.map +1 -1
  262. package/dist/application/source-add-service.js +37 -0
  263. package/dist/application/source-add-service.js.map +1 -0
  264. package/dist/application/source-boundary-policy.js +105 -8
  265. package/dist/application/source-boundary-policy.js.map +1 -1
  266. package/dist/application/source-pipeline.js +68 -0
  267. package/dist/application/source-pipeline.js.map +1 -0
  268. package/dist/application/source-remove-service.js +15 -3
  269. package/dist/application/source-remove-service.js.map +1 -1
  270. package/dist/application/sources-service.js +71 -16
  271. package/dist/application/sources-service.js.map +1 -1
  272. package/dist/application/status-service.js +55 -5
  273. package/dist/application/status-service.js.map +1 -1
  274. package/dist/application/unit-dependencies.js +100 -0
  275. package/dist/application/unit-dependencies.js.map +1 -0
  276. package/dist/application/unit-membership.js +37 -0
  277. package/dist/application/unit-membership.js.map +1 -0
  278. package/dist/application/unit-residue.js +72 -0
  279. package/dist/application/unit-residue.js.map +1 -0
  280. package/dist/application/visibility-doctor-service.js +66 -4
  281. package/dist/application/visibility-doctor-service.js.map +1 -1
  282. package/dist/application/working-branch-service.js +6 -0
  283. package/dist/application/working-branch-service.js.map +1 -1
  284. package/dist/application/workline-graph.js +1 -1
  285. package/dist/application/workline-graph.js.map +1 -1
  286. package/dist/application/workline-index-service.js +118 -17
  287. package/dist/application/workline-index-service.js.map +1 -1
  288. package/dist/application/workspace-commit-service.js +218 -0
  289. package/dist/application/workspace-commit-service.js.map +1 -0
  290. package/dist/application/workspace-init-service.js +64 -34
  291. package/dist/application/workspace-init-service.js.map +1 -1
  292. package/dist/application/workspace-local-config.js +90 -0
  293. package/dist/application/workspace-local-config.js.map +1 -0
  294. package/dist/application/workspace-materialization-service.js +52 -3
  295. package/dist/application/workspace-materialization-service.js.map +1 -1
  296. package/dist/application/workspace-migrate/apply.js +525 -4
  297. package/dist/application/workspace-migrate/apply.js.map +1 -1
  298. package/dist/application/workspace-migrate/markers.js +9 -6
  299. package/dist/application/workspace-migrate/markers.js.map +1 -1
  300. package/dist/application/workspace-migrate/plan.js +97 -5
  301. package/dist/application/workspace-migrate/plan.js.map +1 -1
  302. package/dist/application/workspace-move-service.js +270 -0
  303. package/dist/application/workspace-move-service.js.map +1 -0
  304. package/dist/application/workspace-untrack-service.js +28 -0
  305. package/dist/application/workspace-untrack-service.js.map +1 -0
  306. package/dist/application/worktree-service.js +654 -105
  307. package/dist/application/worktree-service.js.map +1 -1
  308. package/dist/cli/ascii.js +2 -0
  309. package/dist/cli/ascii.js.map +1 -1
  310. package/dist/cli/commands/add-source.js +38 -0
  311. package/dist/cli/commands/add-source.js.map +1 -0
  312. package/dist/cli/commands/amend.js +14 -3
  313. package/dist/cli/commands/amend.js.map +1 -1
  314. package/dist/cli/commands/capability.js +23 -4
  315. package/dist/cli/commands/capability.js.map +1 -1
  316. package/dist/cli/commands/designs.js +14 -5
  317. package/dist/cli/commands/designs.js.map +1 -1
  318. package/dist/cli/commands/dev-only.js +19 -6
  319. package/dist/cli/commands/dev-only.js.map +1 -1
  320. package/dist/cli/commands/doc-branch.js +184 -0
  321. package/dist/cli/commands/doc-branch.js.map +1 -0
  322. package/dist/cli/commands/doctor.js +5 -1
  323. package/dist/cli/commands/doctor.js.map +1 -1
  324. package/dist/cli/commands/export.js +78 -18
  325. package/dist/cli/commands/export.js.map +1 -1
  326. package/dist/cli/commands/fix-git.js +89 -14
  327. package/dist/cli/commands/fix-git.js.map +1 -1
  328. package/dist/cli/commands/flow.js +120 -15
  329. package/dist/cli/commands/flow.js.map +1 -1
  330. package/dist/cli/commands/generate-launch.js +14 -2
  331. package/dist/cli/commands/generate-launch.js.map +1 -1
  332. package/dist/cli/commands/history-update.js +1 -1
  333. package/dist/cli/commands/history-update.js.map +1 -1
  334. package/dist/cli/commands/history.js +14 -0
  335. package/dist/cli/commands/history.js.map +1 -0
  336. package/dist/cli/commands/hook.js +15 -2
  337. package/dist/cli/commands/hook.js.map +1 -1
  338. package/dist/cli/commands/index.js +18 -5
  339. package/dist/cli/commands/index.js.map +1 -1
  340. package/dist/cli/commands/merge-state.js +2 -2
  341. package/dist/cli/commands/merge-state.js.map +1 -1
  342. package/dist/cli/commands/persist.js +6 -5
  343. package/dist/cli/commands/persist.js.map +1 -1
  344. package/dist/cli/commands/project-md-upsert.js +5 -3
  345. package/dist/cli/commands/project-md-upsert.js.map +1 -1
  346. package/dist/cli/commands/release-pass.js +3 -3
  347. package/dist/cli/commands/release-pass.js.map +1 -1
  348. package/dist/cli/commands/resume.js +12 -3
  349. package/dist/cli/commands/resume.js.map +1 -1
  350. package/dist/cli/commands/self.js +8 -24
  351. package/dist/cli/commands/self.js.map +1 -1
  352. package/dist/cli/commands/session-close.js +64 -9
  353. package/dist/cli/commands/session-close.js.map +1 -1
  354. package/dist/cli/commands/session-create.js +4 -2
  355. package/dist/cli/commands/session-create.js.map +1 -1
  356. package/dist/cli/commands/session-pause.js +14 -0
  357. package/dist/cli/commands/session-pause.js.map +1 -0
  358. package/dist/cli/commands/sessions.js +16 -3
  359. package/dist/cli/commands/sessions.js.map +1 -1
  360. package/dist/cli/commands/set-branch.js +28 -4
  361. package/dist/cli/commands/set-branch.js.map +1 -1
  362. package/dist/cli/commands/set-edit-mode.js +20 -0
  363. package/dist/cli/commands/set-edit-mode.js.map +1 -0
  364. package/dist/cli/commands/set-pipeline.js +35 -0
  365. package/dist/cli/commands/set-pipeline.js.map +1 -0
  366. package/dist/cli/commands/skills.js +4 -11
  367. package/dist/cli/commands/skills.js.map +1 -1
  368. package/dist/cli/commands/sources.js +4 -0
  369. package/dist/cli/commands/sources.js.map +1 -1
  370. package/dist/cli/commands/status.js +35 -2
  371. package/dist/cli/commands/status.js.map +1 -1
  372. package/dist/cli/commands/unknown-flags.js +1 -0
  373. package/dist/cli/commands/unknown-flags.js.map +1 -1
  374. package/dist/cli/commands/visibility.js +1 -0
  375. package/dist/cli/commands/visibility.js.map +1 -1
  376. package/dist/cli/commands/workspace-commit.js +62 -0
  377. package/dist/cli/commands/workspace-commit.js.map +1 -0
  378. package/dist/cli/commands/workspace-init.js +39 -2
  379. package/dist/cli/commands/workspace-init.js.map +1 -1
  380. package/dist/cli/commands/workspace-migrate.js +31 -3
  381. package/dist/cli/commands/workspace-migrate.js.map +1 -1
  382. package/dist/cli/commands/workspace-move.js +42 -0
  383. package/dist/cli/commands/workspace-move.js.map +1 -0
  384. package/dist/cli/commands/worktree.js +4 -4
  385. package/dist/cli/commands/worktree.js.map +1 -1
  386. package/dist/cli/context-id.js +6 -0
  387. package/dist/cli/context-id.js.map +1 -1
  388. package/dist/cli/full-cli.js +555 -0
  389. package/dist/cli/full-cli.js.map +1 -0
  390. package/dist/cli/help-groups.js +76 -19
  391. package/dist/cli/help-groups.js.map +1 -1
  392. package/dist/cli/hook-stdin-cache.js +12 -0
  393. package/dist/cli/hook-stdin-cache.js.map +1 -0
  394. package/dist/cli/main.js +47 -453
  395. package/dist/cli/main.js.map +1 -1
  396. package/dist/cli/parser.js +4 -0
  397. package/dist/cli/parser.js.map +1 -1
  398. package/dist/cli/tui/app.js +3 -4
  399. package/dist/cli/tui/app.js.map +1 -1
  400. package/dist/cli/tui/components/host-admin-section.js +2 -13
  401. package/dist/cli/tui/components/host-admin-section.js.map +1 -1
  402. package/dist/cli/tui/components/tabs-config.js +1 -2
  403. package/dist/cli/tui/components/tabs-config.js.map +1 -1
  404. package/dist/cli/tui/components/workspace-init-form.js +4 -1
  405. package/dist/cli/tui/components/workspace-init-form.js.map +1 -1
  406. package/dist/cli/tui/data/workflow-content.js +6 -1
  407. package/dist/cli/tui/data/workflow-content.js.map +1 -1
  408. package/dist/cli/tui/tabs/mcp-tab.js +4 -3
  409. package/dist/cli/tui/tabs/mcp-tab.js.map +1 -1
  410. package/dist/cli/tui/tabs/project-tab.js +7 -2
  411. package/dist/cli/tui/tabs/project-tab.js.map +1 -1
  412. package/dist/cli/tui/tui-prefs.js +2 -0
  413. package/dist/cli/tui/tui-prefs.js.map +1 -1
  414. package/dist/dist-manifest.json +3973 -0
  415. package/dist/domain/capability/protocol.js +3 -1
  416. package/dist/domain/capability/protocol.js.map +1 -1
  417. package/dist/domain/decision-note.js +13 -0
  418. package/dist/domain/decision-note.js.map +1 -1
  419. package/dist/domain/design/artifact.js +22 -3
  420. package/dist/domain/design/artifact.js.map +1 -1
  421. package/dist/domain/design/capability.js +1 -0
  422. package/dist/domain/design/capability.js.map +1 -1
  423. package/dist/domain/design/expansion.js +1 -1
  424. package/dist/domain/design/expansion.js.map +1 -1
  425. package/dist/domain/design/maturity.js +16 -0
  426. package/dist/domain/design/maturity.js.map +1 -1
  427. package/dist/domain/design/reference.js +5 -0
  428. package/dist/domain/design/reference.js.map +1 -1
  429. package/dist/domain/doctor/operations.js +20 -12
  430. package/dist/domain/doctor/operations.js.map +1 -1
  431. package/dist/domain/effective-contract.js +3 -1
  432. package/dist/domain/effective-contract.js.map +1 -1
  433. package/dist/domain/elicitation.js +1 -1
  434. package/dist/domain/flow/answer.js +265 -130
  435. package/dist/domain/flow/answer.js.map +1 -1
  436. package/dist/domain/flow/authority.js +194 -37
  437. package/dist/domain/flow/authority.js.map +1 -1
  438. package/dist/domain/flow/batch-review.js +65 -0
  439. package/dist/domain/flow/batch-review.js.map +1 -0
  440. package/dist/domain/flow/decision-schema.js +47 -0
  441. package/dist/domain/flow/decision-schema.js.map +1 -0
  442. package/dist/domain/flow/directive.js +16 -0
  443. package/dist/domain/flow/directive.js.map +1 -1
  444. package/dist/domain/flow/execution-result.js +91 -2
  445. package/dist/domain/flow/execution-result.js.map +1 -1
  446. package/dist/domain/flow/run-state.js +352 -24
  447. package/dist/domain/flow/run-state.js.map +1 -1
  448. package/dist/domain/flow/test-run-evidence.js +285 -0
  449. package/dist/domain/flow/test-run-evidence.js.map +1 -0
  450. package/dist/domain/flow/unchanged-phase.js +15 -0
  451. package/dist/domain/flow/unchanged-phase.js.map +1 -0
  452. package/dist/domain/harnesses.js +14 -5
  453. package/dist/domain/harnesses.js.map +1 -1
  454. package/dist/domain/isolation-unit.js +2 -2
  455. package/dist/domain/isolation-unit.js.map +1 -1
  456. package/dist/domain/lineage.js +7 -2
  457. package/dist/domain/lineage.js.map +1 -1
  458. package/dist/domain/obligation-correspondence.js +4 -2
  459. package/dist/domain/obligation-correspondence.js.map +1 -1
  460. package/dist/domain/plan-handoff.js +5 -0
  461. package/dist/domain/plan-handoff.js.map +1 -0
  462. package/dist/domain/proposal.js +18 -7
  463. package/dist/domain/proposal.js.map +1 -1
  464. package/dist/domain/reservation.js +5 -3
  465. package/dist/domain/reservation.js.map +1 -1
  466. package/dist/domain/retirement/proposal.js +1 -0
  467. package/dist/domain/retirement/proposal.js.map +1 -1
  468. package/dist/domain/session/custody.js +10 -6
  469. package/dist/domain/session/custody.js.map +1 -1
  470. package/dist/domain/session/narrative.js +4 -1
  471. package/dist/domain/session/narrative.js.map +1 -1
  472. package/dist/domain/skills.js +4 -6
  473. package/dist/domain/skills.js.map +1 -1
  474. package/dist/domain/sql-lexer.js +1 -1
  475. package/dist/domain/sql-lexer.js.map +1 -1
  476. package/dist/runtime/namespace-resolver.js +4 -0
  477. package/dist/runtime/namespace-resolver.js.map +1 -1
  478. package/dist/runtime/workline-marker.js +35 -8
  479. package/dist/runtime/workline-marker.js.map +1 -1
  480. package/dist/runtime/workspace-resolution.js +123 -0
  481. package/dist/runtime/workspace-resolution.js.map +1 -0
  482. package/package.json +6 -5
  483. package/skills/w/SKILL.md +12 -17
  484. package/skills/w/artifacts/artifacts-core/CHECKPOINT.md +1 -1
  485. package/skills/w/artifacts/artifacts-core/SCRIPTS.rollback.sql +8 -0
  486. package/skills/w/artifacts/artifacts-core/SCRIPTS.sql +4 -8
  487. package/skills/w/commands/export-diagrams.md +3 -3
  488. package/skills/w/commands/export-manuals.md +6 -6
  489. package/skills/w/commands/export-reports.md +3 -3
  490. package/skills/w/commands/export-scripts.md +5 -5
  491. package/skills/w/commands/fix-git.md +12 -13
  492. package/skills/w/commands/persist.md +2 -2
  493. package/skills/w/commands/plan-exec.md +4 -2
  494. package/skills/w/commands/spec-new.md +1 -1
  495. package/skills/w/commands/workspace-init.md +2 -0
  496. package/skills/w/context/MANIFEST.json +1 -1
  497. package/skills/w/exports/README.md +4 -4
  498. package/skills/w/exports/export-diagrams/EXPORT.md +4 -4
  499. package/skills/w/exports/export-manuals/EXPORT.md +14 -16
  500. package/skills/w/exports/export-reports/EXPORT.md +3 -3
  501. package/skills/w/exports/export-scripts/EXPORT.md +46 -22
  502. package/skills/w/harness/HARNESS.md +4 -7
  503. package/skills/w/hooks/hooks.template.json +6 -4
  504. package/skills/w/loops/CHASSIS.md +12 -6
  505. package/skills/w/loops/CODE-POLICIES.md +8 -5
  506. package/skills/w/loops/README.md +2 -2
  507. package/skills/w/loops/plan-exec-loop/LOOP.md +23 -22
  508. package/skills/w/loops/plan-new-loop/LOOP.md +23 -31
  509. package/skills/w/loops/plan-refine-loop/LOOP.md +8 -2
  510. package/skills/w/loops/quick-loop/LOOP.md +7 -6
  511. package/skills/w/loops/spec-refine-loop/LOOP.md +1 -1
  512. package/skills/w/modules/DESIGN-REFERENCES.md +9 -11
  513. package/skills/w/modules/PLAN-EXECUTION-BATCHES.md +4 -4
  514. package/skills/w/modules/SESSION-NUMBERING.md +2 -0
  515. package/skills/w/roles/README.md +11 -47
  516. package/skills/w/roles/design/CONTRACT.md +6 -4
  517. package/skills/w/roles/design/ROLE.md +7 -3
  518. package/skills/w/roles/diagrams/ROLE.md +1 -1
  519. package/skills/w/roles/git/ROLE.md +17 -10
  520. package/skills/w/roles/research/ROLE.md +2 -2
  521. package/skills/w/roles/sql/ROLE.md +17 -15
  522. package/skills/w/schemas/design/ui-screen.v1.schema.json +9 -0
  523. package/dist/application/capability/descriptor-loader.js +0 -109
  524. package/dist/application/capability/descriptor-loader.js.map +0 -1
  525. package/dist/application/capability/installed-inventory.js +0 -168
  526. package/dist/application/capability/installed-inventory.js.map +0 -1
  527. package/dist/application/self/install-plugin-skills-git.js +0 -226
  528. package/dist/application/self/install-plugin-skills-git.js.map +0 -1
  529. package/dist/application/self/install-plugin-skills.js +0 -203
  530. package/dist/application/self/install-plugin-skills.js.map +0 -1
  531. package/dist/application/self/plugin-cache-clear.js +0 -133
  532. package/dist/application/self/plugin-cache-clear.js.map +0 -1
  533. package/dist/application/self/plugin-cache-reload.js +0 -141
  534. package/dist/application/self/plugin-cache-reload.js.map +0 -1
  535. package/dist/application/self/skills-apply.js +0 -623
  536. package/dist/application/self/skills-apply.js.map +0 -1
  537. package/dist/application/self/skills-catalog.js +0 -35
  538. package/dist/application/self/skills-catalog.js.map +0 -1
  539. package/dist/application/self/skills-change.js +0 -479
  540. package/dist/application/self/skills-change.js.map +0 -1
  541. package/dist/application/self/skills-discovery.js +0 -275
  542. package/dist/application/self/skills-discovery.js.map +0 -1
  543. package/dist/application/self/skills-manager.js +0 -253
  544. package/dist/application/self/skills-manager.js.map +0 -1
  545. package/dist/application/self/skills-payload.js +0 -566
  546. package/dist/application/self/skills-payload.js.map +0 -1
  547. package/dist/application/self/skills-registry.js +0 -107
  548. package/dist/application/self/skills-registry.js.map +0 -1
  549. package/dist/application/skill-index-service.js +0 -78
  550. package/dist/application/skill-index-service.js.map +0 -1
  551. package/dist/cli/commands/plugin-cache.js +0 -25
  552. package/dist/cli/commands/plugin-cache.js.map +0 -1
  553. package/dist/cli/commands/skill-index.js +0 -19
  554. package/dist/cli/commands/skill-index.js.map +0 -1
  555. package/dist/cli/tui/data/recommended-skills.js +0 -482
  556. package/dist/cli/tui/data/recommended-skills.js.map +0 -1
  557. package/dist/cli/tui/tabs/skills-tab.js +0 -664
  558. package/dist/cli/tui/tabs/skills-tab.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -12,6 +12,112 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
12
12
  - `### Migration` sigue como notas libres.
13
13
  - Las versiones hasta la 25.6.1 sólo traen la sección donde se registró una ruptura conocida, y ahí no pretende ser completa.
14
14
 
15
+ ## [26.0.0] — 2026-09-28
16
+
17
+ **Workline deja de gestionar skills ajenas: distribuye y diagnostica su bundle y capacidades propios, admite ayuda del host sin exigirla y exige validación final completa al publicar planes.**
18
+
19
+ ### Contrato
20
+
21
+ - **Deja de valer:** la pestaña Skills, sus accesos y acciones, y `initialScreen=skills` como pantalla inicial. **Lo reemplaza:** las pestañas Status, Workline, Project, MCP y Config; una preferencia anterior abre Status en memoria sin reescribir el archivo. **Qué hacer:** elegí una pantalla existente y gestioná skills ajenas desde el host o marketplace que uses.
22
+ - **Deja de valer:** `aw self install-plugin-skills`, `install-plugin-skills-git`, `clean-cache`, `aw plugin-cache` y `aw skill-index`; los flags de instalación de terceros, `--keep-cache` en `self install`/`install-skill` y `--prefix` en `self clean-legacy`. **Lo reemplaza:** `aw self install-skill`/`uninstall-skill` mantienen sólo el bundle propio; los comandos retirados dejan de despacharse y esos flags no son admitidos por los subcomandos propios. **Qué hacer:** adaptá scripts e instalá, actualizá o retirá skills ajenas desde el host; sus instalaciones previas no se desinstalan automáticamente.
23
+ - **Deja de valer:** el catálogo recomendado, el inventario y readiness de terceros, y los bindings externos de `skills.toml` como selección, requisito o prueba de compatibilidad para `design` y los flows. **Lo reemplaza:** `aw skills --detail` y `aw doctor` diagnostican capacidades, floor e instalación propios; los bindings ajenos históricos se avisan como no aplicables y sus archivos quedan intactos. **Qué hacer:** revisá consumidores de diagnóstico anterior y quitá o gestioná por tu cuenta bindings que ya no aplican; `off` y `[docs]` mantienen su función propia.
24
+ - **Deja de valer:** acreditar una mejora de `design` por metadata, un `preflight` construido al validar o un `passed: true` declarado por el host sobre un archivo con digest correcto. **Lo reemplaza:** la selección se fija con un pin persistido antes de aportar contenido; las observaciones host quedan sin crédito semántico y `validate` usa el floor con degradación cuando el package propio valida. Las propuestas de autoría siguen parciales hasta aprobación y aplicación. **Qué hacer:** iniciá el intento con `prepare` y conservá su pin y request; tratá las observaciones como información, no como gate acreditado.
25
+ - **Deja de valer:** publicar un plan con una fuente de código sin build o tests resolubles, o repartir los comandos de `Validación final` de una fuente entre viñetas. **Lo reemplaza:** `aw plan lint` y el gate de publicación usado por `plan-new` comprueban build y tests por fuente desde el pipeline versionado o el plan, y señalan comandos ausentes y viñetas partidas. **Qué hacer:** declará ambos comandos por fuente con `aw set-pipeline` o en una sola viñeta de `## Validations`, y corré `aw plan lint` antes de publicar.
26
+
27
+ ### Removed
28
+
29
+ - **Gestión de terceros en CLI/TUI.** Salen la pestaña Skills, su catálogo, los instaladores de plugins, la caché y el índice de skills externas; se retiran los comandos públicos de mantenimiento ajeno.
30
+
31
+ ### Changed
32
+
33
+ - **Instalación y diagnóstico propios.** `aw self install-skill`, `aw skills --detail` y `aw doctor` se centran en Workline; la doctrina del bundle admite ayuda del host sin prescribir skills ajenas por nombre.
34
+ - **Planes con cierre verificable.** El lint y la publicación comprueban build y tests por fuente de código y rechazan validaciones finales divididas en dos viñetas.
35
+
36
+ ### Fixed
37
+
38
+ - **Acreditación de design por intento.** Un pin aportado sólo al validar no sustituye la fijación previa persistida; las observaciones autodeclaradas no acreditan una contribución y una observación inválida no bloquea por sí sola un floor válido.
39
+ - **Preferencias TUI anteriores.** `initialScreen=skills` cae a Status al leer, sin alterar el archivo guardado.
40
+
41
+ ## [25.9.0] — 2026-09-27
42
+
43
+ La ejecución acredita revisiones, pruebas y commits por lote. Las fuentes tienen rutas locales, pipeline versionado y ramas por documento. Los exports conservan el número aprobado. Las sesiones y unidades se cierran con evidencia; cada comando resuelve el workspace que le corresponde.
44
+
45
+ ### Contrato
46
+
47
+ - **Deja de valer:** omitir `plan-exec.review-findings` o cerrar un lote sin revisar sus correcciones. **Lo reemplaza:** revisión registrada por alguien distinto de los implementadores; sin subagentes, relectura limpia declarada. `batch-close` exige el registro. **Qué hacer:** entregá la revisión y volvé a revisar las correcciones.
48
+ - **Deja de valer:** acreditar una fase o la validación final con pruebas que no corrieron, no cargaron o introdujeron fallos. **Lo reemplaza:** el veredicto exige ejecución real y sólo admite rojos previos declarados. **Qué hacer:** corregí fallos nuevos y declará los preexistentes en el plan.
49
+ - **Deja de valer:** bloquear fases sin tareas abiertas o acreditar cualquier lote sin cambios. **Lo reemplaza:** la fase de sólo validación exige aprobación expresa y prueba real; las demás exigen cambios propios. **Qué hacer:** aprobá el lote de sólo validación antes de acreditarlo.
50
+ - **Deja de valer:** omitir `plan-exec.final-validation` o acreditarla con `aw status --json`. **Lo reemplaza:** build y tests reales por fuente de código, resueltos desde `## Validations` o el pipeline versionado. `plan-done` exige evidencia. **Qué hacer:** declará build y test con `aw set-pipeline` o en el plan y entregá sus salidas.
51
+ - **Deja de valer:** inferir siempre un lote por fase y diferir todos los commits al final. **Lo reemplaza:** `## Execution batches` delimita lotes; cada lote acreditado propone commits por fuente y los crea tras aprobación. Las corridas abiertas con la cola anterior la conservan. **Qué hacer:** revisá y aprobá las rutas y mensajes de cada lote.
52
+ - **Deja de valer:** descontar un intento por aprobar una integración o un commit. **Lo reemplaza:** la concesión queda registrada sin gastar un intento de respuesta. **Qué hacer:** distinguí aprobaciones de rechazos al leer el contador.
53
+ - **Deja de valer:** gastar intentos en formato inválido, digest erróneo, plan inválido o prueba vencida y mostrar sólo el primer defecto. **Lo reemplaza:** `error.violations` reúne defectos detectables y `aw flow submit --check` comprueba sin escribir ni gastar intento. La directiva declara efectos, aprobación, tipos, esquema y fuentes en `expects`. **Qué hacer:** corregí las violaciones y comprobá con `--check`.
54
+ - **Deja de valer:** una prueba sin raíz observada o perder `Compactar` y `Cerrar` tras un rechazo. **Lo reemplaza:** `proof` distingue otra raíz de un checkout cambiado y muestra el stderr de git; los controles siguen disponibles en la directiva de rechazo. **Qué hacer:** medí otra vez con `aw flow prove` en el checkout indicado.
55
+ - **Deja de valer:** exigir `schema` y `date` al autor de una nota o cobrar dos veces un reenvío idéntico. **Lo reemplaza:** el CLI completa ambos campos, avisa de campos desconocidos y reconoce el reenvío. **Qué hacer:** entregá los campos de autor y corregí los faltantes indicados.
56
+ - **Deja de valer:** invalidar sellos de texto por LF/CRLF o rechazar en `batch-close` las marcas que el propio CLI escribió. **Lo reemplaza:** se admiten ambos finales de línea y los digests anteriores; otras ediciones muestran diff. `PLAN_EXEC_BATCH_STALE` no cobra intento. **Qué hacer:** ante cambios de contenido, prepará `aw flow recover --reinfer-batch` y confirmá con `--approval <digest>`; repetí pruebas y revisión.
57
+ - **Deja de valer:** escribir el estado de corrida v13. **Lo reemplaza:** v15; v14 sumó revisiones, retiro de señales y observaciones de quick, y v15 añade aislamiento al alcance. Se continúan v11–v14 y se actualizan al escribir; v7–v10 sólo se leen para diagnóstico y recuperación. **Qué hacer:** avanzá una corrida v11–v14; para v7–v10 usá `aw flow restart`. No abras v15 con un CLI anterior.
58
+ - **Deja de valer:** una rama esperada única por fuente. **Lo reemplaza:** `aw doc-branch show|set` registra la rama por documento y fuente, hereda la de spec al plan y permite integrar unidades sin mover el checkout. **Qué hacer:** consultá con `--code` o `--doc` y registrá la rama con `set --source <alias> --rama <rama>`.
59
+ - **Deja de valer:** reescribir siempre rutas absolutas en `## Fuentes` o podar fuentes omitidas por `workspace-init --source`. **Lo reemplaza:** `.workflow/local.json` guarda rutas de este host; `aw add-source` y `workspace-init --source` son aditivos. **Qué hacer:** registrá cada checkout con `aw add-source <alias>:<ruta>:<rama>`.
60
+ - **Deja de valer:** estampar `Última actividad` en WORKSPACE y mostrar `Histórico:` sin archivo. **Lo reemplaza:** la actividad sale en `aw status`, la rama de trabajo figura en Fuentes y CLAUDE.md/AGENTS.md se escriben juntos. **Qué hacer:** consultá la actividad en `aw status`.
61
+ - **Deja de valer:** descargar tres versiones completas en `fix-git prepare` o resolver conflictos sólo con texto; informar `any_merging: false` al no poder leer una fuente. **Lo reemplaza:** `--show` y `--adapt` detallan rutas pedidas; `resolutions` acepta `ours`, `theirs` y `delete`, incluso binarios. `merge-state` informa `unreadable`, `any_merging: null` y sale con 1. **Qué hacer:** pedí las rutas necesarias y tratá `unreadable` como lectura incompleta.
62
+ - **Deja de valer:** confirmar `aw fix-git commit` sin comprobar el build. **Lo reemplaza:** la vista previa sin `--confirm` incluye build, rutas y `left_out`; confirmar ejecuta el build declarado o rechaza con `FIX_GIT_BUILD_UNDECLARED`/`FIX_GIT_BUILD_FAILED`. **Qué hacer:** declará build con `aw set-pipeline` o justificá la omisión con `--skip-build <motivo>`.
63
+ - **Deja de valer:** cambiar en `export-* apply` el número aprobado, admitir `--overwrite` fuera de manuals o reutilizar correlativos publicados tras borrar su carpeta. **Lo reemplaza:** `EXPORT_NUMBER_TAKEN` bloquea la colisión y la numeración consulta HISTORY y pases. **Qué hacer:** prepará otra propuesta si el número quedó ocupado.
64
+ - **Deja de valer:** sellar sólo el inventario de `export-scripts` o publicar forwards y rollbacks planos. **Lo reemplaza:** SQL y `scope.seal` entran al sello; bundles nuevos organizan forwards en 01–05, rollbacks en `rollback/` y generan `bundle.json`. Los bundles planos antiguos siguen legibles. **Qué hacer:** prepará otra vez si cambió SQL o scope y publicá con el manifiesto generado.
65
+ - **Deja de valer:** duplicar publicaciones de `next-number --publish`, materializar un workspace ausente, admitir sólo texto en `persist` o exigir siempre dossier en manuals. **Lo reemplaza:** publicación idempotente con `--dry-run`, adjuntos binarios y manuals de canon plano o `complement` con `INDEX.md`. **Qué hacer:** usá el número reservado y la forma de manuals que corresponde a tus archivos.
66
+ - **Deja de valer:** forzar una tercera revisión simple de design por package o aceptar revisiones editadas. **Lo reemplaza:** `update` conserva el modo simple, `screen_refs` declara citas y `aw designs`/`capability validate` verifican digests; sólo cambiar LF/CRLF avisa sin bloquear. **Qué hacer:** publicá otra revisión en lugar de editar una ya publicada.
67
+ - **Deja de valer:** que `Cerrar` sólo pause, que `quick.db-touched` incluya lecturas o que una señal errónea no se pueda retirar. **Lo reemplaza:** `Cerrar` finaliza los cinco flujos y conserva lo pendiente; `quick.db-touched` significa mutación y `aw flow retract` retira señales no consumidas. **Qué hacer:** reabrí con `aw session-resume --reopen` si seguís; retirá una señal de mera lectura antes del gate.
68
+ - **Deja de valer:** exigir scripts por mera lectura o commit por quick sin archivos, y dejar abierta la quick al cambiar a SPEC. **Lo reemplaza:** scripts sólo por mutación, fix vacío sin commit y escalamiento con cierre y handoff a `/w:spec-new`. **Qué hacer:** guardá DDL/DML en `SCRIPTS.sql` o `scripts/*.sql`; indicá análisis cuando corresponda.
69
+ - **Deja de valer:** escribir para averiguar si `aw amend apply` toca contrato, contar casillas de `## Handoff operativo` como tareas o arrancar `plan-refine` sin plan. **Lo reemplaza:** `--check` consulta sin escribir; el pase se declara `- Pase a cert|prod: <corte>` y `plan-refine` exige plan existente. **Qué hacer:** comprobá con `--check` y pasá `--input docs/plans/PPP-plan-<slug>.md` si falta el plan.
70
+ - **Deja de valer:** exigir unidad aunque el workspace elija editar en su checkout. **Lo reemplaza:** `aw set-edit-mode in-place|unit`; `> Aislamiento: unidad` prevalece. In-place prueba y commitea sólo rutas aprobadas, conserva cambios ajenos y rechaza otra rama o HEAD. **Qué hacer:** elegí `in-place` expresamente y aprobá sólo las rutas propias.
71
+ - **Deja de valer:** fallar en `aw reset` o `aw discard` por una unidad integrada cuya carpeta ya no existe. **Lo reemplaza:** el retiro verifica recibo, inventario git y rama destino antes de revertir el rango atribuible. **Qué hacer:** ejecutalo desde el destino limpio y atendé la negativa si la atribución no es única.
72
+ - **Deja de valer:** cargar todo el CLI en hooks fuera de un workspace o necesitar un hook `prompt` extra para `PostCompact`. **Lo reemplaza:** entrada ligera y reanudación en `resume-summary`; `sql-mutation-guard` conserva su alcance. **Qué hacer:** reinstalá hooks gestionados con `aw self install-hooks`.
73
+ - **Deja de valer:** que `aw doctor` dé por sana la ausencia de hosts o falle sólo por un host `ready` sin binario. **Lo reemplaza:** distingue ausencia, contradicción y cobertura omitida; avisa de `dist/` alterado y upstream a PROD. **Qué hacer:** consultá sus avisos y el remedio de upstream indicado.
74
+ - **Deja de valer:** cerrar con CHECKPOINT incompleto, `## Origin` vacío o criterios sin marcar y sin razón. **Lo reemplaza:** el cierre se niega salvo `--force` o `--abandon`; el CHECKPOINT registra el estado git real por fuente y el Recorrido termina en «Siguiente paso: ninguno». **Qué hacer:** completá origen, criterios y checkpoint; usá `--abandon` sólo para abandonar.
75
+ - **Deja de valer:** crear HISTORY sólo al cerrar, desordenar sus filas o volver a usar un número tras `discard`. **Lo reemplaza:** la fila nace al crear, se ordena por código y se conserva al retirar; `aw history reconcile` muestra discrepancias y `aw workspace-migrate --renumber` resuelve colisiones. **Qué hacer:** reconciliá HISTORY y renumerá la sesión local si comparte número.
76
+ - **Deja de valer:** inferir que toda sesión sin `.closed` está activa. **Lo reemplaza:** `aw session-pause --code <NNN>` y `session-close --abandon` marcan estados propios; retomar reactiva una pausada y una abandonada exige `--reopen`. **Qué hacer:** marcá el estado expresamente y usá `--reopen` para una abandonada.
77
+ - **Deja de valer:** que el cierre deje todo el mínimo sólo en la carpeta efímera o commitee el índice ajeno. **Lo reemplaza:** archiva CHECKPOINT, DECISION, BACKLOG, SQL y evidencia consentida en `.workflow/archive/`; `aw workspace-commit` prepara y aplica con aprobación un commit por rutas, sin push. **Qué hacer:** inspeccioná la propuesta de cierre o export y aprobá el digest si querés el commit; para evidencia temporal usá `--with-evidence`.
78
+ - **Deja de valer:** resolver un workspace por el cwd o por un marcador de `$HOME` dentro de una fuente. **Lo reemplaza:** el registro de hubs en `~/.workflow/hubs.json` resuelve al hub dueño; con varios exige `--workspace <ruta>`. La fuente no recibe `.workflow/` ni cambios de `.gitignore`. **Qué hacer:** corré una vez `aw` en el hub o indicá `--workspace` cuando haya ambigüedad.
79
+ - **Deja de valer:** preparar una operación en un workspace y aplicarla en otro con el mismo contenido. **Lo reemplaza:** las propuestas de dos tiempos sellan la raíz real; `--workspace` selecciona la carpeta exacta y un cambio de raíz se rechaza. **Qué hacer:** aplicá desde el mismo hub o especificá su ruta con `--workspace`.
80
+ - **Deja de valer:** compartir la rama `aw/<sesión>` entre hubs o perder unidades al mover el hub. **Lo reemplaza:** las unidades nuevas usan `aw/<hash8>/<carpeta>`; custodia y claves previas reconocen las antiguas. `aw workspace-move` mueve o repara rutas. **Qué hacer:** mudá con `aw workspace-move <destino>` o repará un movimiento manual con `--repair`.
81
+ - **Deja de valer:** tomar `development` como rama de trabajo implícita para `worktree ensure`, `integrate` y git-flow. **Lo reemplaza:** se exige la rama del documento o una rama de trabajo declarada; `aw sources` informa si falta. **Qué hacer:** registrá la rama con `aw set-working-branch <alias> <rama>`.
82
+ - **Deja de valer:** dejar carpetas huérfanas recuperables y ramas `aw/*` integradas tras liberar, o exigir reabrir la sesión para liberar. **Lo reemplaza:** `release`/`reclaim` terminan removes partidos, retienen archivos propios y borran por CAS sólo ramas contenidas en su base. `release` e `integrate` aceptan sesiones cerradas. **Qué hacer:** usá `aw worktree reclaim` para restos y resolvé por separado lo retenido.
83
+ - **Deja de valer:** que una unidad con dependencias idénticas deba reinstalarlas o que el retiro borre indiscriminadamente `node_modules`. **Lo reemplaza:** la unidad enlaza las dependencias de la fuente si coinciden manifiesto y lockfile; libera sólo ese enlace verificado. **Qué hacer:** no ejecutes `npm ci` en una unidad enlazada: modificaría las dependencias de la fuente.
84
+ - **Deja de valer:** tratar unidades vivas de multiroot como sobrantes o bloquear el cierre final por unidades vacías o preservadas. **Lo reemplaza:** la reparación quita sólo rutas sobrantes; el cierre final libera unidades vacías y preservadas y retiene las que tienen trabajo no acreditado. **Qué hacer:** consultá el motivo de retención antes de integrar o liberar.
85
+ - **Deja de valer:** mostrar ayuda del padre para todo subverbo, ofrecer `--overwrite` en exportaciones que no lo aceptan o admitir juntos `project-md-upsert --read --init`. **Lo reemplaza:** ayuda por subverbo desde el contrato de flags, con `Usage` y opciones excluyentes; la ayuda global anuncia `--workspace`. **Qué hacer:** consultá `<comando> <subverbo> --help` y elegí sólo `--read` o `--init`.
86
+
87
+ ### Added
88
+
89
+ - **`aw doc-branch show|set`, `aw add-source` y `aw set-pipeline`.** Registran ramas por documento, rutas locales y build/test por fuente.
90
+ - **`aw flow submit --check`, `aw flow retract` y `aw flow recover --reinfer-batch`.** Comprueban sin gastar intento, retiran señales no consumidas y re-infieren un lote con aprobación.
91
+ - **`aw set-edit-mode in-place|unit` y `aw set-exception-branch`.** Declaran la edición del checkout y excepciones de rama.
92
+ - **`aw history reconcile`, `aw session-pause` y `aw sessions --sweep`.** Consultan discrepancias, pausan sesiones y limpian residuos del runtime.
93
+ - **`aw workspace-commit` y `aw workspace-init --untrack`.** Preparan commits acotados y dejan de trackear archivos excluidos sin borrarlos.
94
+ - **`aw workspace-move` y registro de hubs.** Resuelven fuentes compartidas y reparan rutas tras una mudanza.
95
+ - **`export-scripts --catalog` y bundles con `bundle.json`.** Contrastan el catálogo en sólo lectura y registran el origen del SQL.
96
+ - **Pases y specs reemplazadas.** `## Handoff operativo` admite `- Pase a cert|prod: <corte>`; `superseded` retira la spec de pendientes.
97
+
98
+ ### Changed
99
+
100
+ - **El estado de corrida escribe v15.** Continúa v11, v12, v13 y v14; v7–v10 sólo se leen y salen por `aw flow restart`.
101
+ - **El cierre acredita pruebas, revisiones y commits por lote.** La validación final toma build y tests del pipeline o del plan.
102
+ - **Los números y sellos de publicación permanecen estables.** `export-* apply` conserva el número aprobado; los sellos de texto toleran LF/CRLF.
103
+ - **La doctrina y la ayuda siguen el binario.** `> Cierre:` lleva evidencia, `> Assurance:` el veredicto; CHASSIS incluye reglas de host y las guías redirigen sobres desde archivos.
104
+ - **El CLI conserva su catálogo propio de skills recomendadas.** El marketplace contrasta una captura del catálogo; el CLI no carga su README.
105
+ - **`aw doctor` distingue cobertura omitida de fallo.** Comprueba integridad de `dist/` y avisa de upstreams a PROD.
106
+ - **Dependencias de mantenimiento.** Vitest 5.0.2 y Vite 8.3.1 son de desarrollo; smol-toml 1.9.0 normaliza tablas de prototipo nulo y ws 8.22.0 sigue transitiva.
107
+
108
+ ### Fixed
109
+
110
+ - **`aw reset` y `aw discard` reconocen unidades integradas y liberadas.** Comprueban recibo y destino antes de revertir.
111
+ - **`fix-git` resuelve bajas, binarios y archivos adaptados.** Aplica sólo las rutas propuestas y conserva los finales de línea de Windows.
112
+ - **`merge-state` informa fuentes ilegibles.** Devuelve `unreadable` y `any_merging: null` en vez de descartar merges sin certeza.
113
+ - **Design comprueba revisiones y renditions.** Una tercera revisión simple sigue la ruta simple y una revisión editada falla por digest.
114
+ - **El bloque compartido conserva fuentes.** Rutas locales quedan fuera del bloque versionado y sus dos espejos se actualizan juntos.
115
+ - **Las unidades se liberan sin arrastrar dependencias.** Se recuperan carpetas limpias de removes partidos y se conserva el trabajo propio.
116
+ - **El commit in-place se reconoce aunque queden cambios ajenos.** Tras una interrupción, sólo impiden reconocerlo cambios pendientes en rutas de la propuesta.
117
+ - **La ayuda conserva `Usage` y anuncia `--workspace`.** `context-budget` puede medir el bundle desde un checkout sin hub.
118
+ - **Una sesión pausada conserva sus reservas.** `aw claims` ya no ofrece recuperarlas; al retomarla, la reserva sigue suya. Las de una sesión abandonada siguen siendo recuperables.
119
+ - **El cierre puede copiar la evidencia y commitearla en la misma decisión.** La copia versionada entra en el commit final del workspace.
120
+
15
121
  ## [25.8.0] — 2026-09-27
16
122
 
17
123
  La guarda de SQL distingue los servidores PostgreSQL registrados en `aw self mcp` y revisa el SQL que ejecutan las funciones remotas. Las corridas acreditan cada lote con prueba de su propio checkout y dejan registrar su ciclo de vida completo. Los comandos rechazan los flags desconocidos, la salida humana puede ser ASCII y el wrapper instalado de design usa el protocolo real de `aw capability` en cada host.
package/README.md CHANGED
@@ -24,7 +24,7 @@ Workline has three layers plus a permanent `docs/` zone:
24
24
  - **Layer 2 · Loops** — the AI runs them whole: `spec-refine-loop` · `plan-new-loop` · `plan-refine-loop` · `plan-exec-loop` · `quick-loop` — all heirs of the shared engine `skills/w/loops/CHASSIS.md` (+ `CODE-POLICIES.md` for the code-editing loops). Each loop is a **persistent goal** that runs until its success criteria are green (verification-first); gap-driven, with **structured-choice** lifecycle control (compact/close — the host's own question surface where one is reachable, **labeled markdown** where none is; the binding per host is stamped into what gets installed) and resumable `CHECKPOINT`.
25
25
  - **Layer 3 · Sessions + artifacts** — internal, ephemeral process state under `.workflow/sessions/` (`SESSION` · `CHECKPOINT` · `BACKLOG` · `SCRIPTS.sql` · `ANALYSIS-FILE` · `CONCLUSIONS` · `DECISION` · …). Sessions are slug-named folders, created by loops, never by the user.
26
26
 
27
- **Pluggable capabilities.** Loops compose capability **roles** (`design`, `sql`, `git`, `research`, `diagrams`, `overview`); the concrete skill bound to each role is resolved via `.workflow/skills.toml` (cascade: built-in default → `~/.workflow/skills.toml` → workspace). Inspect bindings with `aw skills` (advisory: it also warns when a bound skill is not installed in the standard skill roots — the binding itself is not auto-validated). Code/testing/writing conventions **and tool authoring** (`creating-tools`) are **not** roles — they're ambient skills the host auto-applies when present, independent of Workline. Per-source launch scripts live under `.workflow/launch/` (machine-specific, gitignored); created tools live under `docs/tools/`.
27
+ **Capacidades propias.** `design` conserva su floor y operaciones; `overview` orienta sobre Workline. Sólo estos roles propios se resuelven por `skills.toml` (default → global → workspace). `off` conserva el contrato por operación y los bindings históricos ajenos se avisan sin usar ni reescribir. `aw skills --detail` informa únicamente capacidades propias y wrappers; el host puede aportar otras ayudas sin preregistro ni dependencia para SPEC, PLAN y QUICK. Para instalar o retirar skills ajenas, usá el host o marketplace que elijas. Los scripts de arranque por fuente viven en `.workflow/launch/` y las herramientas creadas en `docs/tools/`.
28
28
 
29
29
  **Invariants.** No auto-export (only `export-*` writes `docs/`); the spec and plan are documents, not artifacts; DB scripts-only (never executes DML/DDL); git-safe (verifies the per-source working branch before edits; proposes commits).
30
30
 
@@ -93,6 +93,8 @@ The bundle's internal manuals (`loops/*/LOOP.md`, `roles/*/ROLE.md`, `exports/*/
93
93
 
94
94
  Opt-out flags: `--skill-only`, `--no-commands`, `--no-hooks`. Override the source with `--from /path/to/skills/w`. Other flags: `--confirm-all` (required with `--target all`), `--keep-cache`, `--force`, `--dry-run`.
95
95
 
96
+ To add the `UserPromptSubmit` branch advisory to an existing Claude or Kimi installation, rerun `aw self install-hooks --target claude` or `--target kimi`; updating the CLI alone does not reinstall hooks. Editing remains protected by `branch-check` on all managed hosts.
97
+
96
98
  **What `--target all` means.** Every **host** — never the shared skills dirs, which are install destinations rather than hosts and are reached explicitly (`--target agents`). `install` and `uninstall` use the same set, so the round trip matches: what `all` installs is what `all` removes. (`oz` installs into `~/.agents/skills`, so that directory is still covered under `all` through its host.)
97
99
 
98
100
  ### Support levels and how long a verification is worth
@@ -125,7 +127,6 @@ Running `agent-workflow` (or `aw`) with no arguments opens the tab-based TUI:
125
127
  | **Workline** | Per-host administration of the bundled `w` SKILL (install / reinstall / uninstall, `hooks armed` state) plus a compact flows overview. |
126
128
  | **Project** | Workspace sources, branches and git-flow actions. |
127
129
  | **MCP** | Tools PostgreSQL de solo lectura. `mcp-connections.json` v2 es la única autoridad de alias, provider y variable DSN: registrá con `aw self mcp use-env --name alpha --dsn-var ALPHA_DATABASE_URL`. La TUI instala descriptores absolutos en user scope; `aw mcp setup` conserva además el modo workspace portable dependiente de `PATH`. Cada host muestra configuración, launchability, recarga pendiente y carga observada; Codex queda opcional porque existe el fallback local `aw tool call`. |
128
- | **Skills** | Standalone third-party skills manager (skills.sh model): the source is an `owner/repo`, a git URL (`#ref` supported) or an absolute local path, and **the skill is chosen by its path inside that source** — nested under another skill included, several leaves at once in one proposal — with an explicitly declared path validated against the source even when the walk did not list it. Installing materializes a canonical copy in `~/.agents/skills/<name>` (the open-standard dir every non-Claude host scans) plus a symlink replica in `~/.claude/skills/<name>` (copy fallback where symlinks are unavailable) and a copy in `~/.gemini/skills/<name>`. Seeded with a **curated catalog** (`SKILL_CATALOG`): every reviewed entry carries its verdict — keep, conditional, repair/replace, candidate or withdrawn — plus the condition that makes it pertinent, its known limits and the revision the review inspected. The habitual set the list opens on is derived from it, so withdrawing an entry keeps its reason readable and touches no file; reviewed alternatives stay documented as reserves without being offered. It mirrors the companion marketplace README for the entries that list names — the verdicts, conditions and reserves live here. **Every change goes through one door:** a proposal is prepared and previewed (its exact set, sources, destinations and effects), and applying it sends that proposal's own digest as the approval — a source that moved, one more destination or a different byte produces another digest and has to be approved again. Applying keeps a per-destination backup and a journal next to the registry (outside every host discovery root), so a failure compensates in reverse order and an interrupted run is detected on reopen, offering to restore the previous state. The result is reported per destination, with its verification stated separately: what is checked is the bytes this manager wrote in the locations it manages — never that a host reloaded anything, and never that a catalog filter or a `skills.toml` `off` switched a skill off everywhere. |
129
130
  | **Config** | Namespace, host-targeting preferences, and the workspace branch defaults (written to the WORKSPACE block). |
130
131
 
131
132
  ### PostgreSQL MCP y fallback local
@@ -181,7 +182,9 @@ Workspace artifacts live under `.<namespace>/`. Resolution order (first match wi
181
182
  - `sessions` / `session-create --type <research|refine|exec|quick>` / `session-close` / `session-resume` / `session-artifacts` — internal session lifecycle (used by the loops).
182
183
  - `checkpoint-read` / `checkpoint-write` — `CHECKPOINT.md` handling.
183
184
  - `flow <advance|submit>` — the direction engine: `advance` applies every consecutive `cli`-owned transition of a flow run and returns the directive of the first non-deterministic frontier; `submit` takes the response as JSON via stdin (`--approval <digest>` for effects) and keeps advancing.
184
- - `sources` / `check-branch` / `set-working-branch` / `set-qa-branch` — multi-source git-safety (per-source base / working / QA branches).
185
+ - `sources` / `check-branch` / `set-working-branch` / `set-qa-branch` / `set-exception-branch` — multi-source git-safety (per-source base / working / QA / exception branches).
186
+ - `set-edit-mode in-place|unit` — declares checkout editing or isolated units in the WORKSPACE block; plans can require `> Aislamiento: unidad`.
187
+ - `doc-branch show|set` — propone y asocia una rama de trabajo por documento y fuente, heredada por sus planes; `show` no modifica nada.
185
188
  - `git-flow <sync|to-dev|to-qa|to-prod> [--source|--all] [--target] [--dry-run]` — run the per-source branch flows (sync working ← base, promote to dev/QA/prod) with conflict-pause; `--all` processes every source and reports each one. Also surfaced as Project-tab actions.
186
189
  - `release-data` — corpus reader backing the `export-*` skills.
187
190
  - `self install-skill` / `self doctor` / `self update` / `mcp` — CLI maintenance.
@@ -1,6 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
- import { readFile } from "node:fs/promises";
2
+ import { appendFile, lstat, readFile, readlink } from "node:fs/promises";
3
3
  import { resolve } from "node:path";
4
+ import { checkSafeRelativePath } from "../domain/safe-path.js";
4
5
  /**
5
6
  * Non-interactive git env: `GIT_TERMINAL_PROMPT=0` makes git FAIL FAST instead of
6
7
  * blocking on a terminal credential prompt (a push against a repo needing creds
@@ -49,8 +50,8 @@ export class GitCliAdapter {
49
50
  return new Error(`git ${label} failed in ${repoPath}: ${stderr.trim()}`);
50
51
  }
51
52
  /** Run git, throwing `git <label> failed in <repo>: <stderr>` on non-zero exit. */
52
- async mustRun(label, args, repoPath) {
53
- const result = await this.process.run("git", args, this.opts(repoPath));
53
+ async mustRun(label, args, repoPath, extra = {}) {
54
+ const result = await this.process.run("git", args, this.opts(repoPath, extra));
54
55
  if (result.code !== 0) {
55
56
  throw this.failed(label, repoPath, result.stderr);
56
57
  }
@@ -66,7 +67,22 @@ export class GitCliAdapter {
66
67
  }
67
68
  async isGitRepo(repoPath) {
68
69
  const result = await this.process.run("git", ["rev-parse", "--git-dir"], this.opts(repoPath));
69
- return result.code === 0;
70
+ if (result.code === 0)
71
+ return true;
72
+ if (/not a git repository/i.test(result.stderr))
73
+ return false;
74
+ throw this.failed("rev-parse", repoPath, result.stderr);
75
+ }
76
+ async readConfig(repoPath, key) {
77
+ const result = await this.process.run("git", ["config", "--get", key], this.opts(repoPath));
78
+ if (result.code === 1)
79
+ return null;
80
+ if (result.code !== 0)
81
+ throw this.failed(`config --get ${key}`, repoPath, result.stderr);
82
+ return result.stdout.trim();
83
+ }
84
+ async writeLocalConfig(repoPath, key, value) {
85
+ await this.mustRun(`config --local ${key}`, ["config", "--local", key, value], repoPath);
70
86
  }
71
87
  async currentBranch(repoPath) {
72
88
  const result = await this.process.run("git", ["rev-parse", "--abbrev-ref", "HEAD"], this.opts(repoPath));
@@ -109,11 +125,18 @@ export class GitCliAdapter {
109
125
  * Git's output is hashed as BYTES and never decoded: a digest that has to be
110
126
  * reproducible cannot depend on a text encoding it does not need.
111
127
  */
112
- async checkoutFingerprint(repoPath) {
128
+ async checkoutFingerprint(repoPath, excluded) {
129
+ const scope = excluded === undefined ? [] : [".", ...excluded.map((p) => `:(exclude)${p}`)];
113
130
  const [patch, status, untracked] = await Promise.all([
114
- this.mustRunBinary("diff for checkout fingerprint", ["diff", "--binary", "--full-index", "--no-ext-diff", "HEAD", "--"], repoPath),
115
- this.mustRunBinary("status for checkout fingerprint", ["status", "--porcelain=v2", "-z"], repoPath),
116
- this.mustRunBinary("untracked files for checkout fingerprint", ["ls-files", "--others", "--exclude-standard", "-z"], repoPath),
131
+ this.mustRunBinary("diff for checkout fingerprint", ["diff", "--binary", "--full-index", "--no-ext-diff", "HEAD", "--", ...scope], repoPath),
132
+ this.mustRunBinary("status for checkout fingerprint", ["status", "--porcelain=v2", "-z", ...(excluded === undefined ? [] : ["--", ...scope])], repoPath),
133
+ this.mustRunBinary("untracked files for checkout fingerprint", [
134
+ "ls-files",
135
+ "--others",
136
+ "--exclude-standard",
137
+ "-z",
138
+ ...(excluded === undefined ? [] : ["--", ...scope]),
139
+ ], repoPath),
117
140
  ]);
118
141
  const hash = createHash("sha256");
119
142
  hash.update("patch\0", "utf8");
@@ -121,6 +144,16 @@ export class GitCliAdapter {
121
144
  hash.update("status\0", "utf8");
122
145
  hash.update(status.stdout);
123
146
  await this.hashUntracked(hash, repoPath, untracked.stdout);
147
+ if (excluded !== undefined) {
148
+ // hash-object alone follows symlinks and omits execute bits. A no-index
149
+ // patch includes both Git's file mode and a symlink's destination.
150
+ for (const path of nulSeparated(untracked.stdout).sort()) {
151
+ const patch = await this.process.runBinary("git", ["diff", "--no-index", "--binary", "--no-ext-diff", "--", "/dev/null", path], this.opts(repoPath));
152
+ if (patch.code !== 0 && patch.code !== 1)
153
+ throw this.failed("untracked state", repoPath, patch.stderr.toString());
154
+ hash.update(patch.stdout);
155
+ }
156
+ }
124
157
  return `sha256:${hash.digest("hex")}`;
125
158
  }
126
159
  /**
@@ -329,6 +362,17 @@ export class GitCliAdapter {
329
362
  throw err;
330
363
  }
331
364
  }
365
+ async mergeBases(repoPath) {
366
+ const result = await this.process.run("git", ["merge-base", "--all", "HEAD", "MERGE_HEAD"], this.opts(repoPath));
367
+ if (result.code === 1)
368
+ return [];
369
+ if (result.code !== 0)
370
+ throw this.failed("merge-base --all", repoPath, result.stderr);
371
+ return result.stdout
372
+ .split("\n")
373
+ .map((line) => line.trim())
374
+ .filter(Boolean);
375
+ }
332
376
  async conflictedFiles(repoPath) {
333
377
  const result = await this.process.run("git", ["diff", "--name-only", "--diff-filter=U"], this.opts(repoPath));
334
378
  if (result.code !== 0) {
@@ -356,9 +400,9 @@ export class GitCliAdapter {
356
400
  const hashes = new Map();
357
401
  if (listed.code === 0) {
358
402
  for (const line of listed.stdout.split("\n")) {
359
- const match = /^\d+ ([0-9a-f]{40}) ([123])\t/.exec(line);
360
- if (match?.[1] && match[2])
361
- hashes.set(match[2], match[1]);
403
+ const match = /^(\d{6}) ([0-9a-f]{40}|[0-9a-f]{64}) ([123])\t/.exec(line);
404
+ if (match?.[1] && match[2] && match[3])
405
+ hashes.set(match[3], { mode: match[1], hash: match[2] });
362
406
  }
363
407
  }
364
408
  const base = await this.readStage(repoPath, hashes.get("1"));
@@ -373,12 +417,41 @@ export class GitCliAdapter {
373
417
  binary: present.some((s) => s.content === null),
374
418
  };
375
419
  }
376
- async readStage(repoPath, hash) {
377
- if (hash === undefined)
378
- return { hash: null, content: null, bytes: 0 };
420
+ async indexEntry(repoPath, path) {
421
+ const listed = await this.mustRun(`ls-files -s ${path}`, ["ls-files", "-s", "--", path], repoPath);
422
+ const match = /^(\d{6}) ([0-9a-f]{40}|[0-9a-f]{64}) 0\t/.exec(listed.stdout);
423
+ return match?.[1] && match[2] ? { mode: match[1], hash: match[2] } : null;
424
+ }
425
+ async isWorktreeCleanPath(repoPath, path) {
426
+ const result = await this.process.run("git", ["diff", "--quiet", "--", path], this.opts(repoPath));
427
+ if (result.code === 0)
428
+ return true;
429
+ if (result.code === 1)
430
+ return false;
431
+ throw this.failed(`diff --quiet ${path}`, repoPath, result.stderr);
432
+ }
433
+ async readBlob(repoPath, hash) {
434
+ const stage = await this.readStage(repoPath, { hash, mode: "100644" });
435
+ return { content: stage.content, bytes: stage.bytes };
436
+ }
437
+ async hashBlob(repoPath, content) {
438
+ const result = await this.mustRun("hash-object", ["hash-object", "-w", "--no-filters", "--stdin"], repoPath, { stdin: content });
439
+ return result.stdout.trim();
440
+ }
441
+ async setIndexEntry(repoPath, path, mode, hash) {
442
+ await this.mustRun(`update-index ${path}`, ["update-index", "--add", "--cacheinfo", `${mode},${hash},${path}`], repoPath);
443
+ await this.mustRun(`checkout-index ${path}`, ["checkout-index", "-f", "--", path], repoPath);
444
+ }
445
+ async removeIndexEntry(repoPath, path) {
446
+ await this.mustRun(`update-index --force-remove ${path}`, ["update-index", "--force-remove", "--", path], repoPath);
447
+ }
448
+ async readStage(repoPath, entry) {
449
+ if (entry === undefined)
450
+ return { hash: null, content: null, bytes: 0, mode: null };
451
+ const { hash, mode } = entry;
379
452
  const result = await this.process.runBinary("git", ["cat-file", "-p", hash], this.opts(repoPath));
380
453
  if (result.code !== 0)
381
- return { hash, content: null, bytes: 0 };
454
+ return { hash, content: null, bytes: 0, mode };
382
455
  // A NUL byte is the same heuristic git itself uses to call a blob binary.
383
456
  const binary = result.stdout.includes(0);
384
457
  // The size is the bytes git stored, which a decoded blob no longer measures.
@@ -386,6 +459,7 @@ export class GitCliAdapter {
386
459
  hash,
387
460
  content: binary ? null : result.stdout.toString("utf8"),
388
461
  bytes: result.stdout.length,
462
+ mode,
389
463
  };
390
464
  }
391
465
  async stagePath(repoPath, path) {
@@ -408,6 +482,71 @@ export class GitCliAdapter {
408
482
  parents: await this.parentsOf(repoPath, after),
409
483
  };
410
484
  }
485
+ async commitPaths(repoPath, message, paths) {
486
+ if (paths.length === 0 ||
487
+ paths.some((path) => path.length === 0 ||
488
+ path.startsWith("-") ||
489
+ path.includes("\0") ||
490
+ !checkSafeRelativePath(path).ok)) {
491
+ throw new Error("git commitPaths exige rutas relativas explícitas no vacías");
492
+ }
493
+ const before = await this.headSha(repoPath);
494
+ await this.mustRun("add -- paths", ["add", "--", ...paths], repoPath);
495
+ await this.mustRun("commit --only -- paths", ["commit", "--only", "-m", message, "--", ...paths], repoPath);
496
+ const after = await this.headSha(repoPath);
497
+ if (after === null || after === before)
498
+ throw new Error(`git commitPaths no movió HEAD en ${repoPath}`);
499
+ return {
500
+ branch: (await this.currentBranch(repoPath)) ?? null,
501
+ before,
502
+ after,
503
+ parents: await this.parentsOf(repoPath, after),
504
+ };
505
+ }
506
+ async dirtyPaths(repoPath) {
507
+ const changes = await this.localChanges(repoPath);
508
+ const byPath = new Map();
509
+ for (const change of changes) {
510
+ const files = [change.path, ...(change.from === null ? [] : [change.from])];
511
+ for (const path of files) {
512
+ const absolute = resolve(repoPath, path);
513
+ let bytes = "deleted";
514
+ try {
515
+ const stats = await lstat(absolute);
516
+ bytes = stats.isSymbolicLink() ? await readlink(absolute) : await readFile(absolute);
517
+ }
518
+ catch (error) {
519
+ if (error.code !== "ENOENT")
520
+ throw error;
521
+ }
522
+ const digest = createHash("sha256")
523
+ .update(change.code)
524
+ .update("\0")
525
+ .update(change.head_mode ?? "")
526
+ .update("\0")
527
+ .update(change.worktree_mode ?? "")
528
+ .update("\0")
529
+ .update(bytes)
530
+ .digest("hex");
531
+ byPath.set(path, digest);
532
+ }
533
+ }
534
+ return [...byPath]
535
+ .sort(([left], [right]) => left.localeCompare(right))
536
+ .map(([path, digest]) => ({ path, digest }));
537
+ }
538
+ async commitInfo(repoPath, sha) {
539
+ const [message, changed, parents] = await Promise.all([
540
+ this.mustRun("show --format=%B", ["show", "-s", "--format=%B", sha], repoPath),
541
+ this.mustRun("diff-tree --name-only", ["diff-tree", "--root", "--no-commit-id", "-r", "-z", "--name-only", sha], repoPath),
542
+ this.parentsOf(repoPath, sha),
543
+ ]);
544
+ return {
545
+ message: message.stdout.trimEnd(),
546
+ paths: changed.stdout.split("\0").filter(Boolean).sort(),
547
+ parents,
548
+ };
549
+ }
411
550
  async head(repoPath) {
412
551
  return this.headSha(repoPath);
413
552
  }
@@ -455,6 +594,65 @@ export class GitCliAdapter {
455
594
  return [];
456
595
  return result.stdout.split("\0").filter((p) => p.length > 0);
457
596
  }
597
+ async treeEntries(repoPath, rev) {
598
+ const result = await this.mustRun("ls-tree", ["ls-tree", "-r", "-z", rev], repoPath);
599
+ return result.stdout
600
+ .split("\0")
601
+ .filter(Boolean)
602
+ .map((item) => {
603
+ const match = /^(\d+) blob ([0-9a-f]+)\t(.+)$/s.exec(item);
604
+ if (!match?.[1] || !match[2] || !match[3])
605
+ throw new Error(`entrada ls-tree ilegible en ${repoPath}`);
606
+ return { mode: match[1], hash: match[2], path: match[3] };
607
+ });
608
+ }
609
+ async hashWorktreePath(repoPath, path, symlink) {
610
+ if (symlink) {
611
+ const target = await readlink(path);
612
+ return (await this.mustRun("hash-object", ["hash-object", "--stdin"], repoPath, { stdin: target })).stdout.trim();
613
+ }
614
+ return (await this.mustRun("hash-object", ["hash-object", "--no-filters", path], repoPath)).stdout.trim();
615
+ }
616
+ async worktreeFileMode(path) {
617
+ const stat = await lstat(path);
618
+ if (stat.isSymbolicLink())
619
+ return "120000";
620
+ if (!stat.isFile())
621
+ throw new Error(`no es un archivo recuperable: ${path}`);
622
+ return stat.mode & 0o111 ? "100755" : "100644";
623
+ }
624
+ async ignoredOutsideIndex(repoPath, treePath, relativePath) {
625
+ const gitDir = (await this.mustRun("rev-parse --absolute-git-dir", ["rev-parse", "--absolute-git-dir"], repoPath)).stdout.trim();
626
+ const result = await this.process.run("git", [
627
+ `--git-dir=${gitDir}`,
628
+ `--work-tree=${treePath}`,
629
+ "check-ignore",
630
+ "--no-index",
631
+ "-q",
632
+ "--",
633
+ relativePath,
634
+ ], this.opts(repoPath));
635
+ if (result.code !== 0 && result.code !== 1)
636
+ throw this.failed("check-ignore", repoPath, result.stderr);
637
+ return result.code === 0;
638
+ }
639
+ async ignoredInSource(repoPath, relativePath) {
640
+ const result = await this.process.run("git", ["check-ignore", "--no-index", "-q", "--", relativePath], this.opts(repoPath));
641
+ if (result.code !== 0 && result.code !== 1)
642
+ throw this.failed("check-ignore", repoPath, result.stderr);
643
+ return result.code === 0;
644
+ }
645
+ async excludePattern(repoPath, pattern) {
646
+ const exclude = (await this.mustRun("rev-parse --git-path", ["rev-parse", "--git-path", "info/exclude"], repoPath)).stdout.trim();
647
+ const path = resolve(repoPath, exclude);
648
+ const existing = await readFile(path, "utf8").catch((err) => {
649
+ if (err.code === "ENOENT")
650
+ return "";
651
+ throw err;
652
+ });
653
+ if (!existing.split(/\r?\n/).includes(pattern))
654
+ await appendFile(path, `${existing.length > 0 && !existing.endsWith("\n") ? "\n" : ""}${pattern}\n`);
655
+ }
458
656
  async operationState(repoPath) {
459
657
  // git's own pseudo-refs are the record of an interrupted operation, and asking
460
658
  // git for them keeps this adapter needing only one binary: a `test -d` on
@@ -507,8 +705,8 @@ export class GitCliAdapter {
507
705
  async setRef(repoPath, ref, sha) {
508
706
  return this.attempt("update-ref", ["update-ref", ref, sha], repoPath);
509
707
  }
510
- async deleteRef(repoPath, ref) {
511
- return this.attempt("update-ref -d", ["update-ref", "-d", ref], repoPath);
708
+ async deleteRef(repoPath, ref, expectedOld) {
709
+ return this.attempt("update-ref -d", ["update-ref", "-d", ref, ...(expectedOld ? [expectedOld] : [])], repoPath);
512
710
  }
513
711
  /** Run git and report whether it agreed, with its own words when it did not. */
514
712
  async attempt(label, args, cwd) {
@@ -547,6 +745,16 @@ export class GitCliAdapter {
547
745
  .map((line) => line.trim())
548
746
  .filter((line) => line.length > 0);
549
747
  }
748
+ async upstreamBranch(repoPath, branch) {
749
+ const result = await this.mustRun("for-each-ref upstream", ["for-each-ref", "--format=%(upstream)", `refs/heads/${branch}`], repoPath);
750
+ return result.stdout.trim() || null;
751
+ }
752
+ async readAtRef(repoPath, ref, path) {
753
+ const result = await this.process.run("git", ["show", `${ref}:${path}`], this.opts(repoPath));
754
+ if (result.code !== 0)
755
+ return null;
756
+ return result.stdout;
757
+ }
550
758
  async originFetchRefspecs(repoPath) {
551
759
  const result = await this.process.run("git", ["config", "--get-all", "remote.origin.fetch"], this.opts(repoPath));
552
760
  // `config --get-all` exits 1 when the key is unset: no refspec, not a failure.