@fitlab-ai/agent-infra 0.9.13 → 0.9.15

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 (428) hide show
  1. package/README.md +10 -0
  2. package/README.zh-CN.md +10 -0
  3. package/bin/cli.ts +26 -9
  4. package/bin/internal-cli.sh +45 -0
  5. package/dist/bin/cli.js +173 -157
  6. package/dist/bin/internal-cli.js +126 -42
  7. package/dist/lib/agent-client.js +5 -0
  8. package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +165 -27
  9. package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +3 -2
  10. package/dist/lib/defaults.json +103 -103
  11. package/dist/lib/fs/durable-write.js +37 -0
  12. package/dist/lib/fs/file-lock.js +111 -0
  13. package/dist/lib/host-control/audit.js +19 -0
  14. package/dist/lib/host-control/client.js +142 -0
  15. package/dist/lib/host-control/command.js +49 -0
  16. package/dist/lib/host-control/path.js +160 -0
  17. package/dist/lib/host-control/secure-fs.js +140 -0
  18. package/dist/lib/host-control/server.js +159 -0
  19. package/dist/lib/host-control/service.js +112 -0
  20. package/dist/lib/init.js +11 -2
  21. package/dist/lib/internal/agent-client.js +5 -2
  22. package/dist/lib/internal/cli-route-inventory.js +154 -0
  23. package/dist/lib/internal/codex-lifecycle.js +15 -12
  24. package/dist/lib/internal/codex-sandbox-controller.js +8 -2
  25. package/dist/lib/internal/demo-promotion.js +322 -0
  26. package/dist/lib/internal/demo-transcript.js +454 -0
  27. package/dist/lib/internal/git-workflow.js +10 -6
  28. package/dist/lib/internal/host-control.js +28 -0
  29. package/dist/lib/internal/manual-validation.js +322 -0
  30. package/dist/lib/internal/platform-checks.js +16 -4
  31. package/dist/lib/internal/platform-comment.js +16 -4
  32. package/dist/lib/internal/platform-context.js +4 -1
  33. package/dist/lib/internal/platform-issue.js +12 -4
  34. package/dist/lib/internal/platform-metadata.js +88 -0
  35. package/dist/lib/internal/platform-pr-review.js +16 -3
  36. package/dist/lib/internal/platform-pr.js +42 -14
  37. package/dist/lib/internal/platform-release-notes.js +6 -3
  38. package/dist/lib/internal/platform-security.js +93 -0
  39. package/dist/lib/internal/pr-review-grade.js +14 -3
  40. package/dist/lib/internal/release-workflow.js +82 -89
  41. package/dist/lib/internal/sandbox-control.js +171 -7
  42. package/dist/lib/internal/task-activity.js +13 -4
  43. package/dist/lib/internal/task-artifact.js +19 -107
  44. package/dist/lib/internal/task-context.js +4 -1
  45. package/dist/lib/internal/task-create.js +48 -14
  46. package/dist/lib/internal/task-delivery.js +4 -1
  47. package/dist/lib/internal/task-event.js +38 -35
  48. package/dist/lib/internal/task-finalization.js +4 -1
  49. package/dist/lib/internal/task-invalidation.js +4 -1
  50. package/dist/lib/internal/task-ledger.js +12 -1
  51. package/dist/lib/internal/task-lifecycle.js +4 -1
  52. package/dist/lib/internal/task-operation-registry.js +519 -0
  53. package/dist/lib/internal/task-orchestration.js +12 -0
  54. package/dist/lib/internal/task-override.js +10 -3
  55. package/dist/lib/internal/task-qualification.js +90 -0
  56. package/dist/lib/internal/task-review.js +10 -52
  57. package/dist/lib/internal/task-short-id.js +11 -1
  58. package/dist/lib/internal/task-snapshot.js +4 -1
  59. package/dist/lib/internal/task-validate.js +37 -12
  60. package/dist/lib/internal/task-verify.js +5 -1
  61. package/dist/lib/internal/task-warning.js +8 -1
  62. package/dist/lib/owned-path.js +33 -0
  63. package/dist/lib/platform/check-status.js +11 -0
  64. package/dist/lib/platform/comment-safety.js +229 -0
  65. package/dist/lib/platform/completion-backfill.js +1 -1
  66. package/dist/lib/platform/github-data.js +241 -0
  67. package/dist/lib/platform/github-provider.js +248 -26
  68. package/dist/lib/platform/issue-comments.js +146 -34
  69. package/dist/lib/platform/issues.js +1 -179
  70. package/dist/lib/platform/pr-change-report.js +6 -12
  71. package/dist/lib/platform/pr-checks.js +12 -65
  72. package/dist/lib/platform/pr-summary.js +83 -10
  73. package/dist/lib/platform/provider-contract.d.ts +67 -1
  74. package/dist/lib/platform/provider-contract.js +6 -2
  75. package/dist/lib/platform/provider-validation.js +76 -3
  76. package/dist/lib/platform/pull-requests.js +117 -275
  77. package/dist/lib/platform/repository-metadata.js +377 -0
  78. package/dist/lib/platform/security-alerts.js +155 -0
  79. package/dist/lib/platform/snapshots.js +2 -0
  80. package/dist/lib/platform/verification-sync.js +154 -162
  81. package/dist/lib/process-data/index.js +7 -0
  82. package/dist/lib/release/workflow.js +1 -1
  83. package/dist/lib/run/index.js +5 -0
  84. package/dist/lib/sandbox/commands/control-status.js +22 -0
  85. package/dist/lib/sandbox/commands/create.js +39 -8
  86. package/dist/lib/sandbox/commands/ls.js +5 -0
  87. package/dist/lib/sandbox/commands/rm.js +3 -807
  88. package/dist/lib/sandbox/commands/show.js +16 -0
  89. package/dist/lib/sandbox/control/audit.js +203 -0
  90. package/dist/lib/sandbox/control/client.js +125 -12
  91. package/dist/lib/sandbox/control/completed-reentry.js +85 -0
  92. package/dist/lib/sandbox/control/container-identity.js +28 -31
  93. package/dist/lib/sandbox/control/executor.js +233 -34
  94. package/dist/lib/sandbox/control/finalization-response.js +27 -0
  95. package/dist/lib/sandbox/control/identity-sentinel.js +107 -0
  96. package/dist/lib/sandbox/control/lifecycle.js +656 -128
  97. package/dist/lib/sandbox/control/native-file-lock.js +85 -0
  98. package/dist/lib/sandbox/control/protocol.js +55 -4
  99. package/dist/lib/sandbox/control/server.js +720 -79
  100. package/dist/lib/sandbox/control/state.js +63 -3
  101. package/dist/lib/sandbox/control/task-view.js +183 -0
  102. package/dist/lib/sandbox/control/task-workflow.js +74 -0
  103. package/dist/lib/sandbox/control/workflow-executor.js +99 -0
  104. package/dist/lib/sandbox/engines/authority.js +289 -0
  105. package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
  106. package/dist/lib/sandbox/index.js +7 -2
  107. package/dist/lib/sandbox/recovery.js +49 -5
  108. package/dist/lib/sandbox/removal.js +1717 -0
  109. package/dist/lib/sandbox/task-cleanup.js +217 -0
  110. package/dist/lib/sandbox/workspace-view.js +15 -15
  111. package/dist/lib/sandbox/worktree-safety.js +4 -1
  112. package/dist/lib/server/index.js +8 -0
  113. package/dist/lib/task/activity-intent.js +2 -1
  114. package/dist/lib/task/activity-log.js +30 -24
  115. package/dist/lib/task/artifact-command.js +101 -0
  116. package/dist/lib/task/artifact-lifecycle.js +71 -40
  117. package/dist/lib/task/artifact-name.js +36 -0
  118. package/dist/lib/task/artifact-operations.js +474 -0
  119. package/dist/lib/task/artifact-receipts.js +3 -15
  120. package/dist/lib/task/artifact-repair-intent.js +130 -0
  121. package/dist/lib/task/artifact-schema.js +127 -0
  122. package/dist/lib/task/capabilities.js +83 -19
  123. package/dist/lib/task/codex-orchestration.js +71 -25
  124. package/dist/lib/task/commit-identity.js +28 -0
  125. package/dist/lib/task/commit-operation.js +2 -16
  126. package/dist/lib/task/control-authority.js +375 -5
  127. package/dist/lib/task/control-recovery.js +128 -0
  128. package/dist/lib/task/create-service.js +103 -4
  129. package/dist/lib/task/create.js +80 -2
  130. package/dist/lib/task/decision-details.js +2 -46
  131. package/dist/lib/task/events.js +306 -76
  132. package/dist/lib/task/finalization-state.js +9 -0
  133. package/dist/lib/task/human-override.js +3 -6
  134. package/dist/lib/task/implementation-inputs.js +3 -3
  135. package/dist/lib/task/index.js +11 -3
  136. package/dist/lib/task/intermediate-cleanup.js +383 -0
  137. package/dist/lib/task/invalidation.js +18 -65
  138. package/dist/lib/task/ledger-intents.js +7 -22
  139. package/dist/lib/task/ledger.js +1 -3
  140. package/dist/lib/task/lifecycle.js +19 -1
  141. package/dist/lib/task/local-artifact-finalization.js +190 -290
  142. package/dist/lib/task/manual-validation-completion.js +26 -0
  143. package/dist/lib/task/manual-validation-evidence.js +130 -0
  144. package/dist/lib/task/manual-validation-receipt.js +101 -0
  145. package/dist/lib/task/manual-validation-shared.js +40 -0
  146. package/dist/lib/task/manual-validation-transaction.js +243 -0
  147. package/dist/lib/task/markdown.js +47 -0
  148. package/dist/lib/task/orchestration.js +206 -69
  149. package/dist/lib/task/qualification-audit.js +476 -0
  150. package/dist/lib/task/qualification-confirmation.js +109 -0
  151. package/dist/lib/task/qualification-intents.js +148 -0
  152. package/dist/lib/task/review-artifacts.js +23 -40
  153. package/dist/lib/task/review-command.js +25 -0
  154. package/dist/lib/task/review-finalization.js +146 -97
  155. package/dist/lib/task/review-fingerprint.js +2 -2
  156. package/dist/lib/task/sections.js +34 -54
  157. package/dist/lib/task/verification-config.js +11 -0
  158. package/dist/lib/task/verification-engine.js +170 -327
  159. package/dist/lib/task/verification.js +1 -1
  160. package/dist/lib/task/workflow-command.js +17 -0
  161. package/dist/lib/task/workflow-warning-intents.js +0 -16
  162. package/dist/lib/task/workflow-warnings.js +28 -2
  163. package/dist/lib/update.js +2 -0
  164. package/dist/lifecycle-build-manifest.json +3 -3
  165. package/lib/agent-client.ts +9 -0
  166. package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +223 -33
  167. package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +3 -2
  168. package/lib/fs/durable-write.ts +29 -0
  169. package/lib/fs/file-lock.ts +113 -0
  170. package/lib/host-control/audit.ts +22 -0
  171. package/lib/host-control/client.ts +172 -0
  172. package/lib/host-control/command.ts +60 -0
  173. package/lib/host-control/path.ts +167 -0
  174. package/lib/host-control/secure-fs.ts +135 -0
  175. package/lib/host-control/server.ts +180 -0
  176. package/lib/host-control/service.ts +133 -0
  177. package/lib/init.ts +15 -2
  178. package/lib/internal/agent-client.ts +4 -2
  179. package/lib/internal/cli-route-inventory.ts +142 -0
  180. package/lib/internal/codex-lifecycle.ts +14 -12
  181. package/lib/internal/codex-sandbox-controller.ts +7 -2
  182. package/lib/internal/demo-promotion.ts +354 -0
  183. package/lib/internal/demo-transcript.ts +419 -0
  184. package/lib/internal/git-workflow.ts +9 -6
  185. package/lib/internal/host-control.ts +28 -0
  186. package/lib/internal/manual-validation.ts +306 -0
  187. package/lib/internal/platform-checks.ts +12 -4
  188. package/lib/internal/platform-comment.ts +12 -4
  189. package/lib/internal/platform-context.ts +3 -1
  190. package/lib/internal/platform-issue.ts +11 -4
  191. package/lib/internal/platform-metadata.ts +70 -0
  192. package/lib/internal/platform-pr-review.ts +14 -3
  193. package/lib/internal/platform-pr.ts +38 -14
  194. package/lib/internal/platform-release-notes.ts +5 -3
  195. package/lib/internal/platform-security.ts +83 -0
  196. package/lib/internal/pr-review-grade.ts +10 -3
  197. package/lib/internal/release-workflow.ts +91 -87
  198. package/lib/internal/sandbox-control.ts +181 -6
  199. package/lib/internal/task-activity.ts +12 -4
  200. package/lib/internal/task-artifact.ts +15 -79
  201. package/lib/internal/task-context.ts +3 -1
  202. package/lib/internal/task-create.ts +76 -15
  203. package/lib/internal/task-delivery.ts +3 -1
  204. package/lib/internal/task-event.ts +21 -10
  205. package/lib/internal/task-finalization.ts +3 -1
  206. package/lib/internal/task-invalidation.ts +3 -1
  207. package/lib/internal/task-ledger.ts +11 -1
  208. package/lib/internal/task-lifecycle.ts +3 -1
  209. package/lib/internal/task-operation-registry.ts +590 -0
  210. package/lib/internal/task-orchestration.ts +12 -0
  211. package/lib/internal/task-override.ts +9 -3
  212. package/lib/internal/task-qualification.ts +61 -0
  213. package/lib/internal/task-review.ts +7 -50
  214. package/lib/internal/task-short-id.ts +10 -1
  215. package/lib/internal/task-snapshot.ts +3 -1
  216. package/lib/internal/task-validate.ts +32 -12
  217. package/lib/internal/task-verify.ts +4 -1
  218. package/lib/internal/task-warning.ts +7 -1
  219. package/lib/owned-path.ts +26 -0
  220. package/lib/platform/check-status.ts +9 -0
  221. package/lib/platform/comment-safety.ts +255 -0
  222. package/lib/platform/completion-backfill.ts +1 -1
  223. package/lib/platform/github-data.ts +322 -0
  224. package/lib/platform/github-provider.ts +244 -27
  225. package/lib/platform/issue-comments.ts +159 -35
  226. package/lib/platform/issues.ts +4 -245
  227. package/lib/platform/pr-change-report.ts +6 -12
  228. package/lib/platform/pr-checks.ts +13 -77
  229. package/lib/platform/pr-summary.ts +88 -11
  230. package/lib/platform/provider-contract.ts +78 -3
  231. package/lib/platform/provider-validation.ts +85 -3
  232. package/lib/platform/pull-requests.ts +129 -348
  233. package/lib/platform/repository-metadata.ts +453 -0
  234. package/lib/platform/security-alerts.ts +191 -0
  235. package/lib/platform/snapshots.ts +53 -0
  236. package/lib/platform/verification-sync.ts +171 -177
  237. package/lib/process-data/index.ts +7 -0
  238. package/lib/release/workflow.ts +3 -3
  239. package/lib/run/index.ts +5 -0
  240. package/lib/sandbox/commands/control-status.ts +26 -0
  241. package/lib/sandbox/commands/create.ts +53 -12
  242. package/lib/sandbox/commands/ls.ts +7 -0
  243. package/lib/sandbox/commands/rm.ts +3 -996
  244. package/lib/sandbox/commands/show.ts +16 -0
  245. package/lib/sandbox/control/audit.ts +253 -0
  246. package/lib/sandbox/control/client.ts +150 -13
  247. package/lib/sandbox/control/completed-reentry.ts +98 -0
  248. package/lib/sandbox/control/container-identity.ts +27 -43
  249. package/lib/sandbox/control/executor.ts +262 -37
  250. package/lib/sandbox/control/finalization-response.ts +29 -0
  251. package/lib/sandbox/control/identity-sentinel.ts +137 -0
  252. package/lib/sandbox/control/lifecycle.ts +672 -18
  253. package/lib/sandbox/control/native-file-lock.ts +108 -0
  254. package/lib/sandbox/control/protocol.ts +80 -8
  255. package/lib/sandbox/control/server.ts +779 -82
  256. package/lib/sandbox/control/state.ts +84 -3
  257. package/lib/sandbox/control/task-view.ts +240 -0
  258. package/lib/sandbox/control/task-workflow.ts +95 -0
  259. package/lib/sandbox/control/workflow-executor.ts +102 -0
  260. package/lib/sandbox/engines/authority.ts +365 -0
  261. package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
  262. package/lib/sandbox/index.ts +9 -2
  263. package/lib/sandbox/recovery.ts +49 -6
  264. package/lib/sandbox/removal.ts +2144 -0
  265. package/lib/sandbox/task-cleanup.ts +209 -0
  266. package/lib/sandbox/workspace-view.ts +26 -18
  267. package/lib/sandbox/worktree-safety.ts +4 -1
  268. package/lib/server/index.ts +10 -0
  269. package/lib/task/activity-intent.ts +2 -2
  270. package/lib/task/activity-log.ts +27 -19
  271. package/lib/task/artifact-command.ts +104 -0
  272. package/lib/task/artifact-lifecycle.ts +66 -39
  273. package/lib/task/artifact-name.ts +55 -0
  274. package/lib/task/artifact-operations.ts +580 -0
  275. package/lib/task/artifact-receipts.ts +3 -14
  276. package/lib/task/artifact-repair-intent.ts +152 -0
  277. package/lib/task/artifact-schema.ts +163 -0
  278. package/lib/task/capabilities.ts +82 -22
  279. package/lib/task/codex-orchestration.ts +85 -24
  280. package/lib/task/commit-identity.ts +31 -0
  281. package/lib/task/commit-operation.ts +2 -16
  282. package/lib/task/control-authority.ts +513 -6
  283. package/lib/task/control-recovery.ts +174 -0
  284. package/lib/task/create-service.ts +131 -6
  285. package/lib/task/create.ts +83 -1
  286. package/lib/task/decision-details.ts +3 -71
  287. package/lib/task/events.ts +292 -75
  288. package/lib/task/finalization-state.ts +11 -0
  289. package/lib/task/human-override.ts +3 -8
  290. package/lib/task/implementation-inputs.ts +3 -3
  291. package/lib/task/index.ts +16 -3
  292. package/lib/task/intermediate-cleanup.ts +455 -0
  293. package/lib/task/invalidation.ts +18 -62
  294. package/lib/task/ledger-intents.ts +7 -24
  295. package/lib/task/ledger.ts +1 -3
  296. package/lib/task/lifecycle.ts +17 -1
  297. package/lib/task/local-artifact-finalization.ts +223 -388
  298. package/lib/task/manual-validation-completion.ts +40 -0
  299. package/lib/task/manual-validation-evidence.ts +209 -0
  300. package/lib/task/manual-validation-receipt.ts +152 -0
  301. package/lib/task/manual-validation-shared.ts +50 -0
  302. package/lib/task/manual-validation-transaction.ts +304 -0
  303. package/lib/task/markdown.ts +70 -0
  304. package/lib/task/orchestration.ts +191 -68
  305. package/lib/task/qualification-audit.ts +588 -0
  306. package/lib/task/qualification-confirmation.ts +117 -0
  307. package/lib/task/qualification-intents.ts +150 -0
  308. package/lib/task/review-artifacts.ts +21 -41
  309. package/lib/task/review-command.ts +23 -0
  310. package/lib/task/review-finalization.ts +154 -153
  311. package/lib/task/review-fingerprint.ts +2 -2
  312. package/lib/task/sections.ts +33 -52
  313. package/lib/task/verification-config.ts +12 -0
  314. package/lib/task/verification-engine.ts +165 -370
  315. package/lib/task/verification-types.ts +17 -0
  316. package/lib/task/verification.ts +1 -1
  317. package/lib/task/workflow-command.ts +18 -0
  318. package/lib/task/workflow-warning-intents.ts +0 -13
  319. package/lib/task/workflow-warnings.ts +21 -2
  320. package/lib/update.ts +6 -0
  321. package/package.json +7 -2
  322. package/templates/.agents/hooks/lifecycle-delegation.js +6 -6
  323. package/templates/.agents/rules/README.en.md +2 -0
  324. package/templates/.agents/rules/README.zh-CN.md +2 -0
  325. package/templates/.agents/rules/decision-qualification.en.md +22 -0
  326. package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
  327. package/templates/.agents/rules/evidence-reporting.en.md +28 -0
  328. package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
  329. package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
  330. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
  331. package/templates/.agents/rules/local-artifact-repair.en.md +5 -1
  332. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +5 -1
  333. package/templates/.agents/rules/security-alerts.en.md +8 -8
  334. package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
  335. package/templates/.agents/rules/testing-discipline.en.md +2 -0
  336. package/templates/.agents/rules/testing-discipline.zh-CN.md +2 -0
  337. package/templates/.agents/scripts/package.json +3 -0
  338. package/templates/.agents/skills/analyze-task/SKILL.en.md +15 -2
  339. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +19 -2
  340. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
  341. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
  342. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  343. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  344. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  345. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  346. package/templates/.agents/skills/code-task/SKILL.en.md +14 -1
  347. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +14 -1
  348. package/templates/.agents/skills/code-task/config/verify.en.json +5 -14
  349. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +5 -14
  350. package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
  351. package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
  352. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
  353. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
  354. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
  355. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
  356. package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
  357. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
  358. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +37 -21
  359. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +37 -21
  360. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
  361. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
  362. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +4 -0
  363. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +4 -0
  364. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +16 -7
  365. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +16 -7
  366. package/templates/.agents/skills/complete-task/SKILL.en.md +10 -23
  367. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +10 -23
  368. package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
  369. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
  370. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  371. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  372. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  373. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  374. package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
  375. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
  376. package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
  377. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
  378. package/templates/.agents/skills/plan-task/SKILL.en.md +14 -1
  379. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +16 -1
  380. package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
  381. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
  382. package/templates/.agents/skills/release/SKILL.en.md +7 -3
  383. package/templates/.agents/skills/release/SKILL.zh-CN.md +7 -3
  384. package/templates/.agents/skills/review-analysis/SKILL.en.md +14 -1
  385. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +14 -1
  386. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
  387. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
  388. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
  389. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
  390. package/templates/.agents/skills/review-code/SKILL.en.md +14 -1
  391. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +14 -1
  392. package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
  393. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
  394. package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
  395. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
  396. package/templates/.agents/skills/review-plan/SKILL.en.md +14 -1
  397. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +14 -1
  398. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
  399. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
  400. package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
  401. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
  402. package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
  403. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
  404. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
  405. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
  406. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +25 -4
  407. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +25 -4
  408. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.en.md +4 -1
  409. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.zh-CN.md +4 -1
  410. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +5 -1
  411. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +5 -1
  412. package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
  413. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
  414. package/templates/.agents/skills/test/SKILL.en.md +29 -7
  415. package/templates/.agents/skills/test/SKILL.zh-CN.md +29 -7
  416. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
  417. package/templates/.agents/templates/task.en.md +6 -0
  418. package/templates/.agents/templates/task.zh-CN.md +6 -0
  419. package/templates/.claude/commands/run-manual-validation.en.md +1 -1
  420. package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
  421. package/dist/lib/platform/adapters.js +0 -56
  422. package/lib/platform/adapters.ts +0 -197
  423. package/templates/.agents/scripts/security-alerts.github.sh +0 -151
  424. package/templates/.agents/scripts/security-alerts.sh +0 -31
  425. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
  426. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
  427. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
  428. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
@@ -0,0 +1,154 @@
1
+ export const PUBLIC_CLI_COMMAND_ALIASES = Object.freeze({
2
+ '': 'help',
3
+ s: 'sandbox',
4
+ t: 'task',
5
+ '--version': 'version',
6
+ '-v': 'version'
7
+ });
8
+ export const PUBLIC_CLI_SELECTOR_ALIASES = Object.freeze({
9
+ task: Object.freeze({ d: 'decisions' })
10
+ });
11
+ export const PUBLIC_CLI_ROUTE_SELECTORS = Object.freeze({
12
+ 'agent-client': ['list', 'status', 'enable', 'disable', 'configure'],
13
+ cp: ['cp'],
14
+ data: ['capture', 'verify', 'audit', 'repair', 'export'],
15
+ decide: ['decide'],
16
+ help: ['help'],
17
+ init: ['init'],
18
+ merge: ['merge'],
19
+ run: ['create-task', 'task-skill', 'recreate'],
20
+ sandbox: ['create', 'exec', 'ls', 'show', 'prune', 'rebuild', 'refresh', 'rm', 'start', 'vm'],
21
+ server: ['start', 'stop', 'status', 'logs', '__daemon'],
22
+ task: ['cat', 'decisions', 'files', 'grep', 'issue-body', 'log', 'ls', 'show', 'status'],
23
+ sync: ['sync'],
24
+ update: ['update'],
25
+ version: ['version']
26
+ });
27
+ /**
28
+ * The selector definitions consumed by every internal handler. Keep this
29
+ * module free of handler imports so the pre-import task-view guard remains
30
+ * effective.
31
+ */
32
+ export const INTERNAL_HANDLER_ROUTE_SELECTORS = Object.freeze({
33
+ 'task-create': ['input'],
34
+ 'task-qualification': ['proposal', 'confirm', 'supersede', 'revoke'],
35
+ 'sandbox-control': ['serve', 'execute', 'recover', 'client'],
36
+ 'host-control': ['serve', 'status', 'install', 'uninstall'],
37
+ 'agent-client': ['next-steps', 'model-selection'],
38
+ 'codex-lifecycle': ['preflight', 'capability-arm', 'hook-event', 'resolve-start', 'resolve-stop', 'consume'],
39
+ 'codex-sandbox-controller': ['verify-context', 'run'],
40
+ 'git-workflow': ['inspect', 'preview-tree', 'snapshot', 'compare-trees', 'commit', 'push-rebased'],
41
+ 'task-delivery': ['deliver'],
42
+ 'release-workflow': ['inspect', 'prepare', 'publish', 'post-prepare', 'post-publish'],
43
+ 'platform-release-notes': ['context', 'stage', 'publish'],
44
+ 'platform-security': ['read', 'dismiss'],
45
+ 'platform-metadata': ['init-labels', 'init-milestones'],
46
+ 'platform-context': ['resolve'],
47
+ 'platform-comment': ['list', 'owner', 'backfill', 'sync'],
48
+ 'platform-issue': ['inspect', 'create', 'bind', 'sync'],
49
+ 'platform-pr': ['inspect', 'summary-context', 'resolve-external', 'create', 'bind', 'skip', 'sync', 'change-report', 'summary-sync', 'sync-in-labels'],
50
+ 'platform-pr-review': ['inspect', 'list', 'publish-pr', 'publish-task'],
51
+ 'pr-review-grade': ['decide', 'resolve-host', 'verify-artifact'],
52
+ 'platform-checks': ['inspect', 'watch', 'resolve-run', 'logs'],
53
+ 'task-context': ['resolve'],
54
+ 'task-ledger': ['decision-next-id', 'stage-status', 'finding-upsert', 'finding-respond', 'finding-review', 'decision-upsert', 'rework-intent-upsert'],
55
+ 'task-warning': ['list', 'add', 'set-status'],
56
+ 'task-activity': ['pr-review-inspect', 'pr-review-start', 'pr-review-complete', 'pr-review-terminate'],
57
+ 'task-artifact': ['inspect', 'init', 'repair', 'finalize-local'],
58
+ 'task-orchestration': ['status', 'progress'],
59
+ 'task-review': ['finalize-summary'],
60
+ 'task-event': ['event'],
61
+ 'task-invalidation': ['reconcile'],
62
+ 'task-override': ['diagnose', 'issue', 'consume'],
63
+ 'task-lifecycle': ['intent'],
64
+ 'task-finalization': ['complete'],
65
+ 'task-short-id': ['list', 'list-verify', 'alloc', 'release', 'resolve'],
66
+ 'task-snapshot': ['snapshot'],
67
+ 'task-verify': ['event'],
68
+ 'task-validate': ['snapshot', 'inplace'],
69
+ 'manual-validation': ['transaction']
70
+ });
71
+ export const INTERNAL_CLI_ROUTE_SELECTORS = INTERNAL_HANDLER_ROUTE_SELECTORS;
72
+ function first(args) {
73
+ return args[0] ?? '';
74
+ }
75
+ function optionValue(args, name) {
76
+ const index = args.indexOf(name);
77
+ if (index >= 0)
78
+ return args[index + 1];
79
+ const prefix = `${name}=`;
80
+ return args.find((arg) => arg.startsWith(prefix))?.slice(prefix.length);
81
+ }
82
+ export function internalRouteSelector(command, args) {
83
+ if (command === 'sandbox-control')
84
+ return first(args);
85
+ if (command === 'task-create')
86
+ return 'input';
87
+ if (command === 'task-qualification')
88
+ return args[1] ?? '';
89
+ if (command === 'task-lifecycle')
90
+ return args[1] ? 'intent' : '';
91
+ if (command === 'task-finalization')
92
+ return args[1] === 'complete' ? 'complete' : '';
93
+ if (command === 'task-event')
94
+ return args[1] ? 'event' : '';
95
+ if (command === 'task-verify')
96
+ return args[0] && args[1] ? 'event' : '';
97
+ if (command === 'task-snapshot')
98
+ return 'snapshot';
99
+ if (command === 'task-validate')
100
+ return optionValue(args, '--scope') ?? 'snapshot';
101
+ if (command === 'task-short-id')
102
+ return first(args) === 'list' && args.includes('--verify') ? 'list-verify' : first(args);
103
+ if (command === 'task-orchestration')
104
+ return args[1] === 'status' ? 'status' : args[1] ? 'progress' : '';
105
+ if (command === 'task-review')
106
+ return args[1] ?? '';
107
+ if (command === 'task-invalidation')
108
+ return args[1] ?? '';
109
+ if (command === 'task-override')
110
+ return args[1] ?? '';
111
+ if (command === 'task-artifact')
112
+ return args[1] ?? '';
113
+ if (command === 'platform-pr-review' && first(args) === 'publish') {
114
+ const scope = optionValue(args, '--scope') ?? '';
115
+ return /^TASK-\d{8}-\d{6}$/u.test(scope) ? 'publish-task' : /^pr\d+$/u.test(scope) ? 'publish-pr' : '';
116
+ }
117
+ if (['task-ledger', 'task-warning', 'task-activity'].includes(command))
118
+ return args[1] ?? '';
119
+ if (command === 'task-delivery')
120
+ return args[1] ?? '';
121
+ if (command === 'task-context')
122
+ return first(args);
123
+ return first(args);
124
+ }
125
+ export function isInternalHandlerRoute(command, args) {
126
+ if (args[0] === '--help' || args[0] === '-h')
127
+ return true;
128
+ const selector = internalRouteSelector(command, args);
129
+ const selectors = INTERNAL_HANDLER_ROUTE_SELECTORS[command];
130
+ return Boolean(selector && selectors?.some((candidate) => candidate === selector));
131
+ }
132
+ /**
133
+ * Marks a selector at the handler's actual dispatch branch.
134
+ *
135
+ * The call is intentionally side-effect free so the top-level task-view guard
136
+ * can still run before a handler module is imported. Route coverage tests read
137
+ * these branch markers independently from the pre-import inventory.
138
+ */
139
+ export function internalHandlerRoute(command, selector, actualSelector) {
140
+ return command.length > 0 && selector === actualSelector;
141
+ }
142
+ export function ensureInternalHandlerRoute(command, args) {
143
+ if (isInternalHandlerRoute(command, args))
144
+ return true;
145
+ const selector = internalRouteSelector(command, args);
146
+ process.stdout.write(`${JSON.stringify({
147
+ status: 'failed',
148
+ changed: false,
149
+ error: { code: 'INTERNAL_ROUTE_UNREGISTERED', message: `operation '${command} ${selector || first(args)}' is not registered` }
150
+ })}\n`);
151
+ process.exitCode = 1;
152
+ return false;
153
+ }
154
+ //# sourceMappingURL=cli-route-inventory.js.map
@@ -10,6 +10,7 @@ import { verifyCodexSandboxControllerContextWithWarnings } from '../agent-client
10
10
  import { resolveTaskRef } from '../task/resolve-ref.js';
11
11
  import { hasSealableOrchestrationDelegation } from '../task/orchestration.js';
12
12
  import { activateCodexOrchestrationDelegation, activateCodexSpawnDelegation, reconcileCodexOrchestrationDelegation, sealCodexOrchestrationDelegation, sealCodexParentDelegation } from '../task/codex-orchestration.js';
13
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
13
14
  const USAGE = 'Usage: agent-infra-internal codex-lifecycle <capability-arm|hook-event|resolve-start|resolve-stop|preflight|consume> [options]\n';
14
15
  const MANAGED_AGENT = /^agent-infra-lifecycle-(executor|reviewer)$/;
15
16
  function output(value) {
@@ -144,11 +145,13 @@ function payloadText(payload, key) {
144
145
  : '';
145
146
  }
146
147
  async function codexLifecycle(args = []) {
148
+ if (!ensureInternalHandlerRoute('codex-lifecycle', args))
149
+ return;
147
150
  const parsed = parse(args);
148
151
  if (!parsed || process.exitCode)
149
152
  return;
150
153
  try {
151
- if (parsed.operation === 'preflight') {
154
+ if (internalHandlerRoute('codex-lifecycle', 'preflight', parsed.operation)) {
152
155
  const format = parsed.values['--format'] ?? 'json';
153
156
  if (!['text', 'json'].includes(format))
154
157
  throw new Error("format must be 'text' or 'json'");
@@ -173,7 +176,7 @@ async function codexLifecycle(args = []) {
173
176
  output({ status: 'ready', changed: false, evidence: result, diagnostics: result.diagnostics, error: null });
174
177
  return;
175
178
  }
176
- if (parsed.operation === 'capability-arm') {
179
+ if (internalHandlerRoute('codex-lifecycle', 'capability-arm', parsed.operation)) {
177
180
  const taskId = parsed.values['--task-id'];
178
181
  if (!taskId)
179
182
  throw new Error('capability-arm requires --task-id');
@@ -188,7 +191,7 @@ async function codexLifecycle(args = []) {
188
191
  output({
189
192
  status: 'armed',
190
193
  changed: true,
191
- capabilityToken: armed.token,
194
+ capabilityRef: armed.capabilityRef,
192
195
  marker: armed.marker,
193
196
  expiresAt: armed.expiresAt,
194
197
  buildIdentity: armed.buildIdentity,
@@ -197,7 +200,7 @@ async function codexLifecycle(args = []) {
197
200
  return;
198
201
  }
199
202
  const store = createCodexLifecycleStore({ cliVersion: cliVersion() });
200
- if (parsed.operation === 'hook-event') {
203
+ if (internalHandlerRoute('codex-lifecycle', 'hook-event', parsed.operation)) {
201
204
  const phase = parsed.values['--event'];
202
205
  if (!phase || !['pre-tool', 'subagent-start', 'post-tool', 'subagent-stop'].includes(phase)) {
203
206
  throw new Error('hook-event requires a known --event');
@@ -207,12 +210,12 @@ async function codexLifecycle(args = []) {
207
210
  }
208
211
  const payload = await readStdin();
209
212
  if (phase === 'post-tool') {
210
- const capabilityToken = payloadText(payload, 'capabilityToken');
211
- if (capabilityToken) {
213
+ const capabilityRef = payloadText(payload, 'capabilityRef');
214
+ if (capabilityRef) {
212
215
  const capabilityStore = createCodexCapabilityStore();
213
- const armed = capabilityStore.inspect(capabilityToken);
214
- const capability = createCodexCapabilityStore().attest({
215
- token: capabilityToken,
216
+ const armed = capabilityStore.inspectReference(capabilityRef);
217
+ const capability = capabilityStore.attestByReference({
218
+ capabilityRef,
216
219
  sessionId: payloadText(payload, 'sessionId'),
217
220
  turnId: payloadText(payload, 'turnId'),
218
221
  toolUseId: payloadText(payload, 'toolUseId'),
@@ -337,7 +340,7 @@ async function codexLifecycle(args = []) {
337
340
  const childThreadId = parsed.values['--child-id'];
338
341
  if (!childThreadId)
339
342
  throw new Error(`operation '${parsed.operation}' requires --child-id`);
340
- if (parsed.operation === 'resolve-start') {
343
+ if (internalHandlerRoute('codex-lifecycle', 'resolve-start', parsed.operation)) {
341
344
  if (store.read(childThreadId).state.spawn?.hookDefinitionHash !== hookDefinitionHash()) {
342
345
  throw new Error('Codex lifecycle hook definition hash is stale');
343
346
  }
@@ -351,7 +354,7 @@ async function codexLifecycle(args = []) {
351
354
  process.exitCode = 1;
352
355
  return;
353
356
  }
354
- if (parsed.operation === 'resolve-stop') {
357
+ if (internalHandlerRoute('codex-lifecycle', 'resolve-stop', parsed.operation)) {
355
358
  const stopTurnId = store.read(childThreadId).state.stop?.turnId;
356
359
  if (!stopTurnId)
357
360
  throw new Error('Codex lifecycle stop hook is not available');
@@ -363,7 +366,7 @@ async function codexLifecycle(args = []) {
363
366
  output({ status: latest.state.status, changed: true, evidence: latest.state.stopEvidence, diagnostics: [], error: latest.state.error });
364
367
  return;
365
368
  }
366
- if (parsed.operation === 'consume') {
369
+ if (internalHandlerRoute('codex-lifecycle', 'consume', parsed.operation)) {
367
370
  const consumer = parsed.values['--consumer'];
368
371
  if (!consumer)
369
372
  throw new Error('consume requires --consumer');
@@ -1,4 +1,5 @@
1
1
  import { runCodexSandboxController, verifyCodexSandboxControllerContextWithWarnings } from '../agent-clients/adapters/codex-lifecycle/sandbox-controller.js';
2
+ import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.js';
2
3
  const USAGE = 'Usage: agent-infra-internal codex-sandbox-controller <run|verify-context> [options]\n';
3
4
  function fail(code, message, exitCode = 1) {
4
5
  process.stdout.write(`${JSON.stringify({
@@ -14,7 +15,10 @@ function parse(args) {
14
15
  return null;
15
16
  }
16
17
  const operation = args[0];
17
- if (!operation || !['run', 'verify-context'].includes(operation)) {
18
+ if (!operation || ![
19
+ internalHandlerRoute('codex-sandbox-controller', 'run', operation),
20
+ internalHandlerRoute('codex-sandbox-controller', 'verify-context', operation)
21
+ ].some(Boolean)) {
18
22
  process.stderr.write(USAGE);
19
23
  fail('CODEX_SANDBOX_CONTROLLER_PAYLOAD_INVALID', 'operation must be run or verify-context', 2);
20
24
  return null;
@@ -44,11 +48,13 @@ function parse(args) {
44
48
  return { operation, values };
45
49
  }
46
50
  async function codexSandboxController(args = []) {
51
+ if (!ensureInternalHandlerRoute('codex-sandbox-controller', args))
52
+ return;
47
53
  const parsed = parse(args);
48
54
  if (!parsed || process.exitCode)
49
55
  return;
50
56
  try {
51
- if (parsed.operation === 'verify-context') {
57
+ if (internalHandlerRoute('codex-sandbox-controller', 'verify-context', parsed.operation)) {
52
58
  const contextPath = parsed.values['--context']
53
59
  ?? process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
54
60
  if (!contextPath)
@@ -0,0 +1,322 @@
1
+ import crypto from 'node:crypto';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ const DEMO_ASSET_NAMES = ['gif', 'transcript', 'sha256'];
5
+ const JOURNAL_RELATIVE_PATH = 'assets/.demo-init.promotion.json';
6
+ const PROMOTION_DIR_PREFIX = '.demo-init.promotion-';
7
+ function sha256Bytes(value) {
8
+ return crypto.createHash('sha256').update(value).digest('hex');
9
+ }
10
+ function sha256File(filePath, io = fs) {
11
+ return sha256Bytes(io.readFileSync(filePath));
12
+ }
13
+ function assetTargets(cwd) {
14
+ return {
15
+ gif: path.join(cwd, 'assets', 'demo-init.gif'),
16
+ transcript: path.join(cwd, 'assets', 'demo-init.transcript'),
17
+ sha256: path.join(cwd, 'assets', 'demo-init.transcript.sha256')
18
+ };
19
+ }
20
+ function journalPath(cwd) {
21
+ return path.join(cwd, JOURNAL_RELATIVE_PATH);
22
+ }
23
+ function isUnsupportedFsyncError(error) {
24
+ const code = error.code;
25
+ return code === 'EINVAL' || code === 'ENOSYS' || code === 'ENOTSUP' || code === 'EPERM';
26
+ }
27
+ function syncFile(filePath, io) {
28
+ if (!io.openSync || !io.closeSync || !io.fsyncSync)
29
+ return;
30
+ const descriptor = io.openSync(filePath, 'r');
31
+ try {
32
+ try {
33
+ io.fsyncSync(descriptor);
34
+ }
35
+ catch (error) {
36
+ if (!isUnsupportedFsyncError(error))
37
+ throw error;
38
+ }
39
+ }
40
+ finally {
41
+ io.closeSync(descriptor);
42
+ }
43
+ }
44
+ function writeJournal(cwd, journal, io) {
45
+ const target = journalPath(cwd);
46
+ const temporary = `${target}.tmp-${process.pid}`;
47
+ io.writeFileSync(temporary, `${JSON.stringify(journal, null, 2)}\n`);
48
+ syncFile(temporary, io);
49
+ try {
50
+ io.renameSync(temporary, target);
51
+ }
52
+ catch (error) {
53
+ try {
54
+ io.unlinkSync(temporary);
55
+ }
56
+ catch { /* preserve primary error */ }
57
+ throw error;
58
+ }
59
+ }
60
+ function existingRegularFile(filePath, io) {
61
+ if (!io.existsSync(filePath))
62
+ return false;
63
+ const stat = io.lstatSync(filePath);
64
+ if (!stat.isFile() || stat.isSymbolicLink())
65
+ throw new Error(`promotion target is not a regular file: ${filePath}`);
66
+ return true;
67
+ }
68
+ function removeIfPresent(filePath, io) {
69
+ if (io.existsSync(filePath))
70
+ io.unlinkSync(filePath);
71
+ }
72
+ function samePath(left, right) {
73
+ return path.normalize(path.resolve(left)) === path.normalize(path.resolve(right));
74
+ }
75
+ function pathIsInside(root, candidate) {
76
+ const relative = path.relative(root, candidate);
77
+ return relative !== '' && !path.isAbsolute(relative) && relative !== '..' && !relative.startsWith(`..${path.sep}`);
78
+ }
79
+ function existingStat(filePath, io) {
80
+ try {
81
+ return io.lstatSync(filePath);
82
+ }
83
+ catch (error) {
84
+ if (error.code === 'ENOENT')
85
+ return null;
86
+ throw error;
87
+ }
88
+ }
89
+ function validatePromotionJournal(cwd, journal, io) {
90
+ if (!journal || typeof journal !== 'object')
91
+ throw new Error('promotion journal is invalid');
92
+ if (journal.version !== 1 || !['prepared', 'promoting', 'committed'].includes(journal.phase)) {
93
+ throw new Error('promotion journal is invalid');
94
+ }
95
+ if (typeof journal.generation !== 'string' || !journal.generation || /[\r\n]/u.test(journal.generation)) {
96
+ throw new Error('promotion journal generation is invalid');
97
+ }
98
+ if (!Array.isArray(journal.entries) || journal.entries.length !== DEMO_ASSET_NAMES.length) {
99
+ throw new Error('promotion journal entries are invalid');
100
+ }
101
+ if (!Number.isInteger(journal.currentIndex) || journal.currentIndex < -1 || journal.currentIndex >= journal.entries.length) {
102
+ throw new Error('promotion journal index is invalid');
103
+ }
104
+ const assets = path.join(cwd, 'assets');
105
+ const assetsStat = existingStat(assets, io);
106
+ if (!assetsStat || assetsStat.isSymbolicLink() || !assetsStat.isDirectory()) {
107
+ throw new Error('promotion assets directory is invalid');
108
+ }
109
+ if (typeof journal.directory !== 'string' || path.isAbsolute(journal.directory)) {
110
+ throw new Error('promotion journal directory is invalid');
111
+ }
112
+ const directory = path.resolve(cwd, journal.directory);
113
+ const directoryName = path.basename(directory);
114
+ if (!directoryName.startsWith(PROMOTION_DIR_PREFIX) || directoryName === PROMOTION_DIR_PREFIX
115
+ || journal.directory !== path.relative(cwd, directory)
116
+ || !samePath(directory, path.join(assets, directoryName))) {
117
+ throw new Error('promotion journal directory is invalid');
118
+ }
119
+ const directoryStat = existingStat(directory, io);
120
+ if (directoryStat && (directoryStat.isSymbolicLink() || !directoryStat.isDirectory())) {
121
+ throw new Error('promotion journal directory is invalid');
122
+ }
123
+ const targets = assetTargets(cwd);
124
+ for (const [index, name] of DEMO_ASSET_NAMES.entries()) {
125
+ const entry = journal.entries[index];
126
+ if (!entry || entry.name !== name || typeof entry.target !== 'string' || typeof entry.staging !== 'string'
127
+ || typeof entry.backup !== 'string' || typeof entry.existed !== 'boolean'
128
+ || (entry.oldSha256 !== null && typeof entry.oldSha256 !== 'string')
129
+ || typeof entry.newSha256 !== 'string') {
130
+ throw new Error('promotion journal entry is invalid');
131
+ }
132
+ const target = targets[name];
133
+ const staging = path.join(directory, path.basename(target));
134
+ const backup = path.join(directory, `old-${name}`);
135
+ if (!samePath(entry.target, target) || !samePath(entry.staging, staging) || !samePath(entry.backup, backup)) {
136
+ throw new Error(`promotion journal path is invalid: ${name}`);
137
+ }
138
+ for (const [label, filePath] of [['target', target], ['staging', staging], ['backup', backup]]) {
139
+ if (!pathIsInside(assets, filePath))
140
+ throw new Error(`promotion journal path is invalid: ${name}.${label}`);
141
+ const stat = existingStat(filePath, io);
142
+ if (stat && (stat.isSymbolicLink() || !stat.isFile())) {
143
+ throw new Error(`promotion journal path is invalid: ${name}.${label}`);
144
+ }
145
+ }
146
+ if (entry.existed !== (entry.oldSha256 !== null)) {
147
+ throw new Error(`promotion journal entry is invalid: ${name}`);
148
+ }
149
+ }
150
+ return journal;
151
+ }
152
+ function cleanupJournal(journal, cwd, io) {
153
+ for (const entry of journal.entries) {
154
+ removeIfPresent(entry.staging, io);
155
+ removeIfPresent(entry.backup, io);
156
+ }
157
+ io.rmSync(path.join(cwd, journal.directory), { recursive: true, force: true });
158
+ removeIfPresent(journalPath(cwd), io);
159
+ }
160
+ function verifyTargets(entries, io, expected) {
161
+ for (const entry of entries) {
162
+ if (!entry.existed && expected === 'old') {
163
+ if (io.existsSync(entry.target))
164
+ throw new Error(`old promotion target unexpectedly exists: ${entry.target}`);
165
+ continue;
166
+ }
167
+ if (!io.existsSync(entry.target))
168
+ throw new Error(`promotion target is missing: ${entry.target}`);
169
+ const actual = sha256File(entry.target, io);
170
+ const wanted = expected === 'old' ? entry.oldSha256 : entry.newSha256;
171
+ if (!wanted || actual !== wanted)
172
+ throw new Error(`promotion target has unexpected content: ${entry.target}`);
173
+ }
174
+ }
175
+ function restoreOld(journal, io) {
176
+ for (const entry of [...journal.entries].reverse()) {
177
+ if (!entry.existed) {
178
+ removeIfPresent(entry.target, io);
179
+ continue;
180
+ }
181
+ if (!io.existsSync(entry.backup) || sha256File(entry.backup, io) !== entry.oldSha256) {
182
+ throw new Error(`promotion backup is missing or corrupt: ${entry.backup}`);
183
+ }
184
+ const restore = `${entry.target}.restore-${process.pid}`;
185
+ io.copyFileSync(entry.backup, restore);
186
+ removeIfPresent(entry.target, io);
187
+ io.renameSync(restore, entry.target);
188
+ }
189
+ verifyTargets(journal.entries, io, 'old');
190
+ }
191
+ function recoveryFailure(error) {
192
+ return {
193
+ status: 'failed',
194
+ code: 'DEMO_PROMOTION_RECOVERY_REQUIRED',
195
+ message: error instanceof Error ? error.message : String(error)
196
+ };
197
+ }
198
+ function recoverDemoPromotion(cwd, io = fs) {
199
+ const target = journalPath(cwd);
200
+ if (!io.existsSync(target))
201
+ return null;
202
+ let journal;
203
+ try {
204
+ const journalStat = io.lstatSync(target);
205
+ if (journalStat.isSymbolicLink() || !journalStat.isFile())
206
+ throw new Error('promotion journal is invalid');
207
+ journal = JSON.parse(io.readFileSync(target, 'utf8'));
208
+ journal = validatePromotionJournal(cwd, journal, io);
209
+ if (journal.phase === 'committed') {
210
+ try {
211
+ verifyTargets(journal.entries, io, 'new');
212
+ }
213
+ catch {
214
+ restoreOld(journal, io);
215
+ }
216
+ }
217
+ else {
218
+ restoreOld(journal, io);
219
+ }
220
+ cleanupJournal(journal, cwd, io);
221
+ return { status: 'committed', code: null, message: null };
222
+ }
223
+ catch (error) {
224
+ return recoveryFailure(error);
225
+ }
226
+ }
227
+ function createDemoPromotion(cwd, transcript) {
228
+ const assets = path.join(cwd, 'assets');
229
+ const directory = fs.mkdtempSync(path.join(assets, PROMOTION_DIR_PREFIX));
230
+ const staging = {
231
+ gif: path.join(directory, 'demo-init.gif'),
232
+ transcript: path.join(directory, 'demo-init.transcript'),
233
+ sha256: path.join(directory, 'demo-init.transcript.sha256')
234
+ };
235
+ const sha256 = sha256Bytes(Buffer.from(transcript, 'utf8'));
236
+ fs.writeFileSync(staging.transcript, transcript);
237
+ fs.writeFileSync(staging.sha256, `${sha256}\n`);
238
+ return { directory, staging, sha256 };
239
+ }
240
+ function promoteDemoAssets(cwd, staging, generation, io = fs) {
241
+ const targets = assetTargets(cwd);
242
+ const directory = path.relative(cwd, path.dirname(staging.gif));
243
+ const journal = {
244
+ version: 1,
245
+ generation,
246
+ phase: 'prepared',
247
+ currentIndex: -1,
248
+ directory,
249
+ entries: []
250
+ };
251
+ try {
252
+ for (const name of DEMO_ASSET_NAMES) {
253
+ if (!io.existsSync(staging[name]))
254
+ throw new Error(`staged demo asset is missing: ${staging[name]}`);
255
+ const target = targets[name];
256
+ const backup = path.join(path.dirname(staging[name]), `old-${name}`);
257
+ const existed = existingRegularFile(target, io);
258
+ const oldSha256 = existed ? sha256File(target, io) : null;
259
+ if (existed) {
260
+ io.copyFileSync(target, backup);
261
+ if (sha256File(backup, io) !== oldSha256)
262
+ throw new Error(`promotion backup verification failed: ${target}`);
263
+ }
264
+ journal.entries.push({
265
+ name, target, staging: staging[name], backup, existed, oldSha256,
266
+ newSha256: sha256File(staging[name], io)
267
+ });
268
+ }
269
+ writeJournal(cwd, journal, io);
270
+ for (let index = 0; index < journal.entries.length; index += 1) {
271
+ journal.phase = 'promoting';
272
+ journal.currentIndex = index;
273
+ writeJournal(cwd, journal, io);
274
+ const entry = journal.entries[index];
275
+ removeIfPresent(entry.target, io);
276
+ io.renameSync(entry.staging, entry.target);
277
+ if (sha256File(entry.target, io) !== entry.newSha256)
278
+ throw new Error(`promoted asset verification failed: ${entry.target}`);
279
+ writeJournal(cwd, journal, io);
280
+ }
281
+ verifyTargets(journal.entries, io, 'new');
282
+ journal.phase = 'committed';
283
+ writeJournal(cwd, journal, io);
284
+ try {
285
+ cleanupJournal(journal, cwd, io);
286
+ }
287
+ catch (error) {
288
+ return {
289
+ status: 'failed',
290
+ code: 'DEMO_PROMOTION_CLEANUP_FAILED',
291
+ message: error instanceof Error ? error.message : String(error)
292
+ };
293
+ }
294
+ return { status: 'committed', code: null, message: null };
295
+ }
296
+ catch (error) {
297
+ try {
298
+ if (io.existsSync(journalPath(cwd))) {
299
+ const persisted = validatePromotionJournal(cwd, JSON.parse(io.readFileSync(journalPath(cwd), 'utf8')), io);
300
+ if (persisted.phase === 'committed') {
301
+ verifyTargets(persisted.entries, io, 'new');
302
+ return {
303
+ status: 'failed',
304
+ code: 'DEMO_PROMOTION_CLEANUP_FAILED',
305
+ message: error instanceof Error ? error.message : String(error)
306
+ };
307
+ }
308
+ restoreOld(persisted, io);
309
+ cleanupJournal(persisted, cwd, io);
310
+ }
311
+ else {
312
+ io.rmSync(path.dirname(staging.gif), { recursive: true, force: true });
313
+ }
314
+ return { status: 'failed', code: 'DEMO_PROMOTION_FAILED', message: error instanceof Error ? error.message : String(error) };
315
+ }
316
+ catch (rollbackError) {
317
+ return recoveryFailure(rollbackError);
318
+ }
319
+ }
320
+ }
321
+ export { DEMO_ASSET_NAMES, JOURNAL_RELATIVE_PATH, assetTargets, createDemoPromotion, journalPath, promoteDemoAssets, recoverDemoPromotion, sha256Bytes };
322
+ //# sourceMappingURL=demo-promotion.js.map