@intentius/chant 0.13.1 → 0.15.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 (450) hide show
  1. package/dist/audit/catalog.d.ts +45 -5
  2. package/dist/audit/catalog.d.ts.map +1 -1
  3. package/dist/audit/proof.d.ts +3 -0
  4. package/dist/audit/proof.d.ts.map +1 -1
  5. package/dist/audit/report-model.d.ts +4 -1
  6. package/dist/audit/report-model.d.ts.map +1 -1
  7. package/dist/audit/report.d.ts +3 -0
  8. package/dist/audit/report.d.ts.map +1 -1
  9. package/dist/audit/rules-doc.d.ts +8 -2
  10. package/dist/audit/rules-doc.d.ts.map +1 -1
  11. package/dist/cli/commands/audit.d.ts.map +1 -1
  12. package/dist/cli/commands/doctor.d.ts.map +1 -1
  13. package/dist/cli/commands/lexicon-rolling-upgrade.d.ts +37 -0
  14. package/dist/cli/commands/lexicon-rolling-upgrade.d.ts.map +1 -0
  15. package/dist/cli/commands/lexicon-surface-diff.d.ts +48 -0
  16. package/dist/cli/commands/lexicon-surface-diff.d.ts.map +1 -0
  17. package/dist/cli/commands/lint.d.ts.map +1 -1
  18. package/dist/cli/commands/pinned-upgrade.d.ts +41 -0
  19. package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -0
  20. package/dist/cli/handlers/build.d.ts.map +1 -1
  21. package/dist/cli/handlers/components.d.ts +39 -0
  22. package/dist/cli/handlers/components.d.ts.map +1 -0
  23. package/dist/cli/handlers/dev.d.ts +3 -0
  24. package/dist/cli/handlers/dev.d.ts.map +1 -1
  25. package/dist/cli/handlers/graph.d.ts +4 -2
  26. package/dist/cli/handlers/graph.d.ts.map +1 -1
  27. package/dist/cli/handlers/misc.d.ts.map +1 -1
  28. package/dist/cli/handlers/run.d.ts +49 -0
  29. package/dist/cli/handlers/run.d.ts.map +1 -1
  30. package/dist/cli/main.d.ts.map +1 -1
  31. package/dist/cli/registry.d.ts +35 -0
  32. package/dist/cli/registry.d.ts.map +1 -1
  33. package/dist/codegen/fetch.d.ts +22 -0
  34. package/dist/codegen/fetch.d.ts.map +1 -1
  35. package/dist/codegen/lexicon-regen.d.ts +110 -0
  36. package/dist/codegen/lexicon-regen.d.ts.map +1 -0
  37. package/dist/codegen/pinned-upgrade.d.ts +153 -0
  38. package/dist/codegen/pinned-upgrade.d.ts.map +1 -0
  39. package/dist/codegen/rolling-upgrade.d.ts +138 -0
  40. package/dist/codegen/rolling-upgrade.d.ts.map +1 -0
  41. package/dist/codegen/surface-snapshot.d.ts +173 -0
  42. package/dist/codegen/surface-snapshot.d.ts.map +1 -0
  43. package/dist/codegen/version-bump.d.ts +21 -0
  44. package/dist/codegen/version-bump.d.ts.map +1 -0
  45. package/dist/components/auto-release.d.ts +93 -0
  46. package/dist/components/auto-release.d.ts.map +1 -0
  47. package/dist/components/builders.d.ts +37 -0
  48. package/dist/components/builders.d.ts.map +1 -0
  49. package/dist/components/capability-plugin-loader.d.ts +111 -0
  50. package/dist/components/capability-plugin-loader.d.ts.map +1 -0
  51. package/dist/components/capability-plugin-schema.d.ts +24 -0
  52. package/dist/components/capability-plugin-schema.d.ts.map +1 -0
  53. package/dist/components/capability-plugin.d.ts +85 -0
  54. package/dist/components/capability-plugin.d.ts.map +1 -0
  55. package/dist/components/capability.d.ts +89 -0
  56. package/dist/components/capability.d.ts.map +1 -0
  57. package/dist/components/cli-support.d.ts +204 -0
  58. package/dist/components/cli-support.d.ts.map +1 -0
  59. package/dist/components/component.d.ts +179 -0
  60. package/dist/components/component.d.ts.map +1 -0
  61. package/dist/components/config-defaults.d.ts +41 -0
  62. package/dist/components/config-defaults.d.ts.map +1 -0
  63. package/dist/components/discover.d.ts +60 -0
  64. package/dist/components/discover.d.ts.map +1 -0
  65. package/dist/components/driver-output.d.ts +20 -0
  66. package/dist/components/driver-output.d.ts.map +1 -0
  67. package/dist/components/driver.d.ts +209 -0
  68. package/dist/components/driver.d.ts.map +1 -0
  69. package/dist/components/index.d.ts +22 -0
  70. package/dist/components/index.d.ts.map +1 -0
  71. package/dist/components/manifest-persistence.d.ts +79 -0
  72. package/dist/components/manifest-persistence.d.ts.map +1 -0
  73. package/dist/components/pilots/alb-ecs.pilot.d.ts +27 -0
  74. package/dist/components/pilots/alb-ecs.pilot.d.ts.map +1 -0
  75. package/dist/components/pilots/dynamodb.pilot.d.ts +22 -0
  76. package/dist/components/pilots/dynamodb.pilot.d.ts.map +1 -0
  77. package/dist/components/pilots/jar-emr.pilot.d.ts +37 -0
  78. package/dist/components/pilots/jar-emr.pilot.d.ts.map +1 -0
  79. package/dist/components/pilots/lambda.pilot.d.ts +35 -0
  80. package/dist/components/pilots/lambda.pilot.d.ts.map +1 -0
  81. package/dist/components/pilots/neo4j-fanout.pilot.d.ts +17 -0
  82. package/dist/components/pilots/neo4j-fanout.pilot.d.ts.map +1 -0
  83. package/dist/components/pilots/project.d.ts +13 -0
  84. package/dist/components/pilots/project.d.ts.map +1 -0
  85. package/dist/components/presets/ecs-fargate.d.ts +59 -0
  86. package/dist/components/presets/ecs-fargate.d.ts.map +1 -0
  87. package/dist/components/presets/index.d.ts +29 -0
  88. package/dist/components/presets/index.d.ts.map +1 -0
  89. package/dist/components/presets/lambda.d.ts +35 -0
  90. package/dist/components/presets/lambda.d.ts.map +1 -0
  91. package/dist/components/presets/single-host-compose.d.ts +43 -0
  92. package/dist/components/presets/single-host-compose.d.ts.map +1 -0
  93. package/dist/components/registry.d.ts +29 -0
  94. package/dist/components/registry.d.ts.map +1 -0
  95. package/dist/components/starter-plugin.d.ts +51 -0
  96. package/dist/components/starter-plugin.d.ts.map +1 -0
  97. package/dist/components/temporal-codegen-loader.d.ts +27 -0
  98. package/dist/components/temporal-codegen-loader.d.ts.map +1 -0
  99. package/dist/components/verbs/__tests__/mock-cloud-executor.d.ts +35 -0
  100. package/dist/components/verbs/__tests__/mock-cloud-executor.d.ts.map +1 -0
  101. package/dist/components/verbs/__tests__/mock-process-runner.d.ts +45 -0
  102. package/dist/components/verbs/__tests__/mock-process-runner.d.ts.map +1 -0
  103. package/dist/components/verbs/__tests__/mock-sbom-generator.d.ts +33 -0
  104. package/dist/components/verbs/__tests__/mock-sbom-generator.d.ts.map +1 -0
  105. package/dist/components/verbs/bom-writer.d.ts +155 -0
  106. package/dist/components/verbs/bom-writer.d.ts.map +1 -0
  107. package/dist/components/verbs/build-archive.d.ts +205 -0
  108. package/dist/components/verbs/build-archive.d.ts.map +1 -0
  109. package/dist/components/verbs/build.d.ts +150 -0
  110. package/dist/components/verbs/build.d.ts.map +1 -0
  111. package/dist/components/verbs/cloud-executor.d.ts +88 -0
  112. package/dist/components/verbs/cloud-executor.d.ts.map +1 -0
  113. package/dist/components/verbs/component-bom.d.ts +103 -0
  114. package/dist/components/verbs/component-bom.d.ts.map +1 -0
  115. package/dist/components/verbs/index.d.ts +49 -0
  116. package/dist/components/verbs/index.d.ts.map +1 -0
  117. package/dist/components/verbs/license-policy.d.ts +56 -0
  118. package/dist/components/verbs/license-policy.d.ts.map +1 -0
  119. package/dist/components/verbs/lockfile-sbom-generator.d.ts +81 -0
  120. package/dist/components/verbs/lockfile-sbom-generator.d.ts.map +1 -0
  121. package/dist/components/verbs/process-runner.d.ts +64 -0
  122. package/dist/components/verbs/process-runner.d.ts.map +1 -0
  123. package/dist/components/verbs/reproducibility.d.ts +80 -0
  124. package/dist/components/verbs/reproducibility.d.ts.map +1 -0
  125. package/dist/components/verbs/sbom-generator.d.ts +157 -0
  126. package/dist/components/verbs/sbom-generator.d.ts.map +1 -0
  127. package/dist/components/verbs/sbom.d.ts +79 -0
  128. package/dist/components/verbs/sbom.d.ts.map +1 -0
  129. package/dist/components/verbs/shell.d.ts +35 -0
  130. package/dist/components/verbs/shell.d.ts.map +1 -0
  131. package/dist/components/verbs/sign.d.ts +222 -0
  132. package/dist/components/verbs/sign.d.ts.map +1 -0
  133. package/dist/components/verbs/stub.d.ts +18 -0
  134. package/dist/components/verbs/stub.d.ts.map +1 -0
  135. package/dist/components/verbs/tool-sbom-generator.d.ts +51 -0
  136. package/dist/components/verbs/tool-sbom-generator.d.ts.map +1 -0
  137. package/dist/components/verbs/verify.d.ts +106 -0
  138. package/dist/components/verbs/verify.d.ts.map +1 -0
  139. package/dist/components/verbs/vex.d.ts +65 -0
  140. package/dist/components/verbs/vex.d.ts.map +1 -0
  141. package/dist/components/verbs/vuln-gate.d.ts +91 -0
  142. package/dist/components/verbs/vuln-gate.d.ts.map +1 -0
  143. package/dist/components/verbs/vuln-scan.d.ts +116 -0
  144. package/dist/components/verbs/vuln-scan.d.ts.map +1 -0
  145. package/dist/components/verbs/wait-verify.d.ts +85 -0
  146. package/dist/components/verbs/wait-verify.d.ts.map +1 -0
  147. package/dist/config.d.ts +205 -0
  148. package/dist/config.d.ts.map +1 -1
  149. package/dist/index.d.ts +4 -0
  150. package/dist/index.d.ts.map +1 -1
  151. package/dist/lexicon.d.ts +78 -0
  152. package/dist/lexicon.d.ts.map +1 -1
  153. package/dist/lifecycle/build-ledger-store.d.ts +121 -0
  154. package/dist/lifecycle/build-ledger-store.d.ts.map +1 -0
  155. package/dist/lifecycle/build-ledger.d.ts +225 -0
  156. package/dist/lifecycle/build-ledger.d.ts.map +1 -0
  157. package/dist/lifecycle/git.d.ts +84 -0
  158. package/dist/lifecycle/git.d.ts.map +1 -1
  159. package/dist/lifecycle/index.d.ts +5 -0
  160. package/dist/lifecycle/index.d.ts.map +1 -1
  161. package/dist/lifecycle/oras-referrer-lookup.d.ts +41 -0
  162. package/dist/lifecycle/oras-referrer-lookup.d.ts.map +1 -0
  163. package/dist/lifecycle/release-ledger.d.ts +122 -0
  164. package/dist/lifecycle/release-ledger.d.ts.map +1 -0
  165. package/dist/lifecycle/status.d.ts +150 -0
  166. package/dist/lifecycle/status.d.ts.map +1 -0
  167. package/dist/lint/component-checks.d.ts +95 -0
  168. package/dist/lint/component-checks.d.ts.map +1 -0
  169. package/dist/lint/engine.d.ts +23 -0
  170. package/dist/lint/engine.d.ts.map +1 -1
  171. package/dist/lint/presets/strict.json +8 -1
  172. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.d.ts +4 -0
  173. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.d.ts.map +1 -0
  174. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.d.ts +4 -0
  175. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.d.ts.map +1 -0
  176. package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.d.ts +4 -0
  177. package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.d.ts.map +1 -0
  178. package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.d.ts +4 -0
  179. package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.d.ts.map +1 -0
  180. package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.d.ts +4 -0
  181. package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.d.ts.map +1 -0
  182. package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.d.ts +10 -0
  183. package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.d.ts.map +1 -0
  184. package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.d.ts +3 -0
  185. package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.d.ts.map +1 -0
  186. package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.d.ts +4 -0
  187. package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.d.ts.map +1 -0
  188. package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.d.ts +4 -0
  189. package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.d.ts.map +1 -0
  190. package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.d.ts +4 -0
  191. package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.d.ts.map +1 -0
  192. package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.d.ts +4 -0
  193. package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.d.ts.map +1 -0
  194. package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.d.ts +4 -0
  195. package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.d.ts.map +1 -0
  196. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts +4 -0
  197. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts.map +1 -0
  198. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts +4 -0
  199. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts.map +1 -0
  200. package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.d.ts +4 -0
  201. package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.d.ts.map +1 -0
  202. package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.d.ts +4 -0
  203. package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.d.ts.map +1 -0
  204. package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.d.ts +4 -0
  205. package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.d.ts.map +1 -0
  206. package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.d.ts +4 -0
  207. package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.d.ts.map +1 -0
  208. package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.d.ts +4 -0
  209. package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.d.ts.map +1 -0
  210. package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.d.ts +4 -0
  211. package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.d.ts.map +1 -0
  212. package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.d.ts +3 -0
  213. package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.d.ts.map +1 -0
  214. package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.d.ts +4 -0
  215. package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.d.ts.map +1 -0
  216. package/dist/lint/rules/comp/comp001-publishes-never-applies.d.ts +20 -0
  217. package/dist/lint/rules/comp/comp001-publishes-never-applies.d.ts.map +1 -0
  218. package/dist/lint/rules/comp/comp002-dangling-wiring-ref.d.ts +28 -0
  219. package/dist/lint/rules/comp/comp002-dangling-wiring-ref.d.ts.map +1 -0
  220. package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts +39 -0
  221. package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts.map +1 -0
  222. package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts +37 -0
  223. package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts.map +1 -0
  224. package/dist/lint/rules/comp/comp005-capability-kind-is-noun.d.ts +43 -0
  225. package/dist/lint/rules/comp/comp005-capability-kind-is-noun.d.ts.map +1 -0
  226. package/dist/lint/rules/comp/comp006-shell-needs-reason.d.ts +22 -0
  227. package/dist/lint/rules/comp/comp006-shell-needs-reason.d.ts.map +1 -0
  228. package/dist/lint/rules/comp/comp007-composition-sprawl.d.ts +33 -0
  229. package/dist/lint/rules/comp/comp007-composition-sprawl.d.ts.map +1 -0
  230. package/dist/lint/rules/comp/index.d.ts +18 -0
  231. package/dist/lint/rules/comp/index.d.ts.map +1 -0
  232. package/dist/lint/rules/comp/support.d.ts +71 -0
  233. package/dist/lint/rules/comp/support.d.ts.map +1 -0
  234. package/dist/lsp/lexicon-providers.d.ts.map +1 -1
  235. package/dist/op/activity-registry.d.ts +11 -6
  236. package/dist/op/activity-registry.d.ts.map +1 -1
  237. package/dist/op/activity-runtime.d.ts +24 -0
  238. package/dist/op/activity-runtime.d.ts.map +1 -0
  239. package/dist/op/builders.d.ts +56 -0
  240. package/dist/op/builders.d.ts.map +1 -1
  241. package/dist/op/index.d.ts +2 -1
  242. package/dist/op/index.d.ts.map +1 -1
  243. package/dist/ownership.d.ts +20 -14
  244. package/dist/ownership.d.ts.map +1 -1
  245. package/package.json +14 -1
  246. package/src/audit/catalog.test.ts +74 -22
  247. package/src/audit/catalog.ts +74 -471
  248. package/src/audit/proof.ts +4 -2
  249. package/src/audit/report-html.test.ts +14 -7
  250. package/src/audit/report-model.ts +20 -9
  251. package/src/audit/report.test.ts +36 -13
  252. package/src/audit/report.ts +2 -0
  253. package/src/audit/rules-doc.test.ts +8 -6
  254. package/src/audit/rules-doc.ts +13 -5
  255. package/src/cli/commands/audit.ts +23 -18
  256. package/src/cli/commands/component-lint.test.ts +158 -0
  257. package/src/cli/commands/doctor.test.ts +116 -2
  258. package/src/cli/commands/doctor.ts +46 -0
  259. package/src/cli/commands/lexicon-rolling-upgrade.ts +198 -0
  260. package/src/cli/commands/lexicon-surface-diff.test.ts +104 -0
  261. package/src/cli/commands/lexicon-surface-diff.ts +185 -0
  262. package/src/cli/commands/lint.ts +142 -1
  263. package/src/cli/commands/pinned-upgrade.ts +204 -0
  264. package/src/cli/handlers/build.ts +58 -1
  265. package/src/cli/handlers/components.test.ts +504 -0
  266. package/src/cli/handlers/components.ts +404 -0
  267. package/src/cli/handlers/dev.ts +60 -1
  268. package/src/cli/handlers/graph.ts +47 -2
  269. package/src/cli/handlers/misc.ts +45 -1
  270. package/src/cli/handlers/run.test.ts +967 -3
  271. package/src/cli/handlers/run.ts +618 -11
  272. package/src/cli/main.test.ts +66 -0
  273. package/src/cli/main.ts +105 -2
  274. package/src/cli/registry.ts +35 -0
  275. package/src/codegen/fetch.test.ts +84 -3
  276. package/src/codegen/fetch.ts +76 -2
  277. package/src/codegen/lexicon-regen.test.ts +298 -0
  278. package/src/codegen/lexicon-regen.ts +545 -0
  279. package/src/codegen/pinned-upgrade.test.ts +399 -0
  280. package/src/codegen/pinned-upgrade.ts +423 -0
  281. package/src/codegen/rolling-upgrade.test.ts +333 -0
  282. package/src/codegen/rolling-upgrade.ts +320 -0
  283. package/src/codegen/surface-snapshot.test.ts +461 -0
  284. package/src/codegen/surface-snapshot.ts +546 -0
  285. package/src/codegen/version-bump.test.ts +47 -0
  286. package/src/codegen/version-bump.ts +39 -0
  287. package/src/components/README.md +130 -0
  288. package/src/components/SPRAWL-VALIDATION.md +181 -0
  289. package/src/components/__fixtures__/alb-ecs-service.json +51 -0
  290. package/src/components/__fixtures__/dynamodb-infra.json +32 -0
  291. package/src/components/__fixtures__/emr-job-consumer.json +26 -0
  292. package/src/components/__fixtures__/jar-lib-producer.json +16 -0
  293. package/src/components/__fixtures__/lambda-image-processor.json +28 -0
  294. package/src/components/__fixtures__/neo4j-fanout.json +34 -0
  295. package/src/components/__fixtures__/single-host-compose.json +29 -0
  296. package/src/components/auto-release.test.ts +217 -0
  297. package/src/components/auto-release.ts +216 -0
  298. package/src/components/builders.test.ts +45 -0
  299. package/src/components/builders.ts +71 -0
  300. package/src/components/capability-plugin-loader.ts +218 -0
  301. package/src/components/capability-plugin-schema.ts +56 -0
  302. package/src/components/capability-plugin.test.ts +235 -0
  303. package/src/components/capability-plugin.ts +108 -0
  304. package/src/components/capability.ts +117 -0
  305. package/src/components/cli-support.test.ts +579 -0
  306. package/src/components/cli-support.ts +481 -0
  307. package/src/components/component-schema.test.ts +265 -0
  308. package/src/components/component.schema.json +235 -0
  309. package/src/components/component.test.ts +251 -0
  310. package/src/components/component.ts +255 -0
  311. package/src/components/config-defaults.test.ts +263 -0
  312. package/src/components/config-defaults.ts +145 -0
  313. package/src/components/discover.test.ts +352 -0
  314. package/src/components/discover.ts +167 -0
  315. package/src/components/driver-output.ts +71 -0
  316. package/src/components/driver.test.ts +638 -0
  317. package/src/components/driver.ts +690 -0
  318. package/src/components/index.ts +113 -0
  319. package/src/components/manifest-persistence.test.ts +152 -0
  320. package/src/components/manifest-persistence.ts +164 -0
  321. package/src/components/pilots/README.md +33 -0
  322. package/src/components/pilots/alb-ecs.pilot.ts +63 -0
  323. package/src/components/pilots/dynamodb.pilot.ts +59 -0
  324. package/src/components/pilots/jar-emr.pilot.ts +69 -0
  325. package/src/components/pilots/lambda.pilot.ts +55 -0
  326. package/src/components/pilots/neo4j-fanout.pilot.ts +92 -0
  327. package/src/components/pilots/pilots-lint-clean.test.ts +78 -0
  328. package/src/components/pilots/pilots.test.ts +126 -0
  329. package/src/components/pilots/project.ts +13 -0
  330. package/src/components/presets/comp007-reduction.test.ts +122 -0
  331. package/src/components/presets/ecs-fargate.test.ts +84 -0
  332. package/src/components/presets/ecs-fargate.ts +103 -0
  333. package/src/components/presets/index.ts +32 -0
  334. package/src/components/presets/lambda.test.ts +35 -0
  335. package/src/components/presets/lambda.ts +53 -0
  336. package/src/components/presets/single-host-compose.test.ts +65 -0
  337. package/src/components/presets/single-host-compose.ts +64 -0
  338. package/src/components/registry.test.ts +112 -0
  339. package/src/components/registry.ts +37 -0
  340. package/src/components/starter-plugin.ts +105 -0
  341. package/src/components/temporal-codegen-loader.ts +41 -0
  342. package/src/components/verbs/__fixtures__/package-lock.json +45 -0
  343. package/src/components/verbs/__fixtures__/pom.xml +37 -0
  344. package/src/components/verbs/__fixtures__/schemas/cyclonedx-1.5.schema.json +3800 -0
  345. package/src/components/verbs/__fixtures__/schemas/cyclonedx-spdx-license.schema.json +621 -0
  346. package/src/components/verbs/__fixtures__/schemas/jsf-0.82.schema.json +240 -0
  347. package/src/components/verbs/__fixtures__/schemas/spdx-2.3.schema.json +740 -0
  348. package/src/components/verbs/__tests__/mock-cloud-executor.ts +102 -0
  349. package/src/components/verbs/__tests__/mock-process-runner.ts +79 -0
  350. package/src/components/verbs/__tests__/mock-sbom-generator.ts +85 -0
  351. package/src/components/verbs/bom-writer.test.ts +331 -0
  352. package/src/components/verbs/bom-writer.ts +386 -0
  353. package/src/components/verbs/build-archive.test.ts +251 -0
  354. package/src/components/verbs/build-archive.ts +296 -0
  355. package/src/components/verbs/build.test.ts +222 -0
  356. package/src/components/verbs/build.ts +252 -0
  357. package/src/components/verbs/cloud-executor.ts +181 -0
  358. package/src/components/verbs/component-bom.test.ts +219 -0
  359. package/src/components/verbs/component-bom.ts +189 -0
  360. package/src/components/verbs/index.ts +49 -0
  361. package/src/components/verbs/license-policy.ts +115 -0
  362. package/src/components/verbs/lockfile-sbom-generator.test.ts +195 -0
  363. package/src/components/verbs/lockfile-sbom-generator.ts +236 -0
  364. package/src/components/verbs/process-runner.test.ts +79 -0
  365. package/src/components/verbs/process-runner.ts +113 -0
  366. package/src/components/verbs/reproducibility.test.ts +24 -0
  367. package/src/components/verbs/reproducibility.ts +100 -0
  368. package/src/components/verbs/sbom-generator.test.ts +96 -0
  369. package/src/components/verbs/sbom-generator.ts +209 -0
  370. package/src/components/verbs/sbom.test.ts +184 -0
  371. package/src/components/verbs/sbom.ts +152 -0
  372. package/src/components/verbs/shell.test.ts +36 -0
  373. package/src/components/verbs/shell.ts +51 -0
  374. package/src/components/verbs/sign.test.ts +210 -0
  375. package/src/components/verbs/sign.ts +350 -0
  376. package/src/components/verbs/stub.ts +34 -0
  377. package/src/components/verbs/tool-sbom-generator.test.ts +194 -0
  378. package/src/components/verbs/tool-sbom-generator.ts +192 -0
  379. package/src/components/verbs/verify.test.ts +159 -0
  380. package/src/components/verbs/verify.ts +179 -0
  381. package/src/components/verbs/vex.ts +182 -0
  382. package/src/components/verbs/vuln-gate.test.ts +201 -0
  383. package/src/components/verbs/vuln-gate.ts +170 -0
  384. package/src/components/verbs/vuln-scan.test.ts +145 -0
  385. package/src/components/verbs/vuln-scan.ts +266 -0
  386. package/src/components/verbs/wait-verify.test.ts +111 -0
  387. package/src/components/verbs/wait-verify.ts +171 -0
  388. package/src/config.test.ts +74 -1
  389. package/src/config.ts +219 -0
  390. package/src/index.ts +32 -0
  391. package/src/lexicon.ts +88 -0
  392. package/src/lifecycle/build-ledger-store.test.ts +217 -0
  393. package/src/lifecycle/build-ledger-store.ts +165 -0
  394. package/src/lifecycle/build-ledger.test.ts +349 -0
  395. package/src/lifecycle/build-ledger.ts +305 -0
  396. package/src/lifecycle/git.test.ts +118 -0
  397. package/src/lifecycle/git.ts +149 -14
  398. package/src/lifecycle/index.ts +5 -0
  399. package/src/lifecycle/oras-referrer-lookup.test.ts +116 -0
  400. package/src/lifecycle/oras-referrer-lookup.ts +110 -0
  401. package/src/lifecycle/release-ledger.test.ts +209 -0
  402. package/src/lifecycle/release-ledger.ts +185 -0
  403. package/src/lifecycle/status.test.ts +330 -0
  404. package/src/lifecycle/status.ts +278 -0
  405. package/src/lint/component-checks.ts +148 -0
  406. package/src/lint/config.test.ts +21 -0
  407. package/src/lint/engine.ts +11 -2
  408. package/src/lint/presets/relaxed.json +8 -1
  409. package/src/lint/presets/strict.json +8 -1
  410. package/src/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.ts +9 -0
  411. package/src/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.ts +9 -0
  412. package/src/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.ts +11 -0
  413. package/src/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.ts +13 -0
  414. package/src/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.ts +11 -0
  415. package/src/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.ts +27 -0
  416. package/src/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.ts +10 -0
  417. package/src/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.ts +23 -0
  418. package/src/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.ts +10 -0
  419. package/src/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.ts +19 -0
  420. package/src/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.ts +10 -0
  421. package/src/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.ts +20 -0
  422. package/src/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.ts +23 -0
  423. package/src/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.ts +10 -0
  424. package/src/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.ts +14 -0
  425. package/src/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.ts +18 -0
  426. package/src/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.ts +10 -0
  427. package/src/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.ts +14 -0
  428. package/src/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.ts +13 -0
  429. package/src/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.ts +13 -0
  430. package/src/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.ts +12 -0
  431. package/src/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.ts +18 -0
  432. package/src/lint/rules/comp/comp.test.ts +378 -0
  433. package/src/lint/rules/comp/comp001-publishes-never-applies.ts +78 -0
  434. package/src/lint/rules/comp/comp002-dangling-wiring-ref.ts +94 -0
  435. package/src/lint/rules/comp/comp003-mutating-no-rollback.ts +115 -0
  436. package/src/lint/rules/comp/comp004-gate-needs-temporal.ts +66 -0
  437. package/src/lint/rules/comp/comp005-capability-kind-is-noun.ts +113 -0
  438. package/src/lint/rules/comp/comp006-shell-needs-reason.ts +55 -0
  439. package/src/lint/rules/comp/comp007-composition-sprawl.ts +71 -0
  440. package/src/lint/rules/comp/index.ts +37 -0
  441. package/src/lint/rules/comp/support.ts +173 -0
  442. package/src/lsp/lexicon-providers.test.ts +55 -0
  443. package/src/lsp/lexicon-providers.ts +13 -3
  444. package/src/op/activity-registry.test.ts +38 -0
  445. package/src/op/activity-registry.ts +31 -12
  446. package/src/op/activity-runtime.ts +73 -0
  447. package/src/op/builders.ts +92 -0
  448. package/src/op/index.ts +3 -1
  449. package/src/ownership.test.ts +24 -26
  450. package/src/ownership.ts +26 -38
@@ -1,8 +1,8 @@
1
- import { resolve, join } from "node:path";
2
- import { existsSync } from "node:fs";
1
+ import { resolve, join, dirname } from "node:path";
2
+ import { existsSync, writeFileSync, mkdirSync, readFileSync } from "node:fs";
3
3
  import { createConnection } from "node:net";
4
4
  import { spawn as spawnChild, type ChildProcess } from "node:child_process";
5
- import { loadChantConfig } from "../../config";
5
+ import { loadChantConfig, resolveAutoReleaseDisabled } from "../../config";
6
6
  import { discoverOps } from "../../op/discover";
7
7
  import { loadActivities, loadProfiles } from "../../op/activity-registry";
8
8
  import { runOpLocally, findGate, LocalGateUnsupportedError, OpRunFailure } from "../../op/local-executor";
@@ -19,6 +19,13 @@ import {
19
19
  type WorkflowHistoryRaw,
20
20
  } from "./run-client";
21
21
  import { generateReport, writeReport } from "./run-report";
22
+ import { runComponents, resolveComponentTargets, findComponentGate, listComponents } from "../../components/cli-support";
23
+ import { renderDriverHuman, renderDriverJson } from "../../components/driver-output";
24
+ import { loadComponentTemporalCodegen } from "../../components/temporal-codegen-loader";
25
+ import { applyConfigDefaults } from "../../components/config-defaults";
26
+ import { maybeRecordAutoRelease, extractRunDigestFromPhaseOutputs } from "../../components/auto-release";
27
+ import { maybePersistBuildManifest, extractRunManifestFromPhaseOutputs } from "../../components/manifest-persistence";
28
+ import type { DriverComponentResult } from "../../components/driver";
22
29
 
23
30
  function kebabToCamel(s: string): string {
24
31
  return s.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());
@@ -55,6 +62,8 @@ export async function makeTemporalClient(profileName: string | undefined, projec
55
62
  // ── chant run list ──────────────────────────────────���─────────────────────────
56
63
 
57
64
  export async function runOpList(ctx: CommandContext): Promise<number> {
65
+ if (ctx.args.components) return runComponentsList(ctx);
66
+
58
67
  if (!requireTemporalMode(ctx, "chant run list")) return 1;
59
68
  const { ops, errors } = await discoverOps();
60
69
 
@@ -118,16 +127,99 @@ export async function runOpList(ctx: CommandContext): Promise<number> {
118
127
  return 0;
119
128
  }
120
129
 
130
+ /**
131
+ * `chant run list --components` (#599) — the component counterpart of
132
+ * `runOpList` above, mirrored shape-for-shape: discover, print a header,
133
+ * best-effort annotate with Temporal run status, print one row per entry.
134
+ * Kept behind the same `requireTemporalMode` gate as the Op path — the whole
135
+ * point of this subcommand is the run-status annotation, and components have
136
+ * no local notion of a "run" to list either (mirrors the "Temporal-only
137
+ * subcommand guards" test coverage for the Op list/status/log/signal/cancel
138
+ * set).
139
+ *
140
+ * Discovery + column shape reuses `listComponents` (../../components/cli-
141
+ * support.ts), the same helper `chant list --components` already uses, so
142
+ * archetype inference/field projection isn't duplicated here — this function
143
+ * only adds the Temporal status column. Status lookups use
144
+ * `componentWorkflowId`, the id space `runOpSignal`/`runOpCancel` established
145
+ * for components (#589) — kept distinct from `resolveWorkflowId`'s Op id
146
+ * space so an Op and a component can share a name.
147
+ */
148
+ async function runComponentsList(ctx: CommandContext): Promise<number> {
149
+ if (!requireTemporalMode(ctx, "chant run list --components")) return 1;
150
+
151
+ const projectPath = resolve(".");
152
+ const result = await listComponents(projectPath);
153
+
154
+ if (!result.success) {
155
+ for (const err of result.errors) console.error(formatError({ message: err }));
156
+ return 1;
157
+ }
158
+
159
+ if (result.components.length === 0) {
160
+ console.error(formatWarning({ message: "No component definitions found (*.component.ts)" }));
161
+ return 0;
162
+ }
163
+
164
+ console.log(
165
+ "NAME".padEnd(22) +
166
+ "ARCHETYPE".padEnd(18) +
167
+ "PHASES".padEnd(8) +
168
+ "DEPENDS".padEnd(20) +
169
+ "FILE",
170
+ );
171
+
172
+ let runStatus: Map<string, string> | undefined;
173
+ try {
174
+ const { config } = await loadChantConfig(projectPath);
175
+ const profile = resolveProfile(config as Record<string, unknown>, ctx.args.profile);
176
+ const { Connection, Client } = await loadTemporalClient();
177
+ const connection = await Connection.connect(connectionOptions(profile));
178
+ const client = new Client({ connection, namespace: profile.namespace });
179
+ runStatus = new Map();
180
+ for (const { name } of result.components) {
181
+ try {
182
+ const desc = await client.workflow.getHandle(componentWorkflowId(name)).describe();
183
+ runStatus.set(name, desc.status.name);
184
+ } catch {
185
+ runStatus.set(name, "—");
186
+ }
187
+ }
188
+ } catch {
189
+ // Temporal not available — degrade gracefully
190
+ }
191
+
192
+ for (const c of result.components) {
193
+ const phases = String(c.phases.length);
194
+ const deps = c.dependsOn.join(",") || "—";
195
+ const status = runStatus?.get(c.name);
196
+ const statusStr = status ? ` [${status}]` : "";
197
+
198
+ console.log(
199
+ (c.name + statusStr).padEnd(22) +
200
+ c.archetype.padEnd(18) +
201
+ phases.padEnd(8) +
202
+ deps.padEnd(20) +
203
+ c.filePath,
204
+ );
205
+ }
206
+
207
+ return 0;
208
+ }
209
+
121
210
  // ── chant run status <name> ───────────────────────────────────────────────────
122
211
 
123
212
  export async function runOpStatus(ctx: CommandContext): Promise<number> {
124
213
  if (!requireTemporalMode(ctx, "chant run status")) return 1;
125
214
  const name = ctx.args.extraPositional;
126
215
  if (!name) {
127
- console.error(formatError({ message: "Op name is required: chant run status <name>" }));
216
+ const label = ctx.args.components ? "Component" : "Op";
217
+ console.error(formatError({ message: `${label} name is required: chant run status <name>` }));
128
218
  return 1;
129
219
  }
130
220
 
221
+ if (ctx.args.components) return runComponentStatus(ctx, name);
222
+
131
223
  const projectPath = resolve(".");
132
224
  let client, desc: WorkflowExecutionDescription, history: WorkflowHistoryRaw;
133
225
  try {
@@ -158,16 +250,57 @@ export async function runOpStatus(ctx: CommandContext): Promise<number> {
158
250
  return 0;
159
251
  }
160
252
 
253
+ /**
254
+ * `chant run status <name> --components` (#599) — the component counterpart
255
+ * of `runOpStatus` above. Identical describe+history rendering; the only
256
+ * difference is the workflow id (`componentWorkflowId`, not
257
+ * `resolveWorkflowId`) and the "Component:" label, mirroring how
258
+ * `runOpSignal`/`runOpCancel` already distinguish the two id spaces (#589).
259
+ */
260
+ async function runComponentStatus(ctx: CommandContext, name: string): Promise<number> {
261
+ const projectPath = resolve(".");
262
+ let client, desc: WorkflowExecutionDescription, history: WorkflowHistoryRaw;
263
+ try {
264
+ ({ client } = await makeTemporalClient(ctx.args.profile, projectPath));
265
+ const handle = client.workflow.getHandle(componentWorkflowId(name));
266
+ desc = await handle.describe();
267
+ history = await handle.fetchHistory();
268
+ } catch (err) {
269
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
270
+ return 1;
271
+ }
272
+
273
+ console.log(formatBold(`Component: ${name}`));
274
+ console.log(` Workflow ID : ${desc.workflowId}`);
275
+ console.log(` Run ID : ${desc.runId}`);
276
+ console.log(` Status : ${desc.status.name}`);
277
+ console.log(` Task Queue : ${desc.taskQueue}`);
278
+ console.log(` Started : ${desc.startTime.toISOString()}`);
279
+ if (desc.closeTime) console.log(` Closed : ${desc.closeTime.toISOString()}`);
280
+
281
+ const events = history.events ?? [];
282
+ const completed = events.filter((e) => e.eventType === "ActivityTaskCompleted").length;
283
+ const scheduled = events.filter((e) => e.eventType === "ActivityTaskScheduled").length;
284
+ if (scheduled > 0) {
285
+ console.log(` Activities : ${completed}/${scheduled} completed`);
286
+ }
287
+
288
+ return 0;
289
+ }
290
+
161
291
  // ── chant run log <name> ──────────────────────────────────────────────────────
162
292
 
163
293
  export async function runOpLog(ctx: CommandContext): Promise<number> {
164
294
  if (!requireTemporalMode(ctx, "chant run log")) return 1;
165
295
  const name = ctx.args.extraPositional;
166
296
  if (!name) {
167
- console.error(formatError({ message: "Op name is required: chant run log <name>" }));
297
+ const label = ctx.args.components ? "Component" : "Op";
298
+ console.error(formatError({ message: `${label} name is required: chant run log <name>` }));
168
299
  return 1;
169
300
  }
170
301
 
302
+ if (ctx.args.components) return runComponentLog(ctx, name);
303
+
171
304
  const projectPath = resolve(".");
172
305
  let client;
173
306
  try {
@@ -204,35 +337,101 @@ export async function runOpLog(ctx: CommandContext): Promise<number> {
204
337
  return 0;
205
338
  }
206
339
 
340
+ /**
341
+ * `chant run log <name> --components` (#599) — the component counterpart of
342
+ * `runOpLog` above. Same table shape; the `WorkflowType` query needs the
343
+ * component's generated workflow function name rather than
344
+ * `workflowFnName`'s Op convention, so this loads the Temporal component
345
+ * codegen module (`../../components/temporal-codegen-loader.ts`, the same
346
+ * loader `runComponentTemporal` already uses) purely for its
347
+ * `componentWorkflowFnName` helper — no compilation happens here, `log` only
348
+ * reads past run history.
349
+ */
350
+ async function runComponentLog(ctx: CommandContext, name: string): Promise<number> {
351
+ const projectPath = resolve(".");
352
+ let client;
353
+ try {
354
+ ({ client } = await makeTemporalClient(ctx.args.profile, projectPath));
355
+ } catch (err) {
356
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
357
+ return 1;
358
+ }
359
+
360
+ let fnName: string;
361
+ try {
362
+ const codegen = await loadComponentTemporalCodegen();
363
+ fnName = codegen.componentWorkflowFnName(name);
364
+ } catch (err) {
365
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
366
+ return 1;
367
+ }
368
+
369
+ console.log(
370
+ "RUN-ID".padEnd(36) +
371
+ "STATUS".padEnd(16) +
372
+ "STARTED".padEnd(26) +
373
+ "CLOSED",
374
+ );
375
+
376
+ try {
377
+ for await (const run of client.workflow.list({ query: `WorkflowType = "${fnName}"` })) {
378
+ const start = run.startTime.toISOString().slice(0, 19).replace("T", " ");
379
+ const close = run.closeTime ? run.closeTime.toISOString().slice(0, 19).replace("T", " ") : "—";
380
+ console.log(
381
+ run.runId.padEnd(36) +
382
+ run.status.name.padEnd(16) +
383
+ start.padEnd(26) +
384
+ close,
385
+ );
386
+ }
387
+ } catch (err) {
388
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
389
+ return 1;
390
+ }
391
+
392
+ return 0;
393
+ }
394
+
207
395
  // ── chant run signal <name> <signal> ─────────────────────────────────────────
208
396
 
397
+ /**
398
+ * `chant run signal <name> <signal> [--components]` — sends a signal to a
399
+ * running Op workflow by default, or a component workflow when `--components`
400
+ * is passed (#589): the durable path's gate is otherwise unclearable from the
401
+ * CLI. Resolves the workflow id via `componentWorkflowId` (`chant-component-
402
+ * <name>`) instead of `resolveWorkflowId` (`chant-op-<name>`) in that case —
403
+ * the two id spaces are kept distinct so an Op and a component can share a
404
+ * name without colliding.
405
+ */
209
406
  export async function runOpSignal(ctx: CommandContext): Promise<number> {
210
407
  if (!requireTemporalMode(ctx, "chant run signal")) return 1;
211
408
  const name = ctx.args.extraPositional;
212
409
  const signalName = ctx.args.extraPositional2;
213
410
 
214
411
  if (!name || !signalName) {
215
- console.error(formatError({ message: "Usage: chant run signal <op-name> <signal-name>" }));
412
+ console.error(formatError({ message: "Usage: chant run signal <name> <signal-name>" }));
216
413
  return 1;
217
414
  }
218
415
 
219
416
  const projectPath = resolve(".");
417
+ const workflowId = ctx.args.components ? componentWorkflowId(name) : resolveWorkflowId(name);
220
418
  let handle: WorkflowHandleRaw;
221
419
  try {
222
420
  const { client } = await makeTemporalClient(ctx.args.profile, projectPath);
223
- handle = client.workflow.getHandle(resolveWorkflowId(name));
421
+ handle = client.workflow.getHandle(workflowId);
224
422
  await handle.signal(signalName);
225
423
  } catch (err) {
226
424
  console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
227
425
  return 1;
228
426
  }
229
427
 
230
- console.error(formatSuccess(`Signal "${signalName}" sent to Op "${name}"`));
428
+ console.error(formatSuccess(`Signal "${signalName}" sent to ${ctx.args.components ? "component" : "Op"} "${name}"`));
231
429
  return 0;
232
430
  }
233
431
 
234
432
  // ── chant run cancel <name> ───────────────────────────────────────────────────
235
433
 
434
+ /** `chant run cancel <name> [--components]` — cancels an Op workflow by default, or a component workflow when `--components` is passed (#589), mirroring `runOpSignal`'s id resolution. */
236
435
  export async function runOpCancel(ctx: CommandContext): Promise<number> {
237
436
  if (!requireTemporalMode(ctx, "chant run cancel")) return 1;
238
437
  const name = ctx.args.extraPositional;
@@ -250,17 +449,18 @@ export async function runOpCancel(ctx: CommandContext): Promise<number> {
250
449
  }
251
450
 
252
451
  const projectPath = resolve(".");
452
+ const workflowId = ctx.args.components ? componentWorkflowId(name) : resolveWorkflowId(name);
253
453
  let handle: WorkflowHandleRaw;
254
454
  try {
255
455
  const { client } = await makeTemporalClient(ctx.args.profile, projectPath);
256
- handle = client.workflow.getHandle(resolveWorkflowId(name));
456
+ handle = client.workflow.getHandle(workflowId);
257
457
  await handle.cancel();
258
458
  } catch (err) {
259
459
  console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
260
460
  return 1;
261
461
  }
262
462
 
263
- console.error(formatSuccess(`Cancellation requested for Op "${name}"`));
463
+ console.error(formatSuccess(`Cancellation requested for ${ctx.args.components ? "component" : "Op"} "${name}"`));
264
464
  return 0;
265
465
  }
266
466
 
@@ -303,8 +503,15 @@ function renderProgress(opName: string, history: WorkflowHistoryRaw): void {
303
503
  * Local mode is the default — it runs the Op in-process with no Temporal
304
504
  * server. `--temporal` opts into a cluster (gates, schedules, durable resume).
305
505
  * `--report` reads a past durable run and is therefore Temporal-only.
506
+ *
507
+ * `chant run --components <name|all>` (#585) is a separate target: discovered
508
+ * `Component` declarations dispatched through the interpret driver
509
+ * (`../../components/driver.ts`) rather than a `*.op.ts` Op. Checked first,
510
+ * mirroring `runGraph`'s `if (ctx.args.components) return
511
+ * runComponentGraph(ctx)` branch (../handlers/graph.ts).
306
512
  */
307
513
  export async function runOp(ctx: CommandContext): Promise<number> {
514
+ if (ctx.args.components) return runOpComponents(ctx);
308
515
  if (ctx.args.local && ctx.args.temporal) {
309
516
  console.error(formatError({
310
517
  message: "--local and --temporal are mutually exclusive",
@@ -319,6 +526,396 @@ export async function runOp(ctx: CommandContext): Promise<number> {
319
526
  return ctx.args.temporal ? runOpTemporal(ctx) : runOpLocal(ctx);
320
527
  }
321
528
 
529
+ // ── Auto-release recording post-run (#597) ──────────────────────────────────
530
+
531
+ /**
532
+ * After a successful `chant run --components` (local executor), auto-emit
533
+ * one release record per successfully deployed component that published a
534
+ * digest-bearing artifact — reusing `maybeRecordAutoRelease`
535
+ * (../../components/auto-release.ts), which itself reuses
536
+ * `../../lifecycle/release-ledger.ts`'s `appendReleaseRecord` verbatim. Never
537
+ * called on a failed run: both call sites below only reach this after
538
+ * confirming `result.success`/`componentResult.ok`, so a failed deploy writes
539
+ * nothing, by construction.
540
+ *
541
+ * Also persists the component's accumulated `BuildArchiveManifest`, when its
542
+ * composition produced one, to the durable build-manifest store (#609,
543
+ * ../../components/manifest-persistence.ts, ../../lifecycle/build-ledger-
544
+ * store.ts) — the missing piece that lets `chant components status`'s
545
+ * `componentBom`/`build.reproducibility` resolve to a real manifest instead
546
+ * of always reporting `null`. Same `disabled` opt-out flag as the release
547
+ * record: both are "durably record this successful deploy" side effects, so
548
+ * `--no-release-record`/`release.autoRecord: false` gates persistence too
549
+ * rather than needing a second, easy-to-forget knob (see
550
+ * `ManifestPersistOptions.disabled`'s doc).
551
+ *
552
+ * Best-effort and silent on the happy path: a skip (opted out, no digest/
553
+ * manifest, no actor) is unremarkable and not printed; only an actual write
554
+ * failure (`reason: "error"`) is surfaced, as a warning — never a nonzero
555
+ * exit, since the deploy itself already succeeded and a ledger-write hiccup
556
+ * must not retroactively fail it.
557
+ */
558
+ async function recordAutoReleasesForRun(
559
+ results: DriverComponentResult[],
560
+ env: string,
561
+ runId: string,
562
+ disabled: boolean,
563
+ ): Promise<void> {
564
+ for (const componentResult of results) {
565
+ if (!componentResult.ok) continue;
566
+ const outcome = await maybeRecordAutoRelease(
567
+ {
568
+ component: componentResult.component,
569
+ env,
570
+ success: true,
571
+ records: componentResult.records,
572
+ runId,
573
+ },
574
+ { disabled },
575
+ );
576
+ if (!outcome.recorded && outcome.reason === "error") {
577
+ console.error(formatWarning({
578
+ message: `release record for "${componentResult.component}"@${env} was not recorded: ${outcome.error}`,
579
+ }));
580
+ } else if (outcome.recorded) {
581
+ console.error(formatInfo(
582
+ `Recorded release: ${formatBold(componentResult.component)}@${env} -> ${outcome.record.digest} (commit ${outcome.commit.slice(0, 7)})`,
583
+ ));
584
+ }
585
+
586
+ const manifestOutcome = await maybePersistBuildManifest(
587
+ { success: true, records: componentResult.records },
588
+ { disabled },
589
+ );
590
+ if (!manifestOutcome.persisted && manifestOutcome.reason === "error") {
591
+ console.error(formatWarning({
592
+ message: `build manifest for "${componentResult.component}"@${env} was not persisted: ${manifestOutcome.error}`,
593
+ }));
594
+ } else if (manifestOutcome.persisted) {
595
+ console.error(formatInfo(
596
+ `Persisted build manifest: ${formatBold(componentResult.component)} -> ${manifestOutcome.manifestDigest} (commit ${manifestOutcome.commit.slice(0, 7)})`,
597
+ ));
598
+ }
599
+ }
600
+ }
601
+
602
+ // ── chant run --components <name|all> ────────────────────────────────────────
603
+
604
+ /**
605
+ * `chant run --components <name|all> [--env <env>] [--temporal]` (#585, and
606
+ * #589 for `--temporal`) — the interpret driver's CLI entrypoint. `args.path`
607
+ * is the component name (or `all`), matching `chant run <name>`'s Op-dispatch
608
+ * convention exactly (`args.path` is the Op name there too) rather than a
609
+ * project directory — components are always discovered from the current
610
+ * working directory, the same way Op discovery (`discoverOps()`) never takes
611
+ * a project-path argument either.
612
+ *
613
+ * Local mode (the default) resolves the selector through `runComponents`
614
+ * (`../../components/cli-support.ts`) and runs it on the local in-process
615
+ * executor; gated components are rejected before any step runs (matching
616
+ * `runOpLocal`'s pre-flight `findGate` guard) with an actionable message
617
+ * pointing at `--temporal`.
618
+ *
619
+ * `--temporal` (#589) takes the durable path instead: compiles the named
620
+ * component's composition to a Temporal workflow/worker (mirroring
621
+ * `Temporal::Op` codegen — see `runComponentTemporal` below), and gates are
622
+ * now ACCEPTED — a gate is durable wait-for-signal there, not a local
623
+ * in-process block. Scoped to a single named component (`all --temporal` is
624
+ * out of scope for #589: coordinating N durable workflows' cross-component
625
+ * `dependsOn` durably is a follow-up, not part of "compile a component's
626
+ * `deploy` composition into a durable orchestrator").
627
+ *
628
+ * On a successful run, auto-emits one release-ledger record per component
629
+ * that published a digest (#597, `recordAutoReleasesForRun` above) — a
630
+ * *post-run* CLI step, not a change to the driver itself (`../../components/
631
+ * driver.ts` stays capability-agnostic and knows nothing about the ledger).
632
+ * Opt out with `--no-release-record` or `chant.config.ts`'s
633
+ * `release.autoRecord: false`; the default is ON. A failed run never reaches
634
+ * this step, so it writes nothing.
635
+ */
636
+ export async function runOpComponents(ctx: CommandContext): Promise<number> {
637
+ const selector = ctx.args.path;
638
+ if (!selector || selector === ".") {
639
+ console.error(formatError({
640
+ message: "Component name is required: chant run --components <name|all>",
641
+ hint: "Run `chant list --components` to see available components.",
642
+ }));
643
+ return 1;
644
+ }
645
+
646
+ if (ctx.args.temporal) return runComponentTemporal(ctx, selector);
647
+
648
+ const env = ctx.args.env ?? "local";
649
+ // Seed cross-component/cross-stack outputs from upstream jobs' dumped files
650
+ // (`--seed-outputs`), so a single-component run resolves references to a
651
+ // component that ran in an earlier CI job.
652
+ const seededOutputs: Record<string, Record<string, unknown>> = {};
653
+ for (const file of ctx.args.seedOutputs ?? []) {
654
+ try {
655
+ Object.assign(seededOutputs, JSON.parse(readFileSync(resolve(file), "utf8")));
656
+ } catch (err) {
657
+ console.error(formatError({
658
+ message: `--seed-outputs: could not read "${file}": ${err instanceof Error ? err.message : String(err)}`,
659
+ }));
660
+ return 1;
661
+ }
662
+ }
663
+ const result = await runComponents(resolve("."), selector, { env: ctx.args.env, componentOutputs: seededOutputs });
664
+
665
+ // Dump the accumulated outputs for a downstream job to seed from. Written
666
+ // even on failure (partial outputs) so a resumed run still has what completed.
667
+ if (ctx.args.dumpOutputs && result.run) {
668
+ const dumpPath = resolve(ctx.args.dumpOutputs);
669
+ mkdirSync(dirname(dumpPath), { recursive: true });
670
+ writeFileSync(dumpPath, JSON.stringify(result.run.componentOutputs, null, 2));
671
+ }
672
+
673
+ if (result.gateUnsupported) {
674
+ console.error(formatError({
675
+ message:
676
+ `component "${result.gateUnsupported.component}": gate "${result.gateUnsupported.signalName}" is not ` +
677
+ `supported on the local executor — gates need a durable runtime.`,
678
+ hint: "Re-run with `chant run --components " + result.gateUnsupported.component + " --temporal`.",
679
+ }));
680
+ return 1;
681
+ }
682
+
683
+ if (!result.success && !result.run) {
684
+ console.error(formatError({ message: result.error ?? "Failed to run component(s)" }));
685
+ return 1;
686
+ }
687
+
688
+ if (result.run) {
689
+ if (ctx.args.json) renderDriverJson(result.run); else renderDriverHuman(result.run);
690
+ }
691
+
692
+ if (result.success && result.run) {
693
+ const { config } = await loadChantConfig(resolve(".")).catch(() => ({ config: {} }));
694
+ const disabled = resolveAutoReleaseDisabled(config, ctx.args.noReleaseRecord);
695
+ await recordAutoReleasesForRun(result.run.results, env, `local-${Date.now()}`, disabled);
696
+ }
697
+
698
+ return result.success ? 0 : 1;
699
+ }
700
+
701
+ // ── chant run --components <name> --temporal (#589) ─────────────────────────
702
+
703
+ function componentWorkflowId(componentName: string): string {
704
+ return `chant-component-${componentName}`;
705
+ }
706
+
707
+ /**
708
+ * `chant run --components <name> --temporal` (#589, epic #551 §5/§8) — the
709
+ * durable counterpart to `runOpComponents`'s local path. Mirrors
710
+ * `runOpTemporal`'s shape exactly (build+spawn worker, submit workflow, poll,
711
+ * report) but "build" here means compiling the component's composition
712
+ * on-the-fly via `loadComponentTemporalCodegen` (the Temporal lexicon's
713
+ * `serializeComponent`, mirroring `serializeOps`) rather than reading a
714
+ * pre-existing `dist/ops/<name>/worker.ts` — components have no separate
715
+ * `chant build` step that already produced generated files the way Ops do, so
716
+ * this generates `dist/components/<name>/{workflow,worker,activities}.ts`
717
+ * itself before spawning.
718
+ *
719
+ * Unlike the local executor, a `gate` anywhere in the component's
720
+ * composition is fully supported: the generated workflow durably waits for
721
+ * the signal (see `serializeComponent`'s codegen), survivable across a worker
722
+ * crash and clearable via `chant run signal <name> <signal> --components
723
+ * --temporal` (`runOpSignal` above, extended for components alongside this
724
+ * issue).
725
+ */
726
+ async function runComponentTemporal(ctx: CommandContext, selector: string): Promise<number> {
727
+ if (selector === "all") {
728
+ console.error(formatError({
729
+ message: "`chant run --components all --temporal` is not supported",
730
+ hint: "Pass a single component name — durable execution is compiled and run per component (see epic #551 #589).",
731
+ }));
732
+ return 1;
733
+ }
734
+
735
+ const projectPath = resolve(".");
736
+ const resolved = await resolveComponentTargets(projectPath, selector);
737
+ if (!resolved.success || resolved.targets.length === 0) {
738
+ console.error(formatError({ message: resolved.error ?? `Component "${selector}" not found` }));
739
+ return 1;
740
+ }
741
+ const component = resolved.targets[0];
742
+
743
+ // Load config + profile (mirrors runOpTemporal).
744
+ const { config: chantConfig } = await loadChantConfig(projectPath);
745
+ let profile;
746
+ try {
747
+ profile = resolveProfile(chantConfig as Record<string, unknown>, ctx.args.profile);
748
+ } catch (err) {
749
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
750
+ return 1;
751
+ }
752
+
753
+ // Compile the component to workflow/worker/activities under dist/components/<name>/.
754
+ let codegen;
755
+ try {
756
+ codegen = await loadComponentTemporalCodegen();
757
+ } catch (err) {
758
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
759
+ return 1;
760
+ }
761
+
762
+ // (#629) Fill `chant.config.ts`'s `sbom`/`signing`/`vulnPolicy` defaults into
763
+ // every recognized step BEFORE codegen — same pass the interpret/local path
764
+ // runs in `runComponents` (../../components/cli-support.ts). The Temporal path
765
+ // *inlines* the resolved composition into the generated workflow/activities,
766
+ // so if we serialized the raw component the durable path would silently drop
767
+ // project-level supply-chain defaults the local path honors. (The GitLab
768
+ // generate path needs no equivalent: it emits thin `chant run --components`
769
+ // trigger jobs, so defaults are applied at run time inside the triggered job.)
770
+ const resolvedComponent = applyConfigDefaults(component, chantConfig);
771
+ const files = codegen.serializeComponent(resolvedComponent, { env: ctx.args.env });
772
+ for (const [relPath, content] of Object.entries(files)) {
773
+ const outPath = join(projectPath, "dist", relPath);
774
+ mkdirSync(dirname(outPath), { recursive: true });
775
+ writeFileSync(outPath, content);
776
+ }
777
+
778
+ const workerPath = join(projectPath, "dist", "components", component.name, "worker.ts");
779
+
780
+ // autoStart: spin up temporal server if needed (mirrors runOpTemporal).
781
+ if (profile.autoStart) {
782
+ console.error(formatInfo("autoStart: checking Temporal server..."));
783
+ try {
784
+ await waitForTemporalServer(profile.address, 2000);
785
+ console.error(formatInfo("Temporal server already running."));
786
+ } catch {
787
+ console.error(formatInfo("Starting temporal server start-dev..."));
788
+ spawnChild("temporal", ["server", "start-dev"], {
789
+ cwd: projectPath,
790
+ stdio: "ignore",
791
+ detached: true,
792
+ }).unref();
793
+ await waitForTemporalServer(profile.address, 30_000);
794
+ console.error(formatSuccess("Temporal server ready."));
795
+ }
796
+ }
797
+
798
+ let client;
799
+ try {
800
+ ({ client } = await makeTemporalClient(ctx.args.profile, projectPath));
801
+ } catch (err) {
802
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
803
+ return 1;
804
+ }
805
+
806
+ const profileName = ctx.args.profile ??
807
+ (((chantConfig as Record<string, unknown>).temporal as Record<string, unknown> | undefined)?.defaultProfile as string | undefined) ??
808
+ "local";
809
+
810
+ console.error(formatInfo(`Spawning worker for component "${component.name}" (profile: ${profileName})...`));
811
+ const workerProcess: ChildProcess = spawnChild("npx", ["tsx", workerPath], {
812
+ cwd: projectPath,
813
+ env: { ...process.env, TEMPORAL_PROFILE: profileName },
814
+ stdio: ["ignore", "ignore", "inherit"],
815
+ });
816
+
817
+ const workflowId = componentWorkflowId(component.name);
818
+ const fnName = codegen.componentWorkflowFnName(component.name);
819
+ const taskQueue = profile.taskQueue ?? component.name;
820
+
821
+ let handle: WorkflowHandleRaw;
822
+ try {
823
+ handle = await client.workflow.start(fnName, {
824
+ taskQueue,
825
+ workflowId,
826
+ workflowIdConflictPolicy: "FAIL",
827
+ });
828
+ console.error(formatSuccess(`Workflow started: ${workflowId}`));
829
+ } catch (err) {
830
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
831
+ try { workerProcess.kill(); } catch { /* ignore */ }
832
+ return 1;
833
+ }
834
+
835
+ const gate = findComponentGate(component);
836
+ if (gate) {
837
+ console.error(formatInfo(
838
+ `Component has a gate ("${gate.signalName}") — unblock it with: chant run signal ${component.name} ${gate.signalName} --components --temporal`,
839
+ ));
840
+ }
841
+
842
+ let finalDesc: WorkflowExecutionDescription | undefined;
843
+
844
+ try {
845
+ while (true) {
846
+ await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
847
+ const desc = await handle.describe();
848
+ const history = await handle.fetchHistory();
849
+ renderProgress(component.name, history);
850
+ if (TERMINAL_STATUSES.has(desc.status.name)) {
851
+ process.stderr.write("\n");
852
+ finalDesc = desc;
853
+ break;
854
+ }
855
+ }
856
+ } catch (err) {
857
+ process.stderr.write("\n");
858
+ console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
859
+ return 1;
860
+ } finally {
861
+ try { workerProcess.kill(); } catch { /* ignore */ }
862
+ }
863
+
864
+ if (!finalDesc) return 1;
865
+
866
+ const status = finalDesc.status.name;
867
+ console.error(status === "COMPLETED"
868
+ ? formatSuccess(`Component "${component.name}" completed successfully.`)
869
+ : formatError({ message: `Component "${component.name}" ended with status: ${status}` }),
870
+ );
871
+
872
+ if (status === "COMPLETED") {
873
+ // (#597) Auto-emit a release record post-run — never inside the generated
874
+ // workflow (determinism). The workflow returns its final phaseOutputs
875
+ // (see serializeComponent's codegen) precisely so this read is possible;
876
+ // handle.result() on an already-COMPLETED workflow is a plain historical
877
+ // read, not a new activity/side effect.
878
+ let digest: string | undefined;
879
+ let manifest: ReturnType<typeof extractRunManifestFromPhaseOutputs>;
880
+ try {
881
+ const workflowResult = await handle.result() as { phaseOutputs?: Record<string, Record<string, unknown>> } | undefined;
882
+ digest = extractRunDigestFromPhaseOutputs(workflowResult?.phaseOutputs);
883
+ manifest = extractRunManifestFromPhaseOutputs(workflowResult?.phaseOutputs);
884
+ } catch {
885
+ digest = undefined;
886
+ manifest = undefined;
887
+ }
888
+
889
+ const { config } = await loadChantConfig(projectPath).catch(() => ({ config: {} }));
890
+ const disabled = resolveAutoReleaseDisabled(config, ctx.args.noReleaseRecord);
891
+ const env = ctx.args.env ?? "local";
892
+ const outcome = await maybeRecordAutoRelease(
893
+ { component: component.name, env, success: true, digest, runId: finalDesc.runId },
894
+ { disabled },
895
+ );
896
+ if (!outcome.recorded && outcome.reason === "error") {
897
+ console.error(formatWarning({ message: `release record for "${component.name}"@${env} was not recorded: ${outcome.error}` }));
898
+ } else if (outcome.recorded) {
899
+ console.error(formatInfo(
900
+ `Recorded release: ${formatBold(component.name)}@${env} -> ${outcome.record.digest} (commit ${outcome.commit.slice(0, 7)})`,
901
+ ));
902
+ }
903
+
904
+ // (#609) Persist the run's build manifest post-run, same opt-out flag as
905
+ // the release record above — see ../../components/manifest-persistence.ts.
906
+ const manifestOutcome = await maybePersistBuildManifest({ success: true, manifest }, { disabled });
907
+ if (!manifestOutcome.persisted && manifestOutcome.reason === "error") {
908
+ console.error(formatWarning({ message: `build manifest for "${component.name}"@${env} was not persisted: ${manifestOutcome.error}` }));
909
+ } else if (manifestOutcome.persisted) {
910
+ console.error(formatInfo(
911
+ `Persisted build manifest: ${formatBold(component.name)} -> ${manifestOutcome.manifestDigest} (commit ${manifestOutcome.commit.slice(0, 7)})`,
912
+ ));
913
+ }
914
+ }
915
+
916
+ return status === "COMPLETED" ? 0 : 1;
917
+ }
918
+
322
919
  /**
323
920
  * Run an Op in-process via the local executor — no Temporal worker, server, or
324
921
  * built `worker.ts`. Reads the Op config straight from discovery and resolves
@@ -360,9 +957,19 @@ export async function runOpLocal(ctx: CommandContext): Promise<number> {
360
957
  return 1;
361
958
  }
362
959
 
960
+ // The project's configured lexicons decide which cloud appliers to load
961
+ // (aws → floci, gcp → gcpApply, azure → az group). Best-effort: an unreadable
962
+ // config just yields the temporal base activities.
963
+ let lexicons: string[] = [];
964
+ try {
965
+ lexicons = (await loadChantConfig(process.cwd())).config.lexicons ?? [];
966
+ } catch {
967
+ // No/invalid chant.config — fall back to base activities only.
968
+ }
969
+
363
970
  let activities, profiles;
364
971
  try {
365
- [activities, profiles] = await Promise.all([loadActivities(), loadProfiles()]);
972
+ [activities, profiles] = await Promise.all([loadActivities(lexicons), loadProfiles()]);
366
973
  } catch (err) {
367
974
  console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
368
975
  return 1;