@starci/hfs 4.11.22 → 4.12.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 (1088) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +31 -31
  3. package/ci/cli.d.mts +15 -0
  4. package/ci/cli.mjs +71 -52
  5. package/ci/github.d.mts +43 -0
  6. package/ci/github.mjs +33 -28
  7. package/ci/local.d.mts +12 -0
  8. package/ci/local.mjs +145 -108
  9. package/ci/secret.d.mts +15 -0
  10. package/ci/secret.mjs +31 -21
  11. package/ci/vars.d.mts +17 -0
  12. package/ci/vars.mjs +47 -33
  13. package/ci/verify.d.mts +18 -0
  14. package/ci/verify.mjs +52 -40
  15. package/codemod/button-intent.d.mts +63 -0
  16. package/codemod/button-intent.mjs +338 -285
  17. package/coverage/cli.d.mts +28 -0
  18. package/coverage/cli.mjs +65 -51
  19. package/db/backup-receipt.d.mts +28 -0
  20. package/db/backup-receipt.mjs +78 -58
  21. package/db/drift.d.mts +86 -0
  22. package/db/drift.mjs +213 -180
  23. package/db/dump.d.mts +52 -0
  24. package/db/dump.mjs +63 -56
  25. package/db/entity-list.d.mts +4 -0
  26. package/db/entity-list.mjs +0 -2
  27. package/db/image.d.mts +8 -0
  28. package/db/image.mjs +1 -2
  29. package/db/migrate.d.mts +104 -0
  30. package/db/migrate.mjs +207 -167
  31. package/db/new.d.mts +11 -0
  32. package/db/new.mjs +25 -25
  33. package/db/post-cutover.d.mts +5 -0
  34. package/db/post-cutover.mjs +89 -82
  35. package/db/postgres.d.mts +71 -0
  36. package/db/postgres.mjs +62 -61
  37. package/emit/compiler.d.mts +3 -0
  38. package/emit/compiler.mjs +25 -27
  39. package/emit/contracts.d.mts +35 -0
  40. package/emit/contracts.mjs +46 -50
  41. package/emit/events.d.mts +9 -0
  42. package/emit/events.mjs +19 -20
  43. package/emit/form-bounds.d.mts +83 -0
  44. package/emit/form-bounds.mjs +133 -117
  45. package/emit/graphql-input-bounds.d.mts +63 -0
  46. package/emit/graphql-input-bounds.mjs +90 -79
  47. package/emit/input-bounds.d.mts +30 -0
  48. package/emit/input-bounds.mjs +29 -27
  49. package/emit/operation-schemas.d.mts +24 -0
  50. package/emit/operation-schemas.mjs +136 -116
  51. package/emit/operations-worker.d.mts +1 -0
  52. package/emit/operations-worker.mjs +9 -7
  53. package/emit/operations.d.mts +47 -0
  54. package/emit/operations.mjs +124 -133
  55. package/emit/schema-worker.d.mts +1 -0
  56. package/emit/schema-worker.mjs +57 -50
  57. package/emit/static-graph.d.mts +48 -0
  58. package/emit/static-graph.mjs +766 -640
  59. package/emit/type-schema.d.mts +29 -0
  60. package/emit/type-schema.mjs +153 -140
  61. package/lint/bound-sys.cjs +27 -33
  62. package/lint/chunk.d.mts +17 -0
  63. package/lint/chunk.mjs +41 -31
  64. package/lint/run.d.mts +120 -0
  65. package/lint/run.mjs +414 -325
  66. package/package.json +21 -4
  67. package/release/candidate-ci.d.mts +46 -0
  68. package/release/candidate-ci.mjs +76 -70
  69. package/release/gate.d.mts +120 -0
  70. package/release/gate.mjs +358 -330
  71. package/release/index.d.mts +68 -0
  72. package/release/index.mjs +95 -73
  73. package/release/lint-report.d.mts +14 -0
  74. package/release/lint-report.mjs +33 -32
  75. package/release/push.d.mts +32 -0
  76. package/release/push.mjs +92 -79
  77. package/release/records.d.mts +18 -0
  78. package/release/records.mjs +22 -21
  79. package/release/sonar-quality-gate.d.mts +18 -0
  80. package/release/sonar-quality-gate.mjs +60 -52
  81. package/release/urgent.d.mts +20 -0
  82. package/release/urgent.mjs +76 -74
  83. package/report/order.d.mts +1 -0
  84. package/report/sonar.d.mts +73 -0
  85. package/report/sonar.mjs +82 -89
  86. package/runtime/engine/admission.d.mts +209 -0
  87. package/runtime/engine/admission.mjs +225 -204
  88. package/runtime/engine/by-code-unit.d.mts +5 -0
  89. package/runtime/engine/by-code-unit.mjs +6 -6
  90. package/runtime/engine/config.d.mts +333 -0
  91. package/runtime/engine/config.mjs +486 -328
  92. package/runtime/engine/db/blob.d.mts +83 -0
  93. package/runtime/engine/db/blob.mjs +344 -268
  94. package/runtime/engine/db/event-compact.d.mts +21 -0
  95. package/runtime/engine/db/event-compact.mjs +34 -38
  96. package/runtime/engine/db/machine-connection.d.mts +68 -0
  97. package/runtime/engine/db/machine-connection.mjs +166 -119
  98. package/runtime/engine/db/machine-open.d.mts +26 -0
  99. package/runtime/engine/db/machine-open.mjs +59 -45
  100. package/runtime/engine/db/machine-schema.d.mts +34 -0
  101. package/runtime/engine/db/machine-schema.mjs +102 -83
  102. package/runtime/engine/db/machine.d.mts +1746 -0
  103. package/runtime/engine/db/machine.mjs +1040 -734
  104. package/runtime/engine/db/provider-reservations.d.mts +169 -0
  105. package/runtime/engine/db/provider-reservations.mjs +141 -119
  106. package/runtime/engine/db/provision-lock.d.mts +23 -0
  107. package/runtime/engine/db/provision-lock.mjs +14 -14
  108. package/runtime/engine/db/ref-value.d.mts +19 -0
  109. package/runtime/engine/db/ref-value.mjs +36 -35
  110. package/runtime/engine/db/sqlite-types.d.mts +28 -0
  111. package/runtime/engine/db/sqlite-types.mjs +4 -0
  112. package/runtime/engine/digest.d.mts +4 -0
  113. package/runtime/engine/digest.mjs +16 -7
  114. package/runtime/engine/invalid-config.d.mts +13 -0
  115. package/runtime/engine/invalid-config.mjs +17 -11
  116. package/runtime/engine/model-config.d.mts +91 -0
  117. package/runtime/engine/model-config.mjs +98 -76
  118. package/runtime/engine/orca-config.d.mts +26 -0
  119. package/runtime/engine/orca-config.mjs +22 -17
  120. package/runtime/engine/plain-object.d.mts +2 -0
  121. package/runtime/engine/refuse.d.mts +9 -0
  122. package/runtime/engine/refuse.mjs +3 -6
  123. package/runtime/engine/release-config.d.mts +19 -0
  124. package/runtime/engine/release-config.mjs +22 -18
  125. package/runtime/engine/removed-vocabulary.d.mts +12 -0
  126. package/runtime/engine/removed-vocabulary.mjs +21 -20
  127. package/runtime/engine/resources-config.d.mts +34 -0
  128. package/runtime/engine/resources-config.mjs +42 -35
  129. package/runtime/engine/runtime-root.d.mts +28 -0
  130. package/runtime/engine/runtime-root.mjs +11 -13
  131. package/runtime/engine/secrets.d.mts +41 -0
  132. package/runtime/engine/secrets.mjs +170 -102
  133. package/runtime/engine/sonar-config.d.mts +10 -0
  134. package/runtime/engine/sonar-config.mjs +16 -13
  135. package/runtime/engine/temp-root.d.mts +17 -0
  136. package/runtime/engine/temp-root.mjs +3 -9
  137. package/runtime/engine/yaml.d.mts +9 -0
  138. package/runtime/knowledge/hfs/canon-pins.yaml +10 -10
  139. package/runtime/knowledge/hfs/ci-standard.yaml +2 -2
  140. package/runtime/knowledge/hfs/rules.yaml +72 -6
  141. package/runtime/knowledge/hfs/slots.yaml +3 -3
  142. package/runtime/knowledge/sonar-gate.yaml +1 -1
  143. package/runtime/modules/kernel/failure-codes.yaml +43 -32
  144. package/runtime/modules/schemas/application-stacks.schema.yaml +3 -3
  145. package/runtime/packages/cli/src/catalog.generated.d.mts +13 -0
  146. package/runtime/packages/cli/src/catalog.generated.mjs +1853 -14824
  147. package/runtime/packages/cli/src/validate-args.d.mts +74 -0
  148. package/runtime/packages/cli/src/validate-args.mjs +183 -171
  149. package/runtime/packages/jest-preset/sonar-exclusions.cjs +5 -5
  150. package/runtime/scripts/api/fs/claim-file.d.mts +12 -0
  151. package/runtime/scripts/api/fs/claim-file.mjs +31 -17
  152. package/runtime/scripts/api/fs/ensure-temp-root.d.mts +4 -0
  153. package/runtime/scripts/api/fs/ensure-temp-root.mjs +15 -14
  154. package/runtime/scripts/api/fs/forbidden-root.d.mts +15 -0
  155. package/runtime/scripts/api/fs/forbidden-root.mjs +31 -23
  156. package/runtime/scripts/api/fs/is-link-like.d.mts +10 -0
  157. package/runtime/scripts/api/fs/is-link-like.mjs +25 -11
  158. package/runtime/scripts/api/fs/lib.d.mts +12 -0
  159. package/runtime/scripts/api/fs/lib.mjs +28 -8
  160. package/runtime/scripts/api/fs/make-temp-dir.d.mts +5 -0
  161. package/runtime/scripts/api/fs/make-temp-dir.mjs +3 -4
  162. package/runtime/scripts/api/fs/rename-over.d.mts +13 -0
  163. package/runtime/scripts/api/fs/rename-over.mjs +16 -10
  164. package/runtime/scripts/api/fs/safe-remove.d.mts +25 -0
  165. package/runtime/scripts/api/fs/safe-remove.mjs +129 -71
  166. package/runtime/scripts/api/git/add.d.mts +3 -0
  167. package/runtime/scripts/api/git/add.mjs +0 -1
  168. package/runtime/scripts/api/git/cat-file.d.mts +3 -0
  169. package/runtime/scripts/api/git/cat-file.mjs +0 -1
  170. package/runtime/scripts/api/git/check-ignore.d.mts +3 -0
  171. package/runtime/scripts/api/git/check-ignore.mjs +0 -1
  172. package/runtime/scripts/api/git/commit-tree.d.mts +3 -0
  173. package/runtime/scripts/api/git/commit-tree.mjs +0 -1
  174. package/runtime/scripts/api/git/config-get.d.mts +10 -0
  175. package/runtime/scripts/api/git/config-get.mjs +1 -2
  176. package/runtime/scripts/api/git/diff.d.mts +3 -0
  177. package/runtime/scripts/api/git/diff.mjs +0 -1
  178. package/runtime/scripts/api/git/init.d.mts +7 -0
  179. package/runtime/scripts/api/git/init.mjs +1 -2
  180. package/runtime/scripts/api/git/is-ancestor.d.mts +5 -0
  181. package/runtime/scripts/api/git/is-ancestor.mjs +0 -1
  182. package/runtime/scripts/api/git/lib.d.mts +67 -0
  183. package/runtime/scripts/api/git/lib.mjs +32 -32
  184. package/runtime/scripts/api/git/ls-files.d.mts +3 -0
  185. package/runtime/scripts/api/git/ls-files.mjs +0 -1
  186. package/runtime/scripts/api/git/ls-tree.d.mts +3 -0
  187. package/runtime/scripts/api/git/ls-tree.mjs +0 -1
  188. package/runtime/scripts/api/git/merge-base.d.mts +5 -0
  189. package/runtime/scripts/api/git/merge-base.mjs +2 -3
  190. package/runtime/scripts/api/git/remote.d.mts +3 -0
  191. package/runtime/scripts/api/git/remote.mjs +0 -1
  192. package/runtime/scripts/api/git/rev-parse-query.d.mts +3 -0
  193. package/runtime/scripts/api/git/rev-parse-query.mjs +0 -1
  194. package/runtime/scripts/api/git/show.d.mts +3 -0
  195. package/runtime/scripts/api/git/show.mjs +0 -1
  196. package/runtime/scripts/api/git/tag.d.mts +3 -0
  197. package/runtime/scripts/api/git/tag.mjs +0 -1
  198. package/runtime/scripts/api/git/update-ref.d.mts +7 -0
  199. package/runtime/scripts/api/git/update-ref.mjs +1 -2
  200. package/runtime/scripts/api/git/write-tree.d.mts +3 -0
  201. package/runtime/scripts/api/git/write-tree.mjs +0 -1
  202. package/runtime/scripts/api/node/lib.d.mts +7 -0
  203. package/runtime/scripts/api/node/lib.mjs +17 -7
  204. package/runtime/scripts/api/node/run-node.d.mts +3 -0
  205. package/runtime/scripts/api/node/run-node.mjs +0 -3
  206. package/runtime/scripts/api/process/resolve-real-tool.d.mts +12 -0
  207. package/runtime/scripts/api/process/resolve-real-tool.mjs +46 -38
  208. package/runtime/scripts/api/process/run-program.d.mts +3 -0
  209. package/runtime/scripts/api/process/run-program.mjs +5 -2
  210. package/runtime/scripts/api/sops/decrypt.d.mts +9 -0
  211. package/runtime/scripts/api/sops/decrypt.mjs +1 -2
  212. package/runtime/scripts/api/sops/lib.d.mts +149 -0
  213. package/runtime/scripts/api/sops/lib.mjs +417 -318
  214. package/runtime/scripts/api/sops/resolve-sops.d.mts +3 -0
  215. package/runtime/scripts/api/sops/resolve-sops.mjs +1 -2
  216. package/runtime/scripts/api/sops/seal.d.mts +19 -0
  217. package/runtime/scripts/api/sops/seal.mjs +14 -10
  218. package/runtime/scripts/api/sops/selected-age-recipient.d.mts +3 -0
  219. package/runtime/scripts/api/sops/selected-age-recipient.mjs +1 -2
  220. package/runtime/scripts/api/sops/update-keys.d.mts +16 -0
  221. package/runtime/scripts/api/sops/update-keys.mjs +11 -8
  222. package/runtime/scripts/cli/gen-catalog.d.mts +42 -0
  223. package/runtime/scripts/cli/gen-catalog.mjs +72 -0
  224. package/runtime/scripts/gates/runtime-host.d.mts +23 -0
  225. package/runtime/scripts/gates/runtime-host.mjs +48 -41
  226. package/runtime/scripts/gates/sonar-gate.d.mts +219 -0
  227. package/runtime/scripts/gates/sonar-gate.mjs +166 -153
  228. package/runtime/scripts/gates/starcistacks-ci.d.mts +35 -0
  229. package/runtime/scripts/gates/starcistacks-ci.mjs +47 -39
  230. package/runtime/scripts/gates/starcistacks-form.d.mts +80 -0
  231. package/runtime/scripts/gates/starcistacks-form.mjs +16 -14
  232. package/runtime/scripts/gates/starcistacks-runtime.d.mts +1 -0
  233. package/runtime/scripts/gates/starcistacks-value-file.d.mts +2 -0
  234. package/runtime/scripts/gates/starcistacks-value-file.mjs +14 -11
  235. package/runtime/scripts/gates/starcistacks.d.mts +141 -0
  236. package/runtime/scripts/gates/starcistacks.mjs +470 -355
  237. package/runtime/scripts/guards/git-pathspec.d.mts +48 -0
  238. package/runtime/scripts/guards/git-pathspec.mjs +215 -130
  239. package/runtime/scripts/guards/git-policy.d.mts +30 -0
  240. package/runtime/scripts/guards/git-policy.mjs +278 -235
  241. package/runtime/scripts/guards/hook-io.d.mts +22 -0
  242. package/runtime/scripts/guards/hook-io.mjs +77 -63
  243. package/runtime/scripts/guards/push-scan.d.mts +31 -0
  244. package/runtime/scripts/guards/push-scan.mjs +93 -80
  245. package/runtime/scripts/guards/release-push-gate.d.mts +22 -0
  246. package/runtime/scripts/guards/release-push-gate.mjs +40 -38
  247. package/runtime/scripts/hfs/allows.d.mts +24 -0
  248. package/runtime/scripts/hfs/allows.mjs +37 -38
  249. package/runtime/scripts/hfs/app-wiring.d.mts +72 -0
  250. package/runtime/scripts/hfs/app-wiring.mjs +197 -167
  251. package/runtime/scripts/hfs/architecture/ast-walks.d.mts +89 -0
  252. package/runtime/scripts/hfs/architecture/ast-walks.mjs +180 -163
  253. package/runtime/scripts/hfs/architecture/automatic-gates.d.mts +21 -0
  254. package/runtime/scripts/hfs/architecture/automatic-gates.mjs +80 -73
  255. package/runtime/scripts/hfs/architecture/backend-app-files.d.mts +10 -0
  256. package/runtime/scripts/hfs/architecture/backend-app-files.mjs +88 -77
  257. package/runtime/scripts/hfs/architecture/backend.d.mts +5 -0
  258. package/runtime/scripts/hfs/architecture/backend.mjs +378 -357
  259. package/runtime/scripts/hfs/architecture/background-unowned.d.mts +25 -0
  260. package/runtime/scripts/hfs/architecture/background-unowned.mjs +201 -187
  261. package/runtime/scripts/hfs/architecture/canon-clones.d.mts +8 -0
  262. package/runtime/scripts/hfs/architecture/canon-clones.mjs +260 -209
  263. package/runtime/scripts/hfs/architecture/canon-jsx-clones.d.mts +5 -0
  264. package/runtime/scripts/hfs/architecture/canon-jsx-clones.mjs +149 -116
  265. package/runtime/scripts/hfs/architecture/client-reaches-server.d.mts +28 -0
  266. package/runtime/scripts/hfs/architecture/client-reaches-server.mjs +72 -68
  267. package/runtime/scripts/hfs/architecture/clones.d.mts +54 -0
  268. package/runtime/scripts/hfs/architecture/clones.mjs +212 -217
  269. package/runtime/scripts/hfs/architecture/config-unread.d.mts +14 -0
  270. package/runtime/scripts/hfs/architecture/config-unread.mjs +7 -9
  271. package/runtime/scripts/hfs/architecture/config.d.mts +74 -0
  272. package/runtime/scripts/hfs/architecture/config.mjs +302 -268
  273. package/runtime/scripts/hfs/architecture/connection-map.d.mts +33 -0
  274. package/runtime/scripts/hfs/architecture/connection-map.mjs +258 -225
  275. package/runtime/scripts/hfs/architecture/constructor-deps.d.mts +57 -0
  276. package/runtime/scripts/hfs/architecture/constructor-deps.mjs +80 -71
  277. package/runtime/scripts/hfs/architecture/context-coupling.d.mts +21 -0
  278. package/runtime/scripts/hfs/architecture/context-coupling.mjs +82 -77
  279. package/runtime/scripts/hfs/architecture/context-map.d.mts +102 -0
  280. package/runtime/scripts/hfs/architecture/context-map.mjs +267 -234
  281. package/runtime/scripts/hfs/architecture/context-owner.d.mts +15 -0
  282. package/runtime/scripts/hfs/architecture/context-owner.mjs +73 -61
  283. package/runtime/scripts/hfs/architecture/context-platform-tables.d.mts +18 -0
  284. package/runtime/scripts/hfs/architecture/context-platform-tables.mjs +47 -43
  285. package/runtime/scripts/hfs/architecture/context-transaction.d.mts +20 -0
  286. package/runtime/scripts/hfs/architecture/context-transaction.mjs +54 -52
  287. package/runtime/scripts/hfs/architecture/contract-fixture-guard.d.mts +37 -0
  288. package/runtime/scripts/hfs/architecture/contract-fixture-guard.mjs +113 -104
  289. package/runtime/scripts/hfs/architecture/contracts-readonly.d.mts +32 -0
  290. package/runtime/scripts/hfs/architecture/contracts-readonly.mjs +288 -270
  291. package/runtime/scripts/hfs/architecture/contracts.d.mts +30 -0
  292. package/runtime/scripts/hfs/architecture/contracts.mjs +408 -393
  293. package/runtime/scripts/hfs/architecture/cross-app-duplicate.d.mts +27 -0
  294. package/runtime/scripts/hfs/architecture/cross-app-duplicate.mjs +50 -51
  295. package/runtime/scripts/hfs/architecture/dead-exports-bindings.d.mts +21 -0
  296. package/runtime/scripts/hfs/architecture/dead-exports-bindings.mjs +143 -119
  297. package/runtime/scripts/hfs/architecture/dead-exports.d.mts +32 -0
  298. package/runtime/scripts/hfs/architecture/dead-exports.mjs +286 -228
  299. package/runtime/scripts/hfs/architecture/default-deny.d.mts +21 -0
  300. package/runtime/scripts/hfs/architecture/default-deny.mjs +129 -110
  301. package/runtime/scripts/hfs/architecture/doc-language.d.mts +17 -0
  302. package/runtime/scripts/hfs/architecture/doc-language.mjs +24 -19
  303. package/runtime/scripts/hfs/architecture/entity-registry.d.mts +49 -0
  304. package/runtime/scripts/hfs/architecture/entity-registry.mjs +20 -22
  305. package/runtime/scripts/hfs/architecture/entrypoint.d.mts +13 -0
  306. package/runtime/scripts/hfs/architecture/entrypoint.mjs +47 -45
  307. package/runtime/scripts/hfs/architecture/error-codes.d.mts +16 -0
  308. package/runtime/scripts/hfs/architecture/error-codes.mjs +37 -35
  309. package/runtime/scripts/hfs/architecture/error-masked.d.mts +16 -0
  310. package/runtime/scripts/hfs/architecture/error-masked.mjs +55 -59
  311. package/runtime/scripts/hfs/architecture/fe-slot-allows.d.mts +38 -0
  312. package/runtime/scripts/hfs/architecture/fe-slot-allows.mjs +24 -23
  313. package/runtime/scripts/hfs/architecture/feature-shape.d.mts +26 -0
  314. package/runtime/scripts/hfs/architecture/feature-shape.mjs +40 -38
  315. package/runtime/scripts/hfs/architecture/framework-pinned.d.mts +3 -0
  316. package/runtime/scripts/hfs/architecture/framework-pinned.mjs +21 -21
  317. package/runtime/scripts/hfs/architecture/frontend-block-render.d.mts +26 -0
  318. package/runtime/scripts/hfs/architecture/frontend-block-render.mjs +106 -98
  319. package/runtime/scripts/hfs/architecture/frontend-grammar.d.mts +7 -0
  320. package/runtime/scripts/hfs/architecture/frontend-grammar.mjs +153 -150
  321. package/runtime/scripts/hfs/architecture/frontend-routing.d.mts +23 -0
  322. package/runtime/scripts/hfs/architecture/frontend-routing.mjs +161 -149
  323. package/runtime/scripts/hfs/architecture/frontend-world-render.d.mts +72 -0
  324. package/runtime/scripts/hfs/architecture/frontend-world-render.mjs +343 -305
  325. package/runtime/scripts/hfs/architecture/frontend-world.d.mts +94 -0
  326. package/runtime/scripts/hfs/architecture/frontend-world.mjs +340 -294
  327. package/runtime/scripts/hfs/architecture/frontend.d.mts +31 -0
  328. package/runtime/scripts/hfs/architecture/frontend.mjs +174 -184
  329. package/runtime/scripts/hfs/architecture/function-spec-providers.d.mts +27 -0
  330. package/runtime/scripts/hfs/architecture/function-spec-providers.mjs +124 -106
  331. package/runtime/scripts/hfs/architecture/hfs-graph.d.mts +78 -0
  332. package/runtime/scripts/hfs/architecture/hfs-graph.mjs +52 -48
  333. package/runtime/scripts/hfs/architecture/hfs.d.mts +135 -0
  334. package/runtime/scripts/hfs/architecture/hfs.mjs +328 -282
  335. package/runtime/scripts/hfs/architecture/hooks-are-hooks.d.mts +24 -0
  336. package/runtime/scripts/hfs/architecture/hooks-are-hooks.mjs +81 -71
  337. package/runtime/scripts/hfs/architecture/i18n-keys.d.mts +31 -0
  338. package/runtime/scripts/hfs/architecture/i18n-keys.mjs +155 -141
  339. package/runtime/scripts/hfs/architecture/identity.d.mts +7 -0
  340. package/runtime/scripts/hfs/architecture/identity.mjs +141 -125
  341. package/runtime/scripts/hfs/architecture/index.d.mts +101 -0
  342. package/runtime/scripts/hfs/architecture/index.mjs +272 -272
  343. package/runtime/scripts/hfs/architecture/injection-token-exported.d.mts +21 -0
  344. package/runtime/scripts/hfs/architecture/injection-token-exported.mjs +45 -43
  345. package/runtime/scripts/hfs/architecture/jwt-ast.d.mts +16 -0
  346. package/runtime/scripts/hfs/architecture/jwt-ast.mjs +195 -176
  347. package/runtime/scripts/hfs/architecture/machine-ast.d.mts +88 -0
  348. package/runtime/scripts/hfs/architecture/machine-ast.mjs +163 -155
  349. package/runtime/scripts/hfs/architecture/managed-scripts.d.mts +2 -0
  350. package/runtime/scripts/hfs/architecture/managed-scripts.mjs +19 -20
  351. package/runtime/scripts/hfs/architecture/module-per-transport.d.mts +35 -0
  352. package/runtime/scripts/hfs/architecture/module-per-transport.mjs +177 -172
  353. package/runtime/scripts/hfs/architecture/next-data-contract.d.mts +35 -0
  354. package/runtime/scripts/hfs/architecture/next-data-contract.mjs +100 -78
  355. package/runtime/scripts/hfs/architecture/next-data-inference.d.mts +39 -0
  356. package/runtime/scripts/hfs/architecture/next-data-inference.mjs +170 -154
  357. package/runtime/scripts/hfs/architecture/next-data-key.d.mts +50 -0
  358. package/runtime/scripts/hfs/architecture/next-data-key.mjs +311 -275
  359. package/runtime/scripts/hfs/architecture/next-data-symbols.d.mts +5 -0
  360. package/runtime/scripts/hfs/architecture/next-data-symbols.mjs +17 -17
  361. package/runtime/scripts/hfs/architecture/next-data.d.mts +36 -0
  362. package/runtime/scripts/hfs/architecture/next-data.mjs +351 -334
  363. package/runtime/scripts/hfs/architecture/operation-contract-roots.d.mts +10 -0
  364. package/runtime/scripts/hfs/architecture/operation-contract-roots.mjs +39 -37
  365. package/runtime/scripts/hfs/architecture/owners.d.mts +5 -0
  366. package/runtime/scripts/hfs/architecture/owners.mjs +97 -98
  367. package/runtime/scripts/hfs/architecture/package-shape.d.mts +26 -0
  368. package/runtime/scripts/hfs/architecture/package-shape.mjs +56 -55
  369. package/runtime/scripts/hfs/architecture/presentation.d.mts +24 -0
  370. package/runtime/scripts/hfs/architecture/presentation.mjs +138 -130
  371. package/runtime/scripts/hfs/architecture/reachability.d.mts +25 -0
  372. package/runtime/scripts/hfs/architecture/reachability.mjs +258 -241
  373. package/runtime/scripts/hfs/architecture/register-once.d.mts +18 -0
  374. package/runtime/scripts/hfs/architecture/register-once.mjs +152 -139
  375. package/runtime/scripts/hfs/architecture/registration.d.mts +15 -0
  376. package/runtime/scripts/hfs/architecture/registration.mjs +301 -267
  377. package/runtime/scripts/hfs/architecture/required-files.d.mts +64 -0
  378. package/runtime/scripts/hfs/architecture/required-files.mjs +172 -167
  379. package/runtime/scripts/hfs/architecture/route-files-thin.d.mts +23 -0
  380. package/runtime/scripts/hfs/architecture/route-files-thin.mjs +85 -77
  381. package/runtime/scripts/hfs/architecture/schema-owner.d.mts +34 -0
  382. package/runtime/scripts/hfs/architecture/schema-owner.mjs +206 -181
  383. package/runtime/scripts/hfs/architecture/server-action.d.mts +22 -0
  384. package/runtime/scripts/hfs/architecture/server-action.mjs +48 -48
  385. package/runtime/scripts/hfs/architecture/side-boundary.d.mts +3 -0
  386. package/runtime/scripts/hfs/architecture/side-boundary.mjs +2 -5
  387. package/runtime/scripts/hfs/architecture/source-names-shape.d.mts +85 -0
  388. package/runtime/scripts/hfs/architecture/source-names-shape.mjs +261 -259
  389. package/runtime/scripts/hfs/architecture/source-names.d.mts +7 -0
  390. package/runtime/scripts/hfs/architecture/source-names.mjs +304 -278
  391. package/runtime/scripts/hfs/architecture/sql-keys.d.mts +5 -0
  392. package/runtime/scripts/hfs/architecture/sql-keys.mjs +277 -194
  393. package/runtime/scripts/hfs/architecture/sql-owner.d.mts +30 -0
  394. package/runtime/scripts/hfs/architecture/sql-owner.mjs +236 -194
  395. package/runtime/scripts/hfs/architecture/sql-returning.d.mts +22 -0
  396. package/runtime/scripts/hfs/architecture/sql-returning.mjs +46 -45
  397. package/runtime/scripts/hfs/architecture/sql-token-forms.d.mts +21 -0
  398. package/runtime/scripts/hfs/architecture/sql-token-forms.mjs +86 -74
  399. package/runtime/scripts/hfs/architecture/sql-tokens.d.mts +32 -0
  400. package/runtime/scripts/hfs/architecture/sql-tokens.mjs +456 -341
  401. package/runtime/scripts/hfs/architecture/staged-consumers.d.mts +7 -0
  402. package/runtime/scripts/hfs/architecture/staged-consumers.mjs +35 -30
  403. package/runtime/scripts/hfs/architecture/surface.d.mts +26 -0
  404. package/runtime/scripts/hfs/architecture/surface.mjs +64 -74
  405. package/runtime/scripts/hfs/architecture/symbols.d.mts +11 -0
  406. package/runtime/scripts/hfs/architecture/symbols.mjs +209 -216
  407. package/runtime/scripts/hfs/architecture/test-world-files.d.mts +45 -0
  408. package/runtime/scripts/hfs/architecture/test-world-files.mjs +165 -155
  409. package/runtime/scripts/hfs/architecture/tiers.d.mts +29 -0
  410. package/runtime/scripts/hfs/architecture/tiers.mjs +161 -154
  411. package/runtime/scripts/hfs/architecture/transport-owner.d.mts +37 -0
  412. package/runtime/scripts/hfs/architecture/transport-owner.mjs +155 -149
  413. package/runtime/scripts/hfs/architecture/type-context.d.mts +60 -0
  414. package/runtime/scripts/hfs/architecture/type-context.mjs +255 -250
  415. package/runtime/scripts/hfs/architecture/typescript.d.mts +94 -0
  416. package/runtime/scripts/hfs/architecture/typescript.mjs +358 -318
  417. package/runtime/scripts/hfs/architecture/unit-spec-providers.d.mts +34 -0
  418. package/runtime/scripts/hfs/architecture/unit-spec-providers.mjs +110 -92
  419. package/runtime/scripts/hfs/architecture.d.mts +13 -0
  420. package/runtime/scripts/hfs/architecture.mjs +39 -29
  421. package/runtime/scripts/hfs/canon-pins.d.mts +26 -0
  422. package/runtime/scripts/hfs/canon-pins.mjs +5 -8
  423. package/runtime/scripts/hfs/catalog-once.d.mts +2 -0
  424. package/runtime/scripts/hfs/catalog-once.mjs +8 -9
  425. package/runtime/scripts/hfs/check-results.d.mts +29 -0
  426. package/runtime/scripts/hfs/check-results.mjs +14 -18
  427. package/runtime/scripts/hfs/check.d.mts +144 -0
  428. package/runtime/scripts/hfs/check.mjs +309 -329
  429. package/runtime/scripts/hfs/ci-declaration.d.mts +77 -0
  430. package/runtime/scripts/hfs/ci-declaration.mjs +99 -87
  431. package/runtime/scripts/hfs/coverage-from.d.mts +22 -0
  432. package/runtime/scripts/hfs/coverage-from.mjs +52 -49
  433. package/runtime/scripts/hfs/coverage-scope.d.mts +87 -0
  434. package/runtime/scripts/hfs/coverage-scope.mjs +139 -142
  435. package/runtime/scripts/hfs/db-baseline-verb.d.mts +84 -0
  436. package/runtime/scripts/hfs/db-baseline-verb.mjs +327 -266
  437. package/runtime/scripts/hfs/db-errors.d.mts +2 -0
  438. package/runtime/scripts/hfs/db-errors.mjs +2 -1
  439. package/runtime/scripts/hfs/db-plan-verb.d.mts +33 -0
  440. package/runtime/scripts/hfs/db-plan-verb.mjs +174 -128
  441. package/runtime/scripts/hfs/db-restamp-verb.d.mts +5 -0
  442. package/runtime/scripts/hfs/db-restamp-verb.mjs +94 -70
  443. package/runtime/scripts/hfs/db-squash.d.mts +117 -0
  444. package/runtime/scripts/hfs/db-squash.mjs +414 -351
  445. package/runtime/scripts/hfs/declaration-shape.d.mts +3 -0
  446. package/runtime/scripts/hfs/declaration-shape.mjs +140 -103
  447. package/runtime/scripts/hfs/declaration-slots.d.mts +18 -0
  448. package/runtime/scripts/hfs/declaration-slots.mjs +64 -61
  449. package/runtime/scripts/hfs/doc-commands.d.mts +71 -0
  450. package/runtime/scripts/hfs/doc-commands.mjs +257 -250
  451. package/runtime/scripts/hfs/edition-slots.d.mts +37 -0
  452. package/runtime/scripts/hfs/edition-slots.mjs +43 -40
  453. package/runtime/scripts/hfs/example-secrets.d.mts +18 -0
  454. package/runtime/scripts/hfs/example-secrets.mjs +173 -154
  455. package/runtime/scripts/hfs/gate-threshold.d.mts +20 -0
  456. package/runtime/scripts/hfs/gate-threshold.mjs +14 -22
  457. package/runtime/scripts/hfs/grammar-presentation.d.mts +74 -0
  458. package/runtime/scripts/hfs/grammar-presentation.mjs +109 -106
  459. package/runtime/scripts/hfs/linear-text.d.mts +6 -0
  460. package/runtime/scripts/hfs/linear-text.mjs +20 -20
  461. package/runtime/scripts/hfs/manifest-shape.d.mts +216 -0
  462. package/runtime/scripts/hfs/manifest-shape.mjs +399 -324
  463. package/runtime/scripts/hfs/param-names.d.mts +3 -0
  464. package/runtime/scripts/hfs/param-names.mjs +6 -11
  465. package/runtime/scripts/hfs/path-findings.d.mts +22 -0
  466. package/runtime/scripts/hfs/path-findings.mjs +120 -100
  467. package/runtime/scripts/hfs/pin-findings.d.mts +19 -0
  468. package/runtime/scripts/hfs/pin-findings.mjs +26 -21
  469. package/runtime/scripts/hfs/refusal-codes.d.mts +1 -0
  470. package/runtime/scripts/hfs/refusal-codes.mjs +2 -2
  471. package/runtime/scripts/hfs/repo-identity.d.mts +15 -0
  472. package/runtime/scripts/hfs/repo-identity.mjs +55 -42
  473. package/runtime/scripts/hfs/rule-catalog.d.mts +77 -0
  474. package/runtime/scripts/hfs/rule-catalog.mjs +353 -257
  475. package/runtime/scripts/hfs/rule-params-shape.d.mts +10 -0
  476. package/runtime/scripts/hfs/rule-params-shape.mjs +60 -47
  477. package/runtime/scripts/hfs/rules/a15-findings.d.mts +18 -0
  478. package/runtime/scripts/hfs/rules/a15-findings.mjs +59 -55
  479. package/runtime/scripts/hfs/rules/app-env-required.d.mts +9 -0
  480. package/runtime/scripts/hfs/rules/app-env-required.mjs +13 -13
  481. package/runtime/scripts/hfs/rules/app-root.d.mts +15 -0
  482. package/runtime/scripts/hfs/rules/app-root.mjs +20 -21
  483. package/runtime/scripts/hfs/rules/app-workflow-findings.d.mts +12 -0
  484. package/runtime/scripts/hfs/rules/app-workflow-findings.mjs +4 -4
  485. package/runtime/scripts/hfs/rules/assets.d.mts +13 -0
  486. package/runtime/scripts/hfs/rules/assets.mjs +58 -46
  487. package/runtime/scripts/hfs/rules/boot-proof.d.mts +11 -0
  488. package/runtime/scripts/hfs/rules/boot-proof.mjs +7 -8
  489. package/runtime/scripts/hfs/rules/bypass-markers.d.mts +9 -0
  490. package/runtime/scripts/hfs/rules/bypass-markers.mjs +7 -12
  491. package/runtime/scripts/hfs/rules/canon-copy-drift.d.mts +10 -0
  492. package/runtime/scripts/hfs/rules/canon-copy-drift.mjs +70 -68
  493. package/runtime/scripts/hfs/rules/ci-custody.d.mts +7 -0
  494. package/runtime/scripts/hfs/rules/ci-custody.mjs +72 -73
  495. package/runtime/scripts/hfs/rules/ci-standard.d.mts +12 -0
  496. package/runtime/scripts/hfs/rules/ci-standard.mjs +149 -142
  497. package/runtime/scripts/hfs/rules/cli.d.mts +7 -0
  498. package/runtime/scripts/hfs/rules/cli.mjs +24 -23
  499. package/runtime/scripts/hfs/rules/contract-compat.d.mts +11 -0
  500. package/runtime/scripts/hfs/rules/contract-compat.mjs +64 -53
  501. package/runtime/scripts/hfs/rules/contract.d.mts +26 -0
  502. package/runtime/scripts/hfs/rules/contract.mjs +126 -111
  503. package/runtime/scripts/hfs/rules/coverage-below.d.mts +17 -0
  504. package/runtime/scripts/hfs/rules/coverage-below.mjs +200 -167
  505. package/runtime/scripts/hfs/rules/database-access.d.mts +12 -0
  506. package/runtime/scripts/hfs/rules/database-access.mjs +231 -202
  507. package/runtime/scripts/hfs/rules/database-baseline.d.mts +22 -0
  508. package/runtime/scripts/hfs/rules/database-baseline.mjs +104 -104
  509. package/runtime/scripts/hfs/rules/database-config.d.mts +11 -0
  510. package/runtime/scripts/hfs/rules/database-config.mjs +101 -135
  511. package/runtime/scripts/hfs/rules/database-constants.d.mts +36 -0
  512. package/runtime/scripts/hfs/rules/database-constants.mjs +7 -7
  513. package/runtime/scripts/hfs/rules/database-migrations.d.mts +41 -0
  514. package/runtime/scripts/hfs/rules/database-migrations.mjs +428 -388
  515. package/runtime/scripts/hfs/rules/database-plpgsql.d.mts +5 -0
  516. package/runtime/scripts/hfs/rules/database-plpgsql.mjs +278 -259
  517. package/runtime/scripts/hfs/rules/database-queue-sources.d.mts +4 -0
  518. package/runtime/scripts/hfs/rules/database-queue-sources.mjs +48 -43
  519. package/runtime/scripts/hfs/rules/database-queues.d.mts +15 -0
  520. package/runtime/scripts/hfs/rules/database-queues.mjs +211 -182
  521. package/runtime/scripts/hfs/rules/database-sql.d.mts +16 -0
  522. package/runtime/scripts/hfs/rules/database-sql.mjs +394 -394
  523. package/runtime/scripts/hfs/rules/database-transaction.d.mts +3 -0
  524. package/runtime/scripts/hfs/rules/database-transaction.mjs +25 -27
  525. package/runtime/scripts/hfs/rules/database.d.mts +22 -0
  526. package/runtime/scripts/hfs/rules/database.mjs +42 -58
  527. package/runtime/scripts/hfs/rules/deploy-scan.d.mts +10 -0
  528. package/runtime/scripts/hfs/rules/deploy-scan.mjs +177 -168
  529. package/runtime/scripts/hfs/rules/deploy-workflow.d.mts +3 -0
  530. package/runtime/scripts/hfs/rules/deploy-workflow.mjs +194 -171
  531. package/runtime/scripts/hfs/rules/deps.d.mts +6 -0
  532. package/runtime/scripts/hfs/rules/deps.mjs +61 -60
  533. package/runtime/scripts/hfs/rules/doc-fresh.d.mts +11 -0
  534. package/runtime/scripts/hfs/rules/doc-fresh.mjs +242 -223
  535. package/runtime/scripts/hfs/rules/docker-health.d.mts +9 -0
  536. package/runtime/scripts/hfs/rules/docker-health.mjs +222 -196
  537. package/runtime/scripts/hfs/rules/docker.d.mts +13 -0
  538. package/runtime/scripts/hfs/rules/docker.mjs +234 -208
  539. package/runtime/scripts/hfs/rules/edition.d.mts +18 -0
  540. package/runtime/scripts/hfs/rules/edition.mjs +103 -101
  541. package/runtime/scripts/hfs/rules/env-parity.d.mts +25 -0
  542. package/runtime/scripts/hfs/rules/env-parity.mjs +278 -252
  543. package/runtime/scripts/hfs/rules/env-value-shape.d.mts +21 -0
  544. package/runtime/scripts/hfs/rules/env-value-shape.mjs +82 -67
  545. package/runtime/scripts/hfs/rules/event-bus.d.mts +17 -0
  546. package/runtime/scripts/hfs/rules/event-bus.mjs +145 -133
  547. package/runtime/scripts/hfs/rules/event-tables.d.mts +7 -0
  548. package/runtime/scripts/hfs/rules/event-tables.mjs +77 -75
  549. package/runtime/scripts/hfs/rules/fe-build-args.d.mts +10 -0
  550. package/runtime/scripts/hfs/rules/fe-build-args.mjs +116 -99
  551. package/runtime/scripts/hfs/rules/fe-contract-documents.d.mts +7 -0
  552. package/runtime/scripts/hfs/rules/fe-contract-documents.mjs +121 -111
  553. package/runtime/scripts/hfs/rules/fe-no-tests.d.mts +9 -0
  554. package/runtime/scripts/hfs/rules/fe-no-tests.mjs +37 -36
  555. package/runtime/scripts/hfs/rules/fe-stack.d.mts +23 -0
  556. package/runtime/scripts/hfs/rules/fe-stack.mjs +108 -105
  557. package/runtime/scripts/hfs/rules/feature-files.d.mts +10 -0
  558. package/runtime/scripts/hfs/rules/feature-files.mjs +14 -19
  559. package/runtime/scripts/hfs/rules/frontend-tree.d.mts +18 -0
  560. package/runtime/scripts/hfs/rules/frontend-tree.mjs +105 -91
  561. package/runtime/scripts/hfs/rules/integration-specs.d.mts +7 -0
  562. package/runtime/scripts/hfs/rules/integration-specs.mjs +190 -177
  563. package/runtime/scripts/hfs/rules/kinds.d.mts +6 -0
  564. package/runtime/scripts/hfs/rules/kinds.mjs +88 -81
  565. package/runtime/scripts/hfs/rules/lexicon.d.mts +9 -0
  566. package/runtime/scripts/hfs/rules/lexicon.mjs +43 -40
  567. package/runtime/scripts/hfs/rules/lint-suppression.d.mts +5 -0
  568. package/runtime/scripts/hfs/rules/lint-suppression.mjs +22 -20
  569. package/runtime/scripts/hfs/rules/lite-proof-lane.d.mts +9 -0
  570. package/runtime/scripts/hfs/rules/lite-proof-lane.mjs +59 -58
  571. package/runtime/scripts/hfs/rules/lite-secrets.d.mts +12 -0
  572. package/runtime/scripts/hfs/rules/lite-secrets.mjs +60 -63
  573. package/runtime/scripts/hfs/rules/mcp-tools.d.mts +7 -0
  574. package/runtime/scripts/hfs/rules/mcp-tools.mjs +56 -41
  575. package/runtime/scripts/hfs/rules/monorepo.d.mts +17 -0
  576. package/runtime/scripts/hfs/rules/monorepo.mjs +153 -138
  577. package/runtime/scripts/hfs/rules/peer-integrations.d.mts +7 -0
  578. package/runtime/scripts/hfs/rules/peer-integrations.mjs +39 -36
  579. package/runtime/scripts/hfs/rules/pipeline.d.mts +7 -0
  580. package/runtime/scripts/hfs/rules/pipeline.mjs +53 -53
  581. package/runtime/scripts/hfs/rules/proof-commands.d.mts +14 -0
  582. package/runtime/scripts/hfs/rules/proof-commands.mjs +52 -41
  583. package/runtime/scripts/hfs/rules/read.d.mts +7 -0
  584. package/runtime/scripts/hfs/rules/read.mjs +19 -15
  585. package/runtime/scripts/hfs/rules/release-provenance.d.mts +12 -0
  586. package/runtime/scripts/hfs/rules/release-provenance.mjs +196 -159
  587. package/runtime/scripts/hfs/rules/repo-local-checks.d.mts +5 -0
  588. package/runtime/scripts/hfs/rules/repo-local-checks.mjs +19 -17
  589. package/runtime/scripts/hfs/rules/rule-types.d.mts +40 -0
  590. package/runtime/scripts/hfs/rules/rule-types.mjs +4 -0
  591. package/runtime/scripts/hfs/rules/saga-delivery.d.mts +2 -0
  592. package/runtime/scripts/hfs/rules/saga-delivery.mjs +58 -50
  593. package/runtime/scripts/hfs/rules/saga.d.mts +7 -0
  594. package/runtime/scripts/hfs/rules/saga.mjs +151 -145
  595. package/runtime/scripts/hfs/rules/script-hygiene.d.mts +11 -0
  596. package/runtime/scripts/hfs/rules/script-hygiene.mjs +112 -95
  597. package/runtime/scripts/hfs/rules/secret-custody-only.d.mts +7 -0
  598. package/runtime/scripts/hfs/rules/secret-custody-only.mjs +29 -35
  599. package/runtime/scripts/hfs/rules/secrets.d.mts +29 -0
  600. package/runtime/scripts/hfs/rules/secrets.mjs +45 -44
  601. package/runtime/scripts/hfs/rules/services.d.mts +7 -0
  602. package/runtime/scripts/hfs/rules/services.mjs +148 -148
  603. package/runtime/scripts/hfs/rules/spec-placement.d.mts +8 -0
  604. package/runtime/scripts/hfs/rules/spec-placement.mjs +12 -13
  605. package/runtime/scripts/hfs/rules/stack-tooling.d.mts +11 -0
  606. package/runtime/scripts/hfs/rules/stack-tooling.mjs +45 -52
  607. package/runtime/scripts/hfs/rules/stacks-auth-cookie-domain.d.mts +30 -0
  608. package/runtime/scripts/hfs/rules/stacks-auth-cookie-domain.mjs +149 -0
  609. package/runtime/scripts/hfs/rules/stacks-deploy.d.mts +7 -0
  610. package/runtime/scripts/hfs/rules/stacks-deploy.mjs +32 -42
  611. package/runtime/scripts/hfs/rules/stacks-ingress.d.mts +16 -0
  612. package/runtime/scripts/hfs/rules/stacks-ingress.mjs +62 -64
  613. package/runtime/scripts/hfs/rules/stacks-lite-backing.d.mts +17 -0
  614. package/runtime/scripts/hfs/rules/stacks-lite-backing.mjs +111 -116
  615. package/runtime/scripts/hfs/rules/stacks-release.d.mts +26 -0
  616. package/runtime/scripts/hfs/rules/stacks-release.mjs +335 -309
  617. package/runtime/scripts/hfs/rules/stacks-runtime.d.mts +31 -0
  618. package/runtime/scripts/hfs/rules/stacks-runtime.mjs +130 -124
  619. package/runtime/scripts/hfs/rules/stacks-swarm.d.mts +5 -0
  620. package/runtime/scripts/hfs/rules/stacks-swarm.mjs +366 -344
  621. package/runtime/scripts/hfs/rules/stacks.d.mts +7 -0
  622. package/runtime/scripts/hfs/rules/stacks.mjs +37 -38
  623. package/runtime/scripts/hfs/rules/staged-specs.d.mts +10 -0
  624. package/runtime/scripts/hfs/rules/staged-specs.mjs +14 -18
  625. package/runtime/scripts/hfs/rules/supply-chain.d.mts +10 -0
  626. package/runtime/scripts/hfs/rules/supply-chain.mjs +143 -150
  627. package/runtime/scripts/hfs/rules/test-topology.d.mts +5 -0
  628. package/runtime/scripts/hfs/rules/test-topology.mjs +23 -21
  629. package/runtime/scripts/hfs/rules/text-integrity.d.mts +9 -0
  630. package/runtime/scripts/hfs/rules/text-integrity.mjs +47 -43
  631. package/runtime/scripts/hfs/rules/unused-symbol-flow.d.mts +22 -0
  632. package/runtime/scripts/hfs/rules/unused-symbol-flow.mjs +226 -204
  633. package/runtime/scripts/hfs/rules/unused-symbol-ledger.d.mts +7 -0
  634. package/runtime/scripts/hfs/rules/unused-symbol-ledger.mjs +70 -49
  635. package/runtime/scripts/hfs/rules/unused-symbol-properties.d.mts +12 -0
  636. package/runtime/scripts/hfs/rules/unused-symbol-properties.mjs +141 -126
  637. package/runtime/scripts/hfs/rules/unused-symbol-translators.d.mts +8 -0
  638. package/runtime/scripts/hfs/rules/unused-symbol-translators.mjs +160 -140
  639. package/runtime/scripts/hfs/rules/unused-symbol-values.d.mts +9 -0
  640. package/runtime/scripts/hfs/rules/unused-symbol-values.mjs +138 -125
  641. package/runtime/scripts/hfs/rules/unused-symbol.d.mts +11 -0
  642. package/runtime/scripts/hfs/rules/unused-symbol.mjs +283 -253
  643. package/runtime/scripts/hfs/rules/workflow-contexts.d.mts +8 -0
  644. package/runtime/scripts/hfs/rules/workflow-contexts.mjs +79 -67
  645. package/runtime/scripts/hfs/runtime-rules/git-triggers.d.mts +6 -0
  646. package/runtime/scripts/hfs/runtime-rules/git-triggers.mjs +36 -35
  647. package/runtime/scripts/hfs/runtime-rules/hook-shape.d.mts +10 -0
  648. package/runtime/scripts/hfs/runtime-rules/hook-shape.mjs +45 -42
  649. package/runtime/scripts/hfs/runtime-rules/source-ast.d.mts +39 -0
  650. package/runtime/scripts/hfs/runtime-rules/source-ast.mjs +130 -116
  651. package/runtime/scripts/hfs/runtime-rules/workflow-source.d.mts +5 -0
  652. package/runtime/scripts/hfs/runtime-rules/workflow-source.mjs +8 -7
  653. package/runtime/scripts/hfs/sealed-members.d.mts +22 -0
  654. package/runtime/scripts/hfs/sealed-members.mjs +79 -75
  655. package/runtime/scripts/hfs/secret-bootstrap-crypto.d.mts +12 -0
  656. package/runtime/scripts/hfs/secret-bootstrap-crypto.mjs +151 -167
  657. package/runtime/scripts/hfs/secret-document.d.mts +16 -0
  658. package/runtime/scripts/hfs/secret-document.mjs +59 -75
  659. package/runtime/scripts/hfs/secret-edit.d.mts +14 -0
  660. package/runtime/scripts/hfs/secret-edit.mjs +115 -135
  661. package/runtime/scripts/hfs/secret-errors.d.mts +4 -0
  662. package/runtime/scripts/hfs/secret-errors.mjs +19 -16
  663. package/runtime/scripts/hfs/secret-files.d.mts +20 -0
  664. package/runtime/scripts/hfs/secret-files.mjs +103 -112
  665. package/runtime/scripts/hfs/secret-init.d.mts +108 -0
  666. package/runtime/scripts/hfs/secret-init.mjs +304 -346
  667. package/runtime/scripts/hfs/secret-output.d.mts +18 -0
  668. package/runtime/scripts/hfs/secret-output.mjs +52 -80
  669. package/runtime/scripts/hfs/secret-prompt.d.mts +39 -0
  670. package/runtime/scripts/hfs/secret-prompt.mjs +108 -93
  671. package/runtime/scripts/hfs/secret-sops.d.mts +29 -0
  672. package/runtime/scripts/hfs/secret-sops.mjs +161 -199
  673. package/runtime/scripts/hfs/secret-standard.d.mts +89 -0
  674. package/runtime/scripts/hfs/secret-standard.mjs +300 -264
  675. package/runtime/scripts/hfs/secret-store.d.mts +36 -0
  676. package/runtime/scripts/hfs/secret-store.mjs +120 -136
  677. package/runtime/scripts/hfs/secret.d.mts +40 -0
  678. package/runtime/scripts/hfs/secret.mjs +254 -222
  679. package/runtime/scripts/hfs/slot-app-view.d.mts +11 -0
  680. package/runtime/scripts/hfs/slot-app-view.mjs +69 -74
  681. package/runtime/scripts/hfs/slot-classify.d.mts +75 -0
  682. package/runtime/scripts/hfs/slot-classify.mjs +42 -38
  683. package/runtime/scripts/hfs/slot-errors.d.mts +6 -0
  684. package/runtime/scripts/hfs/slot-errors.mjs +8 -7
  685. package/runtime/scripts/hfs/slot-imports.d.mts +8 -0
  686. package/runtime/scripts/hfs/slot-imports.mjs +70 -63
  687. package/runtime/scripts/hfs/slot-manifest-shape.d.mts +9 -0
  688. package/runtime/scripts/hfs/slot-manifest-shape.mjs +74 -52
  689. package/runtime/scripts/hfs/slot-match.d.mts +50 -0
  690. package/runtime/scripts/hfs/slot-match.mjs +122 -111
  691. package/runtime/scripts/hfs/slot-path.d.mts +1 -0
  692. package/runtime/scripts/hfs/slot-path.mjs +0 -2
  693. package/runtime/scripts/hfs/slot-required.d.mts +11 -0
  694. package/runtime/scripts/hfs/slot-required.mjs +65 -59
  695. package/runtime/scripts/hfs/slot-semantic-problems.d.mts +9 -0
  696. package/runtime/scripts/hfs/slot-semantic-problems.mjs +138 -112
  697. package/runtime/scripts/hfs/slot-side-problems.d.mts +3 -0
  698. package/runtime/scripts/hfs/slot-side-problems.mjs +23 -19
  699. package/runtime/scripts/hfs/slots.d.mts +188 -0
  700. package/runtime/scripts/hfs/slots.mjs +175 -152
  701. package/runtime/scripts/hfs/sql/pg-parse.d.mts +9 -0
  702. package/runtime/scripts/hfs/sql/pg-parse.mjs +25 -25
  703. package/runtime/scripts/hfs/stack-config-kit.d.mts +22 -0
  704. package/runtime/scripts/hfs/stack-config-kit.mjs +21 -17
  705. package/runtime/scripts/hfs/stack-deploy-config.d.mts +155 -0
  706. package/runtime/scripts/hfs/stack-deploy-config.mjs +345 -273
  707. package/runtime/scripts/hfs/stack-ingress-config.d.mts +74 -0
  708. package/runtime/scripts/hfs/stack-ingress-config.mjs +211 -177
  709. package/runtime/scripts/hfs/stacks-gate.d.mts +52 -0
  710. package/runtime/scripts/hfs/stacks-gate.mjs +557 -397
  711. package/runtime/scripts/hfs/starcistacks-runtime.d.mts +7 -0
  712. package/runtime/scripts/hfs/starcistacks-runtime.mjs +51 -40
  713. package/runtime/scripts/hfs/test-world-slot.d.mts +2 -0
  714. package/runtime/scripts/hfs/test-world-slot.mjs +0 -1
  715. package/runtime/scripts/hfs/trailing-slashes.d.mts +2 -0
  716. package/runtime/scripts/hfs/trailing-slashes.mjs +4 -4
  717. package/runtime/scripts/hfs/tree-findings.d.mts +9 -0
  718. package/runtime/scripts/hfs/tree-findings.mjs +18 -17
  719. package/runtime/scripts/hfs/tree.d.mts +35 -0
  720. package/runtime/scripts/hfs/tree.mjs +56 -46
  721. package/runtime/scripts/hfs/typescript-programs.d.mts +36 -0
  722. package/runtime/scripts/hfs/typescript-programs.mjs +66 -69
  723. package/runtime/scripts/hfs/view.d.mts +45 -0
  724. package/runtime/scripts/hfs/view.mjs +38 -40
  725. package/runtime/scripts/lib/bypass-markers.d.mts +15 -0
  726. package/runtime/scripts/lib/bypass-markers.mjs +210 -197
  727. package/runtime/scripts/lib/cli-arg.d.mts +67 -0
  728. package/runtime/scripts/lib/cli-arg.mjs +59 -63
  729. package/runtime/scripts/lib/command-tokens.d.mts +11 -0
  730. package/runtime/scripts/lib/command-tokens.mjs +77 -78
  731. package/runtime/scripts/lib/compose-values.d.mts +6 -0
  732. package/runtime/scripts/lib/compose-values.mjs +7 -7
  733. package/runtime/scripts/lib/css-rules.d.mts +36 -0
  734. package/runtime/scripts/lib/css-rules.mjs +181 -171
  735. package/runtime/scripts/lib/deployment-findings.d.mts +9 -0
  736. package/runtime/scripts/lib/deployment-findings.mjs +4 -4
  737. package/runtime/scripts/lib/dockerfile.d.mts +39 -0
  738. package/runtime/scripts/lib/dockerfile.mjs +131 -114
  739. package/runtime/scripts/lib/dom-tree.d.mts +7 -0
  740. package/runtime/scripts/lib/dom-tree.mjs +3 -3
  741. package/runtime/scripts/lib/env.d.mts +12 -0
  742. package/runtime/scripts/lib/env.mjs +3 -6
  743. package/runtime/scripts/lib/escape.d.mts +6 -0
  744. package/runtime/scripts/lib/escape.mjs +2 -6
  745. package/runtime/scripts/lib/event-contract.d.mts +21 -0
  746. package/runtime/scripts/lib/event-contract.mjs +73 -78
  747. package/runtime/scripts/lib/event-items.d.mts +20 -0
  748. package/runtime/scripts/lib/event-items.mjs +27 -15
  749. package/runtime/scripts/lib/example-refs.d.mts +69 -0
  750. package/runtime/scripts/lib/example-refs.mjs +145 -129
  751. package/runtime/scripts/lib/fs-kind.d.mts +12 -0
  752. package/runtime/scripts/lib/fs-kind.mjs +20 -10
  753. package/runtime/scripts/lib/git-hooks-dir.d.mts +15 -0
  754. package/runtime/scripts/lib/git-hooks-dir.mjs +16 -16
  755. package/runtime/scripts/lib/git.d.mts +24 -0
  756. package/runtime/scripts/lib/git.mjs +15 -16
  757. package/runtime/scripts/lib/glob.d.mts +4 -0
  758. package/runtime/scripts/lib/glob.mjs +23 -14
  759. package/runtime/scripts/lib/grammar-lint.d.mts +47 -0
  760. package/runtime/scripts/lib/grammar-lint.mjs +33 -37
  761. package/runtime/scripts/lib/grammar-vendor-parity-jsx.d.mts +40 -0
  762. package/runtime/scripts/lib/grammar-vendor-parity-jsx.mjs +285 -266
  763. package/runtime/scripts/lib/grammar-vendor-parity.d.mts +61 -0
  764. package/runtime/scripts/lib/grammar-vendor-parity.mjs +209 -216
  765. package/runtime/scripts/lib/graphql-contract.d.mts +53 -0
  766. package/runtime/scripts/lib/graphql-contract.mjs +201 -198
  767. package/runtime/scripts/lib/graphql-sdl.d.mts +66 -0
  768. package/runtime/scripts/lib/graphql-sdl.mjs +230 -205
  769. package/runtime/scripts/lib/hook-limits.d.mts +11 -0
  770. package/runtime/scripts/lib/hook-limits.mjs +0 -1
  771. package/runtime/scripts/lib/i18n.d.mts +48 -0
  772. package/runtime/scripts/lib/i18n.mjs +32 -35
  773. package/runtime/scripts/lib/in-order.d.mts +12 -0
  774. package/runtime/scripts/lib/in-order.mjs +57 -38
  775. package/runtime/scripts/lib/is-main.d.mts +6 -0
  776. package/runtime/scripts/lib/is-main.mjs +11 -4
  777. package/runtime/scripts/lib/js-lex.d.mts +32 -0
  778. package/runtime/scripts/lib/js-lex.mjs +196 -162
  779. package/runtime/scripts/lib/json-clone.d.mts +11 -0
  780. package/runtime/scripts/lib/json-clone.mjs +45 -36
  781. package/runtime/scripts/lib/json-schema.d.mts +2 -0
  782. package/runtime/scripts/lib/json-schema.mjs +127 -90
  783. package/runtime/scripts/lib/json.d.mts +16 -0
  784. package/runtime/scripts/lib/json.mjs +26 -14
  785. package/runtime/scripts/lib/language.d.mts +44 -0
  786. package/runtime/scripts/lib/language.mjs +133 -129
  787. package/runtime/scripts/lib/list.d.mts +17 -0
  788. package/runtime/scripts/lib/list.mjs +9 -14
  789. package/runtime/scripts/lib/loosening-budgets.d.mts +12 -0
  790. package/runtime/scripts/lib/loosening-budgets.mjs +35 -29
  791. package/runtime/scripts/lib/loosening-config.d.mts +64 -0
  792. package/runtime/scripts/lib/loosening-config.mjs +267 -236
  793. package/runtime/scripts/lib/loosening-state.d.mts +77 -0
  794. package/runtime/scripts/lib/loosening-state.mjs +134 -128
  795. package/runtime/scripts/lib/mutation-fence.d.mts +11 -0
  796. package/runtime/scripts/lib/mutation-fence.mjs +10 -5
  797. package/runtime/scripts/lib/normalize.d.mts +12 -0
  798. package/runtime/scripts/lib/normalize.mjs +11 -11
  799. package/runtime/scripts/lib/numeric-match.d.mts +2 -0
  800. package/runtime/scripts/lib/numeric-match.mjs +2 -2
  801. package/runtime/scripts/lib/package-at.d.mts +24 -0
  802. package/runtime/scripts/lib/package-at.mjs +34 -31
  803. package/runtime/scripts/lib/path-key.d.mts +76 -0
  804. package/runtime/scripts/lib/path-key.mjs +53 -38
  805. package/runtime/scripts/lib/pid-alive.d.mts +2 -0
  806. package/runtime/scripts/lib/pid-alive.mjs +10 -3
  807. package/runtime/scripts/lib/properties.d.mts +2 -0
  808. package/runtime/scripts/lib/properties.mjs +17 -11
  809. package/runtime/scripts/lib/provision-operation-schema.d.mts +4 -0
  810. package/runtime/scripts/lib/provision-operation-schema.mjs +4 -5
  811. package/runtime/scripts/lib/read-text.d.mts +12 -0
  812. package/runtime/scripts/lib/read-text.mjs +30 -17
  813. package/runtime/scripts/lib/redact.d.mts +52 -0
  814. package/runtime/scripts/lib/redact.mjs +135 -121
  815. package/runtime/scripts/lib/regex.d.mts +2 -0
  816. package/runtime/scripts/lib/regex.mjs +1 -2
  817. package/runtime/scripts/lib/roots.d.mts +32 -0
  818. package/runtime/scripts/lib/roots.mjs +5 -15
  819. package/runtime/scripts/lib/runtime-example.d.mts +1 -0
  820. package/runtime/scripts/lib/runtime-example.mjs +10 -8
  821. package/runtime/scripts/lib/same-text.d.mts +2 -0
  822. package/runtime/scripts/lib/same-text.mjs +0 -1
  823. package/runtime/scripts/lib/sealed-member.d.mts +16 -0
  824. package/runtime/scripts/lib/sealed-member.mjs +8 -13
  825. package/runtime/scripts/lib/secret-patterns.d.mts +30 -0
  826. package/runtime/scripts/lib/secret-patterns.mjs +175 -163
  827. package/runtime/scripts/lib/shell-source.d.mts +2 -0
  828. package/runtime/scripts/lib/shell-source.mjs +0 -1
  829. package/runtime/scripts/lib/sleep-sync.d.mts +2 -0
  830. package/runtime/scripts/lib/sleep-sync.mjs +5 -6
  831. package/runtime/scripts/lib/sops-envelope.d.mts +34 -0
  832. package/runtime/scripts/lib/sops-envelope.mjs +148 -120
  833. package/runtime/scripts/lib/source-phrases.d.mts +4 -0
  834. package/runtime/scripts/lib/source-phrases.mjs +13 -13
  835. package/runtime/scripts/lib/sql-ast.d.mts +13 -0
  836. package/runtime/scripts/lib/sql-ast.mjs +19 -18
  837. package/runtime/scripts/lib/sqlite.d.mts +21 -0
  838. package/runtime/scripts/lib/sqlite.mjs +3 -9
  839. package/runtime/scripts/lib/stack-declaration.d.mts +51 -0
  840. package/runtime/scripts/lib/stack-declaration.mjs +27 -20
  841. package/runtime/scripts/lib/stack-services.d.mts +73 -0
  842. package/runtime/scripts/lib/stack-services.mjs +128 -129
  843. package/runtime/scripts/lib/starciwork-boundary.d.mts +10 -0
  844. package/runtime/scripts/lib/starciwork-boundary.mjs +98 -92
  845. package/runtime/scripts/lib/swarm-stack.d.mts +24 -0
  846. package/runtime/scripts/lib/swarm-stack.mjs +112 -100
  847. package/runtime/scripts/lib/trim-end.d.mts +2 -0
  848. package/runtime/scripts/lib/trim-end.mjs +4 -4
  849. package/runtime/scripts/lib/ts-analysis.d.mts +24 -0
  850. package/runtime/scripts/lib/ts-analysis.mjs +28 -26
  851. package/runtime/scripts/lib/ts-ast.d.mts +36 -0
  852. package/runtime/scripts/lib/ts-ast.mjs +36 -42
  853. package/runtime/scripts/lib/walk.d.mts +19 -0
  854. package/runtime/scripts/lib/walk.mjs +33 -27
  855. package/runtime/scripts/lib/work-edition.d.mts +10 -0
  856. package/runtime/scripts/lib/work-edition.mjs +29 -21
  857. package/runtime/scripts/lib/workflow-events.d.mts +2 -0
  858. package/runtime/scripts/lib/workflow-events.mjs +5 -4
  859. package/runtime/scripts/lib/worktree-exclude.d.mts +16 -0
  860. package/runtime/scripts/lib/worktree-exclude.mjs +6 -8
  861. package/runtime/scripts/lib/yaml-cached.d.mts +2 -0
  862. package/runtime/scripts/lib/yaml-cached.mjs +4 -4
  863. package/runtime/scripts/machine/artifact-hold.d.mts +26 -0
  864. package/runtime/scripts/machine/artifact-hold.mjs +22 -23
  865. package/runtime/scripts/work/asset-slot.d.mts +96 -0
  866. package/runtime/scripts/work/asset-slot.mjs +201 -175
  867. package/runtime/scripts/work/draw/draw-dna-anatomy.d.mts +30 -0
  868. package/runtime/scripts/work/draw/draw-dna-anatomy.mjs +40 -36
  869. package/runtime/scripts/work/draw/draw-dna-findings.d.mts +12 -0
  870. package/runtime/scripts/work/draw/draw-dna-findings.mjs +240 -206
  871. package/runtime/scripts/work/draw/draw-dna-selector.d.mts +7 -0
  872. package/runtime/scripts/work/draw/draw-dna-selector.mjs +28 -28
  873. package/runtime/scripts/work/draw/draw-dna.d.mts +191 -0
  874. package/runtime/scripts/work/draw/draw-dna.mjs +283 -249
  875. package/runtime/scripts/work/grammar-proposal.d.mts +83 -0
  876. package/runtime/scripts/work/grammar-proposal.mjs +215 -178
  877. package/runtime/scripts/work/work-io.d.mts +62 -0
  878. package/runtime/scripts/work/work-io.mjs +82 -63
  879. package/scaffold/add-app.d.mts +15 -0
  880. package/scaffold/add-app.mjs +111 -163
  881. package/scaffold/add-cli-lite.d.mts +8 -0
  882. package/scaffold/add-cli-lite.mjs +173 -207
  883. package/scaffold/add-compose.d.mts +44 -0
  884. package/scaffold/add-compose.mjs +62 -62
  885. package/scaffold/add-database-lite.d.mts +2 -0
  886. package/scaffold/add-database-lite.mjs +10 -10
  887. package/scaffold/add-fe-layout.d.mts +16 -0
  888. package/scaffold/add-fe-layout.mjs +23 -23
  889. package/scaffold/add-fe-overlay.d.mts +17 -0
  890. package/scaffold/add-fe-overlay.mjs +76 -78
  891. package/scaffold/add-fe-page.d.mts +41 -0
  892. package/scaffold/add-fe-page.mjs +84 -89
  893. package/scaffold/add-fe-unit.d.mts +59 -0
  894. package/scaffold/add-fe-unit.mjs +205 -197
  895. package/scaffold/add-inbox-lite.d.mts +17 -0
  896. package/scaffold/add-inbox-lite.mjs +209 -264
  897. package/scaffold/add-plan.d.mts +68 -0
  898. package/scaffold/add-plan.mjs +164 -149
  899. package/scaffold/add-queue-lite.d.mts +34 -0
  900. package/scaffold/add-queue-lite.mjs +267 -267
  901. package/scaffold/add-table.d.mts +16 -0
  902. package/scaffold/add-table.mjs +405 -442
  903. package/scaffold/add.d.mts +34 -0
  904. package/scaffold/add.mjs +260 -246
  905. package/scaffold/app.d.mts +198 -0
  906. package/scaffold/app.mjs +413 -391
  907. package/scaffold/edition-gate.d.mts +49 -0
  908. package/scaffold/edition-gate.mjs +19 -29
  909. package/scaffold/image.d.mts +4 -0
  910. package/scaffold/image.mjs +12 -12
  911. package/scaffold/lite-exports.d.mts +15 -0
  912. package/scaffold/lite-exports.mjs +262 -255
  913. package/scaffold/pattern-file-slots.d.mts +7 -0
  914. package/scaffold/pattern-file-slots.mjs +29 -24
  915. package/scaffold/service.d.mts +60 -0
  916. package/scaffold/service.mjs +297 -279
  917. package/scaffold/test-world.d.mts +31 -0
  918. package/scaffold/test-world.mjs +71 -78
  919. package/scaffold/yaml-block-edit.d.mts +23 -0
  920. package/scaffold/yaml-block-edit.mjs +95 -87
  921. package/scripts/sync-bundles.d.mts +31 -0
  922. package/src/fixtures/bypass-index.d.mts +4 -0
  923. package/src/fixtures/hfs-stack-tooling/passing.d.mts +8 -0
  924. package/src/fixtures/hfs-stack-tooling/violating.d.mts +19 -0
  925. package/src/fixtures/hfs-stacks-full/model-unavailable.d.mts +10 -0
  926. package/src/fixtures/hfs-stacks-full/passing.d.mts +19 -0
  927. package/src/fixtures/hfs-stacks-full/violating.d.mts +10 -0
  928. package/src/fixtures/loosening/adversarial.d.mts +4 -0
  929. package/src/fixtures/loosening/forms.d.mts +16 -0
  930. package/src/fixtures/loosening/swallows.d.mts +5 -0
  931. package/src/helpers/hfs-arch-fixture.d.mts +47 -0
  932. package/src/helpers/hfs-cli-fixture.d.mts +65 -0
  933. package/src/helpers/hfs-hfs-docker-rules-fixture.d.mts +5 -0
  934. package/src/helpers/hfs-secret-fixture.d.mts +19 -0
  935. package/src/helpers/pre-push-fixture.d.mts +21 -0
  936. package/src/helpers/stack-compose.d.mts +6 -0
  937. package/src/helpers/swarm-stack-fixture.d.mts +18 -0
  938. package/src/helpers/tmpdir.d.mts +2 -0
  939. package/src/main.d.mts +58 -0
  940. package/src/main.mjs +493 -348
  941. package/stack/age-install.d.mts +13 -0
  942. package/stack/age-install.mjs +28 -25
  943. package/stack/backup.d.mts +11 -0
  944. package/stack/backup.mjs +76 -69
  945. package/stack/build-args.d.mts +7 -0
  946. package/stack/build-args.mjs +22 -23
  947. package/stack/build.d.mts +8 -0
  948. package/stack/build.mjs +138 -119
  949. package/stack/cli.d.mts +55 -0
  950. package/stack/cli.mjs +187 -130
  951. package/stack/config.d.mts +197 -0
  952. package/stack/config.mjs +47 -33
  953. package/stack/context.d.mts +122 -0
  954. package/stack/context.mjs +63 -65
  955. package/stack/converge.d.mts +13 -0
  956. package/stack/converge.mjs +73 -69
  957. package/stack/deploy.d.mts +88 -0
  958. package/stack/deploy.mjs +272 -224
  959. package/stack/digest.d.mts +8 -0
  960. package/stack/digest.mjs +1 -6
  961. package/stack/docker-transport.d.mts +5 -0
  962. package/stack/docker-transport.mjs +101 -93
  963. package/stack/edge-alias.d.mts +42 -0
  964. package/stack/edge-alias.mjs +62 -60
  965. package/stack/errors.d.mts +18 -0
  966. package/stack/errors.mjs +8 -10
  967. package/stack/image-scan.d.mts +20 -0
  968. package/stack/image-scan.mjs +114 -101
  969. package/stack/ingress-create.d.mts +4 -0
  970. package/stack/ingress-create.mjs +82 -86
  971. package/stack/ingress-publish.d.mts +6 -0
  972. package/stack/ingress-publish.mjs +194 -182
  973. package/stack/ingress.d.mts +55 -0
  974. package/stack/ingress.mjs +534 -524
  975. package/stack/jobs.d.mts +12 -0
  976. package/stack/jobs.mjs +35 -34
  977. package/stack/live-restore.d.mts +35 -0
  978. package/stack/live-restore.mjs +120 -125
  979. package/stack/post-deploy.d.mts +8 -0
  980. package/stack/post-deploy.mjs +25 -25
  981. package/stack/prepare.d.mts +24 -0
  982. package/stack/prepare.mjs +213 -200
  983. package/stack/private-file.d.mts +5 -0
  984. package/stack/private-file.mjs +9 -9
  985. package/stack/provision.d.mts +25 -0
  986. package/stack/provision.mjs +64 -63
  987. package/stack/prune.d.mts +11 -0
  988. package/stack/prune.mjs +38 -27
  989. package/stack/release-store.d.mts +28 -0
  990. package/stack/release-store.mjs +68 -67
  991. package/stack/remote.d.mts +83 -0
  992. package/stack/remote.mjs +176 -162
  993. package/stack/render.d.mts +14 -0
  994. package/stack/render.mjs +132 -124
  995. package/stack/retire.d.mts +9 -0
  996. package/stack/retire.mjs +31 -34
  997. package/stack/sealed.d.mts +46 -0
  998. package/stack/sealed.mjs +78 -82
  999. package/stack/server-key.d.mts +67 -0
  1000. package/stack/server-key.mjs +217 -203
  1001. package/stack/ssh-session.d.mts +29 -0
  1002. package/stack/ssh-session.mjs +133 -123
  1003. package/stack/target-binding.d.mts +21 -0
  1004. package/stack/target-binding.mjs +68 -44
  1005. package/stack/task.d.mts +12 -0
  1006. package/stack/task.mjs +26 -31
  1007. package/stack/urgent-floor.d.mts +106 -0
  1008. package/stack/urgent-floor.mjs +211 -160
  1009. package/stack/urgent-release.d.mts +38 -0
  1010. package/stack/urgent-release.mjs +26 -22
  1011. package/stack/verify.d.mts +14 -0
  1012. package/stack/verify.mjs +75 -65
  1013. package/sync/ci-commands.d.mts +26 -0
  1014. package/sync/ci-commands.mjs +181 -182
  1015. package/sync/cli.d.mts +8 -0
  1016. package/sync/cli.mjs +9 -9
  1017. package/sync/format.d.mts +38 -0
  1018. package/sync/format.mjs +30 -24
  1019. package/sync/hygiene.d.mts +23 -0
  1020. package/sync/hygiene.mjs +113 -99
  1021. package/sync/index.d.mts +237 -0
  1022. package/sync/index.mjs +457 -436
  1023. package/sync/managed.d.mts +23 -0
  1024. package/sync/managed.mjs +104 -94
  1025. package/sync/quality-services.d.mts +35 -0
  1026. package/sync/quality-services.mjs +48 -41
  1027. package/sync/readme-badges.d.mts +13 -0
  1028. package/sync/readme-badges.mjs +45 -44
  1029. package/sync/sonar-key.d.mts +31 -0
  1030. package/sync/sonar-key.mjs +29 -28
  1031. package/sync/stack-images.d.mts +36 -0
  1032. package/sync/stack-images.mjs +85 -95
  1033. package/sync/ts-strict.d.mts +14 -0
  1034. package/sync/ts-strict.mjs +43 -34
  1035. package/templates/app/ci-workflows/github/workflows/ci.yml +1 -1
  1036. package/templates/app/ci-workflows/github/workflows/images.yml +1 -1
  1037. package/templates/app/ci-workflows/github/workflows/stack-deploy.yml +2 -2
  1038. package/templates/app/ci-workflows/github/workflows/stack-key-restore.yml +1 -1
  1039. package/templates/app/ci-workflows-lite/github/workflows/ci.yml +1 -1
  1040. package/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml +3 -3
  1041. package/templates/app/ci-workflows-lite/github/workflows/images.yml +1 -1
  1042. package/templates/app/ci-workflows-lite/github/workflows/stack-deploy.yml +2 -2
  1043. package/templates/app/ci-workflows-lite/github/workflows/stack-key-restore.yml +1 -1
  1044. package/templates/app/codegen-lite/scripts/codegen.mjs +1 -1
  1045. package/templates/app/db-bootstrap/db/bootstrap.sql +1 -1
  1046. package/templates/app/db-image/starcistacks/images/db/Dockerfile +1 -1
  1047. package/templates/app/hooks/husky/pre-commit +2 -2
  1048. package/templates/app/package-scripts/db.json +3 -3
  1049. package/templates/app/package-scripts/package.json +1 -1
  1050. package/templates/app/quality-config/sonar-project.properties +1 -1
  1051. package/templates/app/skeleton/.starcistacks/application-stacks.yaml +2 -2
  1052. package/templates/app/skeleton/.starcistacks/production/README.md +4 -4
  1053. package/templates/app/skeleton/.starcistacks/production/infra/swarm/stack.yaml +8 -3
  1054. package/templates/app/skeleton/README.md +1 -1
  1055. package/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml +2 -2
  1056. package/templates/app/skeleton-lite/.starcistacks/dev/README.md +1 -1
  1057. package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/stack.yaml +6 -2
  1058. package/templates/app/skeleton-lite/.starcistacks/dev/runtime/env/KEYS.md +3 -2
  1059. package/templates/app/skeleton-lite/.starcistacks/production/README.md +5 -5
  1060. package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/stack.yaml +7 -2
  1061. package/templates/app/skeleton-lite/.starcistacks/production/runtime/env/KEYS.md +3 -2
  1062. package/templates/app/skeleton-lite/README.md +2 -2
  1063. package/templates/be/skeleton/apps/cli/src/compose/platform.ts +1 -1
  1064. package/templates/be/skeleton/apps/cli/src/main.ts +6 -4
  1065. package/templates/be/skeleton/src/modules/platform/config/env-source.config.ts +12 -0
  1066. package/templates/be/skeleton/src/modules/platform/database/abstract.entity.ts +19 -0
  1067. package/templates/be/skeleton/src/modules/platform/database/database.module.ts +7 -1
  1068. package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.spec.ts +19 -0
  1069. package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.ts +4 -3
  1070. package/templates/be/skeleton/src/modules/platform/logging/logging.module.ts +1 -1
  1071. package/templates/be/skeleton/src/modules/platform/logging/logging.options.ts +5 -2
  1072. package/templates/be/skeleton-lite/apps/cli/src/compose/platform.ts +1 -1
  1073. package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.config.spec.ts +40 -0
  1074. package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.config.ts +1 -0
  1075. package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.cookie.spec.ts +48 -1
  1076. package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.cookie.ts +5 -0
  1077. package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.options.ts +5 -0
  1078. package/templates/be/skeleton-lite/src/modules/integrations/passport/strategies/google.strategy.ts +1 -1
  1079. package/templates/be/skeleton-lite/src/modules/integrations/passport/strategies/oauth-state.store.ts +7 -3
  1080. package/templates/be/skeleton-lite/src/modules/platform/database/database.module.ts +7 -1
  1081. package/templates/be/table/entity.ts.tpl +4 -15
  1082. package/upgrade/check.d.mts +9 -0
  1083. package/upgrade/check.mjs +8 -8
  1084. package/upgrade/file-state.d.mts +6 -0
  1085. package/upgrade/file-state.mjs +32 -40
  1086. package/upgrade/index.d.mts +13 -0
  1087. package/upgrade/index.mjs +122 -151
  1088. package/vendor-types.d.mts +8 -0
package/src/main.mjs CHANGED
@@ -1,6 +1,14 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
1
9
  // The @starci/hfs implementation behind `starci app`: one repository, `<app>/`, with one package.json, lockfile and node_modules
2
10
  // at its root and two sides, be/ and fe/, declared by the one hfs.json of kind app. Every verb runs at the app root.
3
- // starci app check [--cwd <dir>] [--json] [--fast] [--base <ref>] [--wiring] [--coverage-from <lcov>]
11
+ // starci app check [--cwd <dir>] [--json] [--fast] [--base <ref>] [--wiring] [--coverage-from <lcov>] | check --staged
4
12
  // every tracked path has a slot; required files exist; nothing forbidden or
5
13
  // tracked-that-must-be-ignored; pins match; every managed file equals its render
6
14
  // (sync/managed.mjs, the .gitignore block and sonar-project.properties included); no empty or ghost
@@ -12,45 +20,50 @@
12
20
  // front-end and back-end source rules), each violation a finding with its why.
13
21
  // ESLint executes once per side through the installed managed config; the FE config composes
14
22
  // the universal canon and the explicitly selected Grammar-family canon.
23
+ // --staged: the pre-commit guard alone (sync/hygiene.mjs: staged .starciwork and .starcistacks paths, the secrets
24
+ // guard and the bypass guard over every staged file read from the index, a new back-end logic file staged
25
+ // without its unit spec); it takes no other flag.
15
26
  // --fast: only what changed since the merge-base with origin/main (else main; --base
16
27
  // overrides it); the machine
17
28
  // runs on those owners without clones and dead exports. No merge-base is a refusal
18
- // (exit 2), never a silent full pass. Exit 1 on any error-level finding. The root checks run once and
29
+ // (exit 2), never a silent full pass. Exit 1 at 20 error findings or a hard blocker (gate-threshold.mjs). The root checks run once and
19
30
  // the side checks and the machine once per side, the side folder as their root; every path is app-relative.
20
- // starci app lint [--cwd <dir>] [--changed <file>...] [--workspace <dir>] [--side be|fe] [--fix] [--format text|json] [--sonar <file>]
31
+ // starci app lint [--cwd <dir>] [--changed <file>...] [--workspace <dir>] [--side be|fe] [--fix] [--json] [--out <file>]
21
32
  // the ONE lint entry (npm run lint): ESLint per side with that side's canon config (per-file rules and
22
33
  // the project-graph rules), this check's findings, and stylelint over the fe side, as one starci/lint@1
23
- // report; --sonar writes the one Sonar import file. Exit 0 clean, 1 findings, 2 a tool could not run (lint/run.mjs).
34
+ // report; --out writes the one Sonar import file. Exit 0 under 20 error findings and no hard blocker, 1 otherwise, 2 a tool could not run (lint/run.mjs).
24
35
  // --workspace <dir> (from the current directory) scopes the same lint to one fe workspace: the
25
36
  // `lint` script of fe/apps/<app> and fe/packages/<pkg>, run by the turbo lint task.
26
- // starci app scaffold <name> [--into <dir>] a new app <dir>/<name>/: the root (hfs.json, package.json, managed files, .starciwork) and the
37
+ // starci app scaffold <name> [--cwd <dir>] a new app <dir>/<name>/ (<dir> is the global --cwd): the root (hfs.json, package.json, managed files, .starciwork) and the
27
38
  // be/ and fe/ skeletons (scaffold/app.mjs). Accepts an empty unborn main Git root.
28
- // starci app explain <path> [--cwd <dir>] [--json] which slot owns the path, its tier, allowed imports, required tests.
39
+ // starci app slot <path> [--cwd <dir>] [--json] which slot owns the path, its tier, allowed imports, required tests.
29
40
  // starci app emit [--cwd <dir>] write be/contracts/<app>/schema.graphql of every api app that serves GraphQL (emit/contracts.mjs):
30
41
  // printSchema(lexicographicSortSchema) of the resolvers the app root composes; no env, no database, no network.
31
- // starci app sync (--check | --write) [--cwd <dir>] the managed files of the root (scripts, husky, CI, .gitignore block, sonar, prettier) and
32
- // of each side (tsconfig, eslint, jest, stylelint); sync/cli.mjs
33
- // starci app hygiene the pre-commit guard: staged .starciwork and .starcistacks paths, the secrets guard over every staged file (read from the index) and a new back-end logic file staged without its unit spec; sync/cli.mjs
42
+ // starci app sync [--execute] [--cwd <dir>] the managed files of the root (scripts, husky, CI, .gitignore block, sonar, prettier) and
43
+ // of each side (tsconfig, eslint, jest, stylelint); sync/cli.mjs. Dry run unless --execute: it reports drift and exits 1 on it.
34
44
  // starci app coverage merge --out <lcov> <lcov-or-dir>... the lcov reports of the sharded unit run merged into one (coverage/cli.mjs; the managed CI coverage job)
35
- // starci app new service <dir> <name> [--inject <Decorator>=<module>:<Type> | <Class>=<module>]... [--cwd <dir>]
45
+ // starci app add service <dir> <name> [--inject <Decorator>=<module>:<Type> | <Class>=<module>]... [--cwd <dir>]
36
46
  // a back-end `<name>.service.ts` and its `<name>.service.spec.ts` skeleton (scaffold/service.mjs; <dir> is
37
47
  // relative to be/): the spec is built
38
48
  // with Test.createTestingModule, one provider per constructor dependency (kit doubles from @starci/jest-preset),
39
49
  // one placeholder it per public method. Never overwrites a file. Both editions: a lite back end keeps full's unit specs (ruling:R212/case-1 (owner:lite-production-swarm), amended by ruling:R212/case-4).
40
- // starci app new image [--cwd <dir>] the Dockerfile of every declared app that has none, from the image canon (scaffold/image.mjs); never overwrites
41
- // starci app new spec <file>.service.ts [--cwd <dir>] the spec skeleton of an existing service, read from its constructor with the repository's TypeScript
42
- // starci app stack prepare|doctor|connect|disconnect|build-args|render|deploy|converge|verify|rollback|prune|backup|jobs --env <env> [--execute]
50
+ // starci app add image [--cwd <dir>] the Dockerfile of every declared app that has none, from the image canon (scaffold/image.mjs); never overwrites
51
+ // starci app add spec <file>.service.ts [--cwd <dir>] the spec skeleton of an existing service, read from its constructor with the repository's TypeScript
52
+ // (service, spec and image take only what is written here: an option another noun takes is refused, as --inject is on every other noun)
53
+ // starci app world <up|down|status> [--stack <dir>] [--services <list>] [--k3d] [--force] [--json] the full edition's local test world (the installed @starci/test-world cli)
54
+ // starci app stack <action> --env <env> [--execute]
43
55
  // the Swarm deploy tooling of stack/ (dry run unless --execute; never prints a secret value; see docs/application-stacks.md).
44
- // starci app secret init | set <env> <slug> <KEY> [--generate <bytes>] | get <env> <slug> [KEY] --to-file [--reveal]
45
- // starci app secret unset <env> <slug> <KEY> [--execute] | rename <env> <slug> <OLD> <NEW> [--execute] | remove <env> <slug> [--execute] [--force-nonempty]
46
- // starci app secret materialize <env> | list <env> | verify <env>
56
+ // starci app secret init | set --env <env> <slug> <KEY> [--generate <bytes>] | get --env <env> <slug> [KEY] --to-file [--reveal]
57
+ // starci app secret unset --env <env> <slug> <KEY> [--execute] | rename --env <env> <slug> <OLD> <NEW> [--execute] | remove --env <env> <slug> [--execute] [--force-nonempty]
58
+ // starci app secret materialize --env <env> | list --env <env> | verify --env <env> | recipients --env <env> [--add|--remove <age1...|owner>] [--execute]
47
59
  // dotenv custody in .starcistacks, public age rule initialization, private KEY files outside Git;
48
60
  // values reach stdout only when get explicitly receives --reveal.
49
- // starci app ci secret set <NAME> [--env E | --dependabot] [--repo owner/name] reads the value from stdin only.
50
- // starci app ci var set <NAME> [--env E] [--value v] | var sync [--execute] | verify [--json]
51
- // declared GitHub CI custody; verify compares names, scopes and public values.
52
- // starci app db new <name> | baseline | restamp --map <restamp.yaml> | plan | migrate | post-cutover | dump
53
- // preview the database cutover or compare its state with the repo; baseline and restamp mutate only with --apply.
61
+ // starci app ci secret set <NAME> [--env E | --dependabot] [--repo owner/name] [--execute] reads the value from stdin only; dry until --execute.
62
+ // starci app ci var set <NAME> [--env E] [--value v] [--execute] | var sync [--execute] | verify [--json] | local [--execute]
63
+ // declared GitHub CI custody; verify compares names, scopes and public values; local prints the CI plan, --execute runs it.
64
+ // starci app db new <name> | baseline | restamp --map <restamp.yaml> | migrate | post-cutover | dump | drift [--db-url-env <NAME>]
65
+ // baseline and restamp preview and mutate only with --execute; migrate without --execute prints the plan and compares
66
+ // the database with the repo (exit 0 agree, 1 drift, 2 refused).
54
67
  // starci app add <api|webhook|realtime|saga|job|reactor|queue|projection> <name> [--event <event> --from <service> --service <Class>=<module>] [--owner <service> --failed <event> --done <event>] [--connection <name>] [--cwd <dir>]
55
68
  // exactly that kind's file tree, generated FROM the files: tree of its pattern topic (knowledge/patterns/be) with the
56
69
  // one template body of each entry (templates/be/patterns), plus the platform capabilities it needs when they are missing;
@@ -60,23 +73,24 @@
60
73
  // or overlay owner (scaffold/add-fe-page.mjs, add-fe-layout.mjs, add-fe-overlay.mjs).
61
74
  // one front-end unit in the shape-slot pattern from templates/fe/units (scaffold/add-fe-unit.mjs); the
62
75
  // first block writes the app's one copy of the status owners. Never overwrites a unit.
63
- // Every finding names a why code and carries its Vietnamese text. check, lint and explain read the app, never write to it. Exit codes:
76
+ // The flags of every verb are those of USAGE below, generated from the parser tables that refuse every other flag.
77
+ // Every finding names a why code and carries its Vietnamese text. check, lint and slot read the app, never write to it. Exit codes:
64
78
  // 0 clean, 1 error findings, 2 a refusal or bad usage.
65
79
  import fs from 'node:fs';
66
80
  import { createRequire } from 'node:module';
67
81
  import path from 'node:path';
68
- import { fileURLToPath, pathToFileURL } from 'node:url';
82
+ import { pathToFileURL } from 'node:url';
69
83
  import { isMain } from '../runtime/scripts/lib/is-main.mjs';
70
84
  import { changedSince, checkDatabase, checkRepository, explainPath, trackedFiles, withCheckProofs } from '../runtime/scripts/hfs/check.mjs';
71
85
  import { secretMain } from '../runtime/scripts/hfs/secret.mjs';
72
86
  import { dbBaselineMain } from '../runtime/scripts/hfs/db-baseline-verb.mjs';
73
87
  import { dbRestampMain } from '../runtime/scripts/hfs/db-restamp-verb.mjs';
74
- import { dbPlanMain } from '../runtime/scripts/hfs/db-plan-verb.mjs';
75
88
  import { formatCoverageReport } from '../runtime/scripts/hfs/coverage-from.mjs';
76
89
  import { gateVerdict } from '../runtime/scripts/hfs/gate-threshold.mjs';
77
90
  import { HFS_DECLARATION_FILE, HfsSlotsError, loadSlotManifest, readRepoDeclaration } from '../runtime/scripts/hfs/slots.mjs';
78
91
  import { formatFindings } from '../sync/format.mjs';
79
92
  import { main as syncMain } from '../sync/cli.mjs';
93
+ import { runWorkHygiene } from '../sync/hygiene.mjs';
80
94
  import { SyncError, bundledPresets } from '../sync/index.mjs';
81
95
  import { managedFindings } from '../sync/managed.mjs';
82
96
  import { emitContracts } from '../emit/contracts.mjs';
@@ -90,399 +104,530 @@ import { eslintRepository, lintRepository, parseLintArgs, printLintText } from '
90
104
  import { writeReport } from '../report/sonar.mjs';
91
105
  import { checkEdition } from '../upgrade/check.mjs';
92
106
  import { UpgradeError, upgradeMain } from '../upgrade/index.mjs';
93
- import { ACTIONS as STACK_ACTIONS, stackMain as deployStackMain } from '../stack/cli.mjs';
94
- import { releaseMain } from '../release/index.mjs';
95
- import { dbMigrateMain } from '../db/migrate.mjs';
96
- import { dbPostCutoverMain } from '../db/post-cutover.mjs';
97
- import { dbDumpMain } from '../db/dump.mjs';
98
- import { dbNewMain } from '../db/new.mjs';
99
- import { dbDriftMain } from '../db/drift.mjs';
107
+ import { ACTIONS as STACK_ACTIONS, FLAGS as STACK_FLAGS, OPERANDS as STACK_OPERANDS, READ_ONLY as STACK_READ_ONLY, REPEAT as STACK_REPEAT, VALUE as STACK_VALUE, stackMain as deployStackMain } from '../stack/cli.mjs';
108
+ import { RELEASE_FLAGS, releaseMain } from '../release/index.mjs';
109
+ import { SPEC as DB_MIGRATE_FLAGS, dbMigrateMain } from '../db/migrate.mjs';
110
+ import { SPEC as DB_POST_CUTOVER_FLAGS, dbPostCutoverMain } from '../db/post-cutover.mjs';
111
+ import { SPEC as DB_DUMP_FLAGS, dbDumpMain } from '../db/dump.mjs';
112
+ import { SPEC as DB_NEW_FLAGS, dbNewMain } from '../db/new.mjs';
113
+ import { SPEC as DB_DRIFT_FLAGS, dbDriftMain } from '../db/drift.mjs';
114
+ import { BASELINE_OPTIONS, DB_BOOLEAN_OPTIONS } from '../runtime/scripts/hfs/db-baseline-verb.mjs';
115
+ import { RESTAMP_OPTIONS } from '../runtime/scripts/hfs/db-restamp-verb.mjs';
116
+ import { SECRET_VERBS, secretUsage } from '../runtime/scripts/hfs/secret.mjs';
117
+ import { BOOLEAN as CI_BOOLEAN, COMMANDS as CI_COMMANDS } from '../ci/cli.mjs';
118
+ import { LOCAL_FLAGS as CI_LOCAL_FLAGS } from '../ci/local.mjs';
119
+ import { USAGE as COVERAGE_USAGE } from '../coverage/cli.mjs';
120
+ import { SYNC_USAGE } from '../sync/cli.mjs';
100
121
  import { codemodMain } from '../codemod/button-intent.mjs';
101
-
102
- export const VERBS = Object.freeze(['scaffold', 'add', 'lint', 'sync', 'check', 'upgrade', 'stack', 'release', 'explain', 'emit', 'new', 'secret', 'ci', 'db', 'hygiene', 'coverage', 'codemod']);
103
- const DATABASE_VERBS = new Map([['baseline', dbBaselineMain], ['restamp', dbRestampMain], ['plan', dbPlanMain], ['migrate', dbMigrateMain], ['post-cutover', dbPostCutoverMain], ['dump', dbDumpMain], ['new', dbNewMain], ['drift', dbDriftMain]]);
104
-
105
- const USAGE = `starci app scaffold <name> [--into <dir>] [--edition full|lite] [--registry-visibility public|private] [--cwd <dir>]
106
- starci app add <api|webhook|realtime|saga|job|reactor|queue|projection|cli|table|app|block|composite|branch|leaf|page|overlay|layout> <name> [options] [--cwd <dir>]
107
- starci app lint [--cwd <dir>] [--changed <file>...] [--workspace <dir>] [--side be|fe] [--fix] [--format text|json] [--sonar <file>]
108
- starci app codemod button-intent [--write] [--format json|markdown] [--report <file.json|file.md>] [--cwd <dir>]
109
- starci app sync (--check | --write) [--cwd <dir>]
110
- starci app check [--cwd <dir>] [--json] [--fast] [--base <ref>] [--wiring] [--coverage-from <lcov>]
111
- starci app db new <kebab-name> [--json] [--cwd <dir>]
112
- starci app db baseline [--stamp <version>] [--url-env <NAME>] [--squash [--drop-extension <a,b>] [--drop-pgmq-queue <q,job_*>] [--seed-tables <t1,t2>] [--image <ref>]] [--apply] [--cwd <dir>]
113
- starci app db restamp --map <restamp.yaml> [--url-env <NAME>] [--apply] [--cwd <dir>]
114
- starci app db plan [--url-env <NAME>] [--json] [--cwd <dir>]
115
- starci app db dump [--url-env <NAME>] --out <dir> [--schema-only] [--json] [--cwd <dir>]
116
- starci app db migrate [--execute] [--url-env <NAME>] [--json] [--cwd <dir>]
117
- starci app db post-cutover [--execute] [--green-at <ISO> | --owner-confirms-old-app-gone] [--url-env <NAME>] [--json] [--cwd <dir>]
118
- starci app db drift [--url-env <NAME>] [--json] [--cwd <dir>]
119
- starci app release gate [--execute] [--source <ref>] [--tag-prefix <prefix>] [--backfill <tag>] [--json] [--cwd <dir>]
120
- starci app release push [--execute] [--remote <name>] [--urgent --reason <text>] [--json] [--cwd <dir>]
121
- starci app upgrade [--plan] [--cwd <dir>]
122
- starci app stack <up|down|status> [--stack <dir>] [--services <list>] [--k3d] [--force] [--json] [--cwd <dir>]
123
- starci app stack <prepare|doctor|connect|disconnect|build-args|render|deploy|converge|verify|rollback|prune|backup|jobs> --env <env> [--execute] [--json] [--cwd <dir>]
124
- starci app stack deploy --env <env> --urgent (--reason <text> [--remote <name>] | --source-sha <sha> --image <service>=<ref>) [--db-url-env <NAME>] [--backup-out <dir>] [--first-start --db-service <service>] [--execute] [--json] [--cwd <dir>]
125
- starci app explain <path> [--cwd <dir>] [--json]
126
- starci app emit [--cwd <dir>]
127
- starci app new service <dir> <name> [--inject <binding>...] [--cwd <dir>]
128
- starci app new spec <file>.service.ts [--cwd <dir>]
129
- starci app new image [--cwd <dir>]
130
- starci app secret init [--cwd <dir>]
131
- starci app secret set <env> <slug> <KEY> [--generate <bytes>] [--cwd <dir>]
132
- starci app secret get <env> <slug> [KEY] --to-file [--reveal] [--cwd <dir>]
133
- starci app secret unset <env> <slug> <KEY> [--execute] [--cwd <dir>]
134
- starci app secret rename <env> <slug> <OLD> <NEW> [--execute] [--cwd <dir>]
135
- starci app secret remove <env> <slug> [--execute] [--force-nonempty] [--cwd <dir>]
136
- starci app secret materialize <env> [--cwd <dir>]
137
- starci app secret list <env> [--cwd <dir>]
138
- starci app secret verify <env> [--cwd <dir>]
139
- starci app secret server-key <env> [--rotate | --backup github | --restore github] [--execute] [--cwd <dir>]
140
- starci app ci secret set <NAME> [--env E | --dependabot] [--repo owner/name] [--cwd <dir>]
141
- starci app ci var set <NAME> [--env E] [--value v] [--repo owner/name] [--cwd <dir>]
142
- starci app ci var sync [--execute] [--repo owner/name] [--cwd <dir>]
143
- starci app ci verify [--json] [--repo owner/name] [--cwd <dir>]
144
- starci app hygiene [--cwd <dir>]
145
- starci app coverage merge --out <lcov> <lcov-or-dir>... [--cwd <dir>]
122
+ /** A value flag as parse stores it: the string given, else undefined. */
123
+ const valueFlag = (opts, flag) => { const given = opts[flag]; return typeof given === 'string' ? given : undefined; };
124
+ /** A boolean flag as parse stores it: true when given, else undefined. */
125
+ const booleanFlag = (opts, flag) => { const given = opts[flag]; return typeof given === 'boolean' ? given : undefined; };
126
+ /** A list flag as parse stores it: every value given, else undefined. */
127
+ const listFlag = (opts, flag) => { const given = opts[flag]; return Array.isArray(given) ? given : undefined; };
128
+ export const VERBS = Object.freeze(['scaffold', 'add', 'lint', 'sync', 'check', 'upgrade', 'stack', 'world', 'release', 'slot', 'emit', 'secret', 'ci', 'db', 'coverage', 'codemod']);
129
+ const DATABASE_VERBS = new Map([['baseline', dbBaselineMain], ['restamp', dbRestampMain], ['migrate', dbMigrateMain], ['post-cutover', dbPostCutoverMain], ['dump', dbDumpMain], ['new', dbNewMain], ['drift', dbDriftMain]]);
130
+ /**
131
+ * The verbs parsed here, each with the only flags it takes ({ boolean, value, list }); a flag of another verb is refused, never ignored.
132
+ * `forms` are its usage lines: the operands and, where a form takes fewer flags than the verb, its own. `edition` marks a verb that reads the
133
+ * global --edition (editionOption).
134
+ */
135
+ /** The flags of the add nouns that generate a file tree from a pattern (service, spec and image take none of them, and --inject is only theirs). */
136
+ const ADD_FLAGS = { value: ['--event', '--from', '--service', '--connection', '--owner', '--failed', '--done', '--shapes', '--read', '--app', '--kind', '--blocks', '--tabs'], boolean: ['--fe', '--form'] };
137
+ const PARSED = {
138
+ scaffold: { run: scaffoldMain, value: ['--registry-visibility'], edition: true, forms: [{ operands: '<name>' }] },
139
+ add: {
140
+ run: addMain, ...ADD_FLAGS, list: ['--inject'],
141
+ forms: [
142
+ { operands: '<api|webhook|realtime|saga|job|reactor|queue|projection|cli|table|app|block|composite|branch|leaf|page|overlay|layout> <name>', only: ADD_FLAGS },
143
+ { operands: 'service <dir> <name>', only: { list: ['--inject'] } },
144
+ { operands: 'spec <file>.service.ts', flags: [] },
145
+ { operands: 'image', flags: [] },
146
+ ],
147
+ },
148
+ check: { run: checkMain, value: ['--base', '--coverage-from'], boolean: ['--json', '--fast', '--wiring', '--staged'], edition: true, forms: [{ only: { boolean: ['--json', '--fast', '--wiring'], value: ['--base', '--coverage-from'] } }, { only: { boolean: ['--staged'] }, edition: false }] },
149
+ slot: { run: slotMain, boolean: ['--json'], forms: [{ operands: '<path>' }] },
150
+ emit: { run: emitMain, forms: [{}] },
151
+ };
152
+ const flagsOf = (spec) => [...(spec.boolean ?? []), ...(spec.value ?? []), ...(spec.list ?? [])];
153
+ const ADD_FLAGS_ALL = flagsOf(ADD_FLAGS);
154
+ /** Every flag some parsed verb takes, and the global --edition: naming one on a verb that does not take it says so. */
155
+ const PARSED_FLAGS = new Set([...Object.values(PARSED).flatMap(flagsOf), '--edition']);
156
+ /** The placeholder of a value flag in the usage; any other prints as <name>. */
157
+ const PLACEHOLDERS = {
158
+ '--registry-visibility': 'public|private', '--edition': 'full|lite', '--base': '<ref>', '--coverage-from': '<lcov>', '--inject': '<binding>',
159
+ '--event': '<event>', '--from': '<service>', '--service': '<Class>=<module>', '--owner': '<service>', '--failed': '<event>', '--done': '<event>',
160
+ '--shapes': '<a,b,c>', '--blocks': '<a,b>', '--tabs': '<a,b>', '--kind': 'modal|drawer', '--image': '<service>=<ref>', '--sha': '<sha>',
161
+ '--previous': '<release>', '--release': '<release>', '--out': '<path>', '--since': '<ISO>', '--timeout': '<seconds>', '--retry': '<seconds>',
162
+ '--keep': '<release.json>', '--ssh-cmd': '<command>', '--extra-compose': '<file>', '--target-binding': '<json>', '--db-url-env': '<NAME>',
163
+ '--backup-out': '<dir>', '--db-service': '<service>', '--reason': '<text>', '--remote': '<name>', '--tag-prefix': '<prefix>',
164
+ '--backfill': '<tag>', '--green-at': '<ISO>', '--stamp': '<version>', '--map': '<restamp.yaml>', '--drop-extension': '<a,b>',
165
+ '--drop-pgmq-queue': '<q,job_*>', '--seed-tables': '<t1,t2>', '--repo': '<owner/name>', '--jobs': '<id,...>', '--parallel': '<n>', '--logs': '<dir>',
166
+ };
167
+ const flagUsage = (flag, { value = false, repeat = false, placeholders = PLACEHOLDERS } = {}) => `[${flag}${value ? ` ${placeholders[flag] ?? `<${flag.slice(2)}>`}` : ''}]${repeat ? '...' : ''}`;
168
+ const line = (...parts) => parts.flat().filter(Boolean).join(' ');
169
+ /** The flags of a { boolean, value, list } spec as usage text. */
170
+ const specUsage = ({ boolean = [], value = [], list = [] }, placeholders = PLACEHOLDERS) => [
171
+ ...boolean.map((flag) => flagUsage(flag)),
172
+ ...value.map((flag) => flagUsage(flag, { value: true, placeholders })),
173
+ ...list.map((flag) => flagUsage(flag, { value: true, repeat: true, placeholders })),
174
+ ];
175
+ /** A dbOptions list (bare names) as a spec; --cwd is the global flag. */
176
+ const dbSpec = (names) => ({ boolean: names.filter((name) => DB_BOOLEAN_OPTIONS.includes(name)).map((name) => `--${name}`), value: names.filter((name) => name !== 'cwd' && !DB_BOOLEAN_OPTIONS.includes(name)).map((name) => `--${name}`) });
177
+ const DATABASE_USAGE = [['new', '<kebab-name>', DB_NEW_FLAGS], ['baseline', '', dbSpec(BASELINE_OPTIONS)], ['restamp', '', dbSpec(RESTAMP_OPTIONS)], ['migrate', '', DB_MIGRATE_FLAGS], ['post-cutover', '', DB_POST_CUTOVER_FLAGS], ['dump', '', DB_DUMP_FLAGS], ['drift', '', DB_DRIFT_FLAGS]];
178
+ /** The usage of each verb, from the tables its parser refuses every other flag with (lint, codemod and upgrade keep hand-parsed arguments, held by main.spec.mjs). */
179
+ const VERB_USAGE = {
180
+ ...Object.fromEntries(Object.entries(PARSED).map(([verb, spec]) => [verb, spec.forms.map((form) => line(`starci app ${verb}`, form.operands, specUsage(form.only ?? (form.flags === undefined ? spec : { value: form.flags })), spec.edition && form.edition !== false ? flagUsage('--edition', { value: true }) : ''))])),
181
+ lint: ['starci app lint [--changed <file>...] [--workspace <dir>] [--side be|fe] [--fix] [--json] [--out <file>]'],
182
+ codemod: ['starci app codemod button-intent [--execute] [--json] [--format json|markdown] [--out <file.json|file.md>]'],
183
+ upgrade: ['starci app upgrade [--execute]'],
184
+ sync: [SYNC_USAGE.sync],
185
+ world: ['starci app world <up|down|status> [--stack <dir>] [--services <list>] [--k3d] [--force] [--json] [--edition full|lite]'],
186
+ stack: [
187
+ ...STACK_ACTIONS.map((action) => line(`starci app stack ${action}`, STACK_OPERANDS[action], STACK_READ_ONLY.includes(action) ? flagUsage('--env', { value: true }) : '--env <env>', STACK_FLAGS[action].map((flag) => flagUsage(flag, { value: STACK_VALUE.has(flag), repeat: STACK_REPEAT.has(flag) })), '[--json]')),
188
+ ],
189
+ release: Object.entries(RELEASE_FLAGS).map(([action, spec]) => line(`starci app release ${action}`, specUsage(spec))),
190
+ secret: SECRET_VERBS.map((verb) => line(`starci app secret ${verb}`, secretUsage(verb))),
191
+ ci: [
192
+ ...Object.entries(CI_COMMANDS).map(([command, options]) => line(`starci app ci ${command}`, command.endsWith(' set') ? '<NAME>' : '', options.map((name) => flagUsage(`--${name}`, { value: !CI_BOOLEAN.has(name) })))),
193
+ line('starci app ci local', specUsage(CI_LOCAL_FLAGS)),
194
+ ],
195
+ db: DATABASE_USAGE.map(([verb, operands, spec]) => line(`starci app db ${verb}`, operands, specUsage(spec, { ...PLACEHOLDERS, '--image': '<ref>', '--out': '<dir>' }))),
196
+ coverage: COVERAGE_USAGE.replace(/^usage: /, '').split(' | ').map((text) => text.replace(' [--cwd <dir>]', '')),
197
+ };
198
+ export const USAGE = `${VERBS.flatMap((verb) => VERB_USAGE[verb]).join('\n')}
199
+ every verb: [--cwd <dir>] [--quiet] [--help]
146
200
  `;
147
201
  const PER_CODE_LIMIT = 25;
148
- const VALUE_FLAGS = new Set(['--base', '--inject', '--into', '--event', '--from', '--service', '--connection', '--owner', '--failed', '--done', '--coverage-from', '--registry-visibility', '--shapes', '--read', '--app', '--kind', '--blocks', '--tabs']);
149
- /** Flags that may repeat: their values are collected in order. */
150
- const LIST_FLAGS = new Set(['--inject']);
151
- const BOOL_FLAGS = new Set(['--json', '--fast', '--fe', '--wiring', '--form']);
152
-
153
- function coverageArgument(arg, args, opts) {
154
- const inline = arg.startsWith('--coverage-from=');
155
- const value = inline ? arg.slice('--coverage-from='.length) : args.next().value;
156
- if (!value || value.startsWith('--')) throw new Error('--coverage-from needs a value');
157
- if (opts['coverage-from'] !== undefined) throw new Error('--coverage-from may be given only once');
158
- opts['coverage-from'] = value;
159
- }
160
-
161
- function valueArgument(arg, args, opts) {
162
- const value = args.next().value;
163
- if (value === undefined) throw new Error(`${arg} needs a value`);
164
- const key = arg.slice(2);
165
- opts[key] = LIST_FLAGS.has(arg) ? [...(opts[key] ?? []), value] : value;
166
- }
167
-
168
- function parse(argv) {
169
- const opts = { positional: [] };
170
- const args = argv.values();
171
- for (const arg of args) {
172
- if (arg === '--coverage-from' || arg.startsWith('--coverage-from=')) {
173
- coverageArgument(arg, args, opts);
174
- continue;
175
- }
176
- if (VALUE_FLAGS.has(arg)) {
177
- valueArgument(arg, args, opts);
202
+ /** Splits the arguments of a parsed verb into { positional, <flag>: value }; a flag the verb does not take, a repeated single value or a missing value is refused. */
203
+ function parse(verb, argv) {
204
+ const { boolean = [], value = [], list = [] } = PARSED[verb];
205
+ const opts = { positional: [] };
206
+ const args = argv.values();
207
+ for (const arg of args) {
208
+ if (!arg.startsWith('--')) {
209
+ opts.positional.push(arg);
210
+ continue;
211
+ }
212
+ const [flag, inline] = arg.split(/=(.*)/s);
213
+ const key = flag.slice(2);
214
+ if (boolean.includes(flag) && inline === undefined)
215
+ opts[key] = true;
216
+ else if (value.includes(flag) || list.includes(flag)) {
217
+ const given = inline ?? args.next().value;
218
+ if (!given || given.startsWith('--'))
219
+ throw new Error(`${flag} needs a value`);
220
+ if (list.includes(flag))
221
+ opts[key] = [...(opts[key] ?? []), given];
222
+ else if (opts[key] !== undefined)
223
+ throw new Error(`${flag} may be given only once`);
224
+ else
225
+ opts[key] = given;
226
+ }
227
+ else if (boolean.includes(flag))
228
+ throw new Error(`${flag} takes no value`);
229
+ else
230
+ throw new Error(PARSED_FLAGS.has(flag) ? `starci app ${verb} takes no ${flag}` : `unknown flag ${flag}`);
178
231
  }
179
- else if (BOOL_FLAGS.has(arg)) opts[arg.slice(2)] = true;
180
- else if (arg.startsWith('--')) throw new Error(`unknown flag ${arg}`);
181
- else opts.positional.push(arg);
182
- }
183
- return opts;
232
+ return opts;
184
233
  }
185
-
186
234
  function machineDescription(machine) {
187
- if (machine.status !== 'ran') return `skipped, ${machine.reason}`;
188
- const owners = machine.paths ? ` (owners ${machine.paths.join(', ')})` : '';
189
- return `ran over ${machine.files} source files${owners}`;
235
+ if (machine.status !== 'ran')
236
+ return `skipped, ${machine.reason}`;
237
+ const owners = machine.paths ? ` (owners ${machine.paths.join(', ')})` : '';
238
+ return `ran over ${machine.files} source files${owners}`;
190
239
  }
191
-
192
240
  function contractDescription(contracts) {
193
- if (contracts.status !== 'checked') return `skipped, ${contracts.reason}`;
194
- const apps = contracts.apps.map((app) => `${app.app}/${app.artifact} ${app.status}`).join(', ') || 'no api app';
195
- return `emitted and compared, ${apps}`;
241
+ if (contracts.status !== 'checked')
242
+ return `skipped, ${contracts.reason}`;
243
+ const apps = contracts.apps.map((app) => `${app.app}/${app.artifact} ${app.status}`).join(', ') || 'no api app';
244
+ return `emitted and compared, ${apps}`;
196
245
  }
197
-
198
246
  function printCheckOverview(result, out) {
199
- out(`starci app check${result.fast ? ' --fast' : ''} ${result.repoRoot} (profile ${result.profile ?? 'unknown'}, manifest ${result.manifest}, ${result.tracked} tracked paths)\n`);
200
- if (result.fast) out(` ${result.fast.changed} path${result.fast.changed === 1 ? '' : 's'} changed since ${result.fast.base.slice(0, 12)}\n`);
201
- out(` architecture machine: ${machineDescription(result.machine)}\n`);
202
- if (result.contracts) out(` contract snapshots: ${contractDescription(result.contracts)}\n`);
203
- if (result.eslint) {
204
- const sides = Object.entries(result.eslint.sides).map(([side, run]) => `${side}: ${run.files} files${run.skipped ? ` (${run.skipped})` : ''}`).join(', ');
205
- out(` ESLint: ${sides}\n`);
206
- for (const error of result.eslint.errors) out(` ESLint tool error: ${error}\n`);
207
- }
247
+ out(`starci app check${result.fast ? ' --fast' : ''} ${result.repoRoot} (profile ${result.profile ?? 'unknown'}, manifest ${result.manifest}, ${result.tracked} tracked paths)\n`);
248
+ if (result.fast)
249
+ out(` ${result.fast.changed} path${result.fast.changed === 1 ? '' : 's'} changed since ${result.fast.base.slice(0, 12)}\n`);
250
+ out(` architecture machine: ${machineDescription(result.machine)}\n`);
251
+ if (result.contracts)
252
+ out(` contract snapshots: ${contractDescription(result.contracts)}\n`);
253
+ if (result.eslint) {
254
+ const sides = Object.entries(result.eslint.sides).map(([side, run]) => `${side}: ${run.files} files${run.skipped ? ` (${run.skipped})` : ''}`).join(', ');
255
+ out(` ESLint: ${sides}\n`);
256
+ for (const error of result.eslint.errors)
257
+ out(` ESLint tool error: ${error}\n`);
258
+ }
208
259
  }
209
-
210
260
  function printFindingGroup(code, list, out) {
211
- const first = list[0];
212
- if (first.engine === 'eslint') out(`\n[${first.level.toUpperCase()}] ${code} x${list.length}\n`);
213
- else out(`\n[${first.level.toUpperCase()}] ${code} x${list.length}: ${first.titleVi}\n ${first.whyVi}\n -> ${first.nextStepVi}\n`);
214
- for (const finding of list.slice(0, PER_CODE_LIMIT)) out(` - ${finding.message}\n`);
215
- if (list.length > PER_CODE_LIMIT) out(` ... and ${list.length - PER_CODE_LIMIT} more (use --json for all)\n`);
261
+ const first = list[0];
262
+ if (first.engine === 'eslint')
263
+ out(`\n[${first.level.toUpperCase()}] ${code} x${list.length}\n`);
264
+ else
265
+ out(`\n[${first.level.toUpperCase()}] ${code} x${list.length}: ${first.titleVi}\n ${first.whyVi}\n -> ${first.nextStepVi}\n`);
266
+ for (const finding of list.slice(0, PER_CODE_LIMIT))
267
+ out(` - ${finding.message}\n`);
268
+ if (list.length > PER_CODE_LIMIT)
269
+ out(` ... and ${list.length - PER_CODE_LIMIT} more (use --json for all)\n`);
216
270
  }
217
-
218
271
  function printCheck(result, out) {
219
- const { counts } = result;
220
- printCheckOverview(result, out);
221
- const byCode = new Map();
222
- for (const f of result.findings) byCode.set(f.code, [...(byCode.get(f.code) ?? []), f]);
223
- for (const [code, list] of byCode) printFindingGroup(code, list, out);
224
- out(`\n${counts.error} error finding${counts.error === 1 ? '' : 's'}, ${counts.warning} warning${counts.warning === 1 ? '' : 's'}, ${counts.info} report-only\n`);
272
+ const { counts } = result;
273
+ printCheckOverview(result, out);
274
+ const byCode = new Map();
275
+ for (const f of result.findings)
276
+ byCode.set(f.code, [...(byCode.get(f.code) ?? []), f]);
277
+ for (const [code, list] of byCode)
278
+ printFindingGroup(code, list, out);
279
+ out(`\n${counts.error} error finding${counts.error === 1 ? '' : 's'}, ${counts.warning} warning${counts.warning === 1 ? '' : 's'}, ${counts.info} report-only\n`);
225
280
  }
226
-
227
281
  function printNoSlot(e, out) {
228
- out(` no slot owns this path (${e.code}): ${e.titleVi}\n ${e.whyVi}\n`);
229
- if (e.nearest) out(` nearest slot ${e.nearest.slot}, pattern ${e.nearest.pattern}; matched ${e.nearest.matchedPrefix || '.'}, then expected ${e.nearest.expectedNext ?? 'nothing'}\n`);
282
+ out(` no slot owns this path (${e.code}): ${e.titleVi}\n ${e.whyVi}\n`);
283
+ if (e.nearest)
284
+ out(` nearest slot ${e.nearest.slot}, pattern ${e.nearest.pattern}; matched ${e.nearest.matchedPrefix || '.'}, then expected ${e.nearest.expectedNext ?? 'nothing'}\n`);
230
285
  }
231
-
232
286
  function printExplain(e, out) {
233
- out(`${e.path}\n`);
234
- if (e.status === 'no-slot') {
235
- printNoSlot(e, out);
236
- return;
237
- }
238
- if (e.status === 'ambiguous') { out(` owned equally by ${e.candidates.join(', ')} (${e.code}): ${e.titleVi}\n`); return; }
239
- const owner = e.owner ? ` owner ${e.owner.root} (${e.owner.slot})` : '';
240
- const imports = e.allowedImports ? `may import ${e.allowedImports.join(', ')}; ${e.importRule}` : (e.importRule ?? 'not applicable');
241
- out(` slot ${e.slot} (${e.pattern})\n presence ${e.presence}, ${e.tracking}\n tier ${e.tier}${owner}\n`);
242
- out(` imports ${imports}\n`);
243
- out(` tests ${e.tests}: ${e.testsMeaning}\n`);
244
- if (e.requiredFiles.length) out(` requires ${e.requiredFiles.join(', ')}\n`);
245
- if (e.goesTo) out(` belongs at ${e.goesTo}\n`);
246
- if (e.rules) out(` rules ${e.rules.join(', ')}\n`);
247
- if (e.code) out(` ${e.code}: ${e.titleVi}\n ${e.whyVi}\n`);
287
+ out(`${e.path}\n`);
288
+ if (e.status === 'no-slot') {
289
+ printNoSlot(e, out);
290
+ return;
291
+ }
292
+ if (e.status === 'ambiguous') {
293
+ out(` owned equally by ${e.candidates.join(', ')} (${e.code}): ${e.titleVi}\n`);
294
+ return;
295
+ }
296
+ const owner = e.owner ? ` owner ${e.owner.root} (${e.owner.slot})` : '';
297
+ const imports = e.allowedImports ? `may import ${e.allowedImports.join(', ')}; ${e.importRule}` : (e.importRule ?? 'not applicable');
298
+ out(` slot ${e.slot} (${e.pattern})\n presence ${e.presence}, ${e.tracking}\n tier ${e.tier}${owner}\n`);
299
+ out(` imports ${imports}\n`);
300
+ out(` tests ${e.tests}: ${e.testsMeaning}\n`);
301
+ if (e.requiredFiles.length)
302
+ out(` requires ${e.requiredFiles.join(', ')}\n`);
303
+ if (e.goesTo)
304
+ out(` belongs at ${e.goesTo}\n`);
305
+ if (e.rules)
306
+ out(` rules ${e.rules.join(', ')}\n`);
307
+ if (e.code)
308
+ out(` ${e.code}: ${e.titleVi}\n ${e.whyVi}\n`);
248
309
  }
249
-
250
310
  /**
251
311
  * The app pass: slots, managed files, formatter, contract snapshots and the architecture machine's check surface, root and sides.
252
312
  * `only` limits the formatter to those (app-relative) files.
253
313
  */
254
314
  async function runCheck({ repoRoot, harness, fast = false, base, only, presets, prettier }) {
255
- const tracked = trackedFiles(repoRoot);
256
- // Managed files of the root and both sides, the .gitignore block and sonar against their render (R04, R05, R11, ...), and prettier
257
- // through the app's own install (R19, never under --fast).
258
- const extraFindings = [...await managedFindings({ repoRoot, tracked, presets }), ...await checkDatabase({ repoRoot, files: tracked, base }), ...(fast ? [] : await formatFindings({ repoRoot, files: only ?? tracked, prettier }))];
259
- // R23 against the be side itself (full pass only): committed snapshots equal what `starci app emit` writes now.
260
- let contracts = null;
261
- let be = null;
262
- try { be = readRepoDeclaration(loadSlotManifest(), repoRoot).sides?.be ?? null; } catch { /* checkRepository reports the unreadable declaration */ }
263
- if (be) {
264
- if (fast) contracts = { status: 'skipped', reason: '--fast does not emit the apps' };
265
- else {
266
- const files = tracked.filter((file) => file.startsWith('be/')).map((file) => file.slice('be/'.length));
267
- const emitted = contractEmitFindings({ repoRoot: path.join(repoRoot, 'be'), files, repo: be, emit: emitContracts });
268
- extraFindings.push(...emitted.findings.map((finding) => ({ ...finding, side: 'be', path: `be/${finding.path}` })));
269
- contracts = { status: 'checked', apps: emitted.apps };
315
+ const tracked = trackedFiles(repoRoot);
316
+ // Managed files of the root and both sides, the .gitignore block and sonar against their render (R04, R05, R11, ...), and prettier
317
+ // through the app's own install (R19, never under --fast).
318
+ const extraFindings = [...await managedFindings({ repoRoot, tracked, presets }), ...await checkDatabase({ repoRoot, files: tracked, base }), ...(fast ? [] : await formatFindings({ repoRoot, files: only ?? tracked, prettier }))];
319
+ // R23 against the be side itself (full pass only): committed snapshots equal what `starci app emit` writes now.
320
+ let contracts = null;
321
+ let be = null;
322
+ try {
323
+ be = readRepoDeclaration(loadSlotManifest(), repoRoot).sides?.be ?? null;
270
324
  }
271
- }
272
- const result = checkRepository({ repoRoot, harness, fast, base, extraFindings });
273
- if (contracts) result.contracts = contracts;
274
- return result;
325
+ catch { /* checkRepository reports the unreadable declaration */ }
326
+ if (be) {
327
+ if (fast)
328
+ contracts = { status: 'skipped', reason: '--fast does not emit the apps' };
329
+ else {
330
+ const files = tracked.filter((file) => file.startsWith('be/')).map((file) => file.slice('be/'.length));
331
+ const emitted = contractEmitFindings({ repoRoot: path.join(repoRoot, 'be'), files, repo: be, emit: emitContracts });
332
+ extraFindings.push(...emitted.findings.map((finding) => ({ ...finding, side: 'be', path: `be/${finding.path}` })));
333
+ contracts = { status: 'checked', apps: emitted.apps };
334
+ }
335
+ }
336
+ const result = checkRepository({ repoRoot, harness, fast, base, extraFindings });
337
+ if (contracts)
338
+ result.contracts = contracts;
339
+ return result;
275
340
  }
276
-
277
341
  /** The nearest folder at or above `dir` that holds hfs.json (the app root of a workspace), or `dir` itself when none does (the lint then refuses it). */
278
342
  export function appRootAbove(dir) {
279
- for (let at = dir; ; at = path.dirname(at)) {
280
- if (fs.existsSync(path.join(at, HFS_DECLARATION_FILE))) return at;
281
- if (path.dirname(at) === at) return dir;
282
- }
343
+ for (let at = dir;; at = path.dirname(at)) {
344
+ if (fs.existsSync(path.join(at, HFS_DECLARATION_FILE)))
345
+ return at;
346
+ if (path.dirname(at) === at)
347
+ return dir;
348
+ }
283
349
  }
284
-
285
350
  /** `starci app lint`: ESLint per side, the app checks and stylelint over the fe side as one report; see lint/run.mjs. */
286
351
  async function lintMain(argv, { cwd, harness, stdout, presets, prettier, runLinter, checkApp = runCheck }) {
287
- const opts = parseLintArgs(argv);
288
- // --workspace names a folder from the working directory (`starci app lint --workspace .` is an fe workspace script); the app
289
- // root is then the nearest folder above it that holds hfs.json, and the workspace is passed on app-relative.
290
- const workspaceDir = opts.workspace === undefined ? null : path.resolve(cwd, opts.workspace);
291
- const repoRoot = path.resolve(workspaceDir ? appRootAbove(workspaceDir) : cwd);
292
- if (workspaceDir) opts.workspace = path.relative(repoRoot, workspaceDir).split(path.sep).join('/');
293
- const { report, sonar, exit } = await lintRepository({
294
- repoRoot, opts, trackedFiles, runLinter,
295
- hfsCheck: (root) => checkApp({ repoRoot: root, harness, only: opts.changed ?? undefined, presets, prettier }),
296
- });
297
- if (opts.sonar !== undefined) writeReport(path.resolve(cwd, opts.sonar), sonar);
298
- if (opts.format === 'json') stdout(`${JSON.stringify(report, null, 2)}
299
- `); else printLintText(report, stdout);
300
- return exit;
352
+ const opts = parseLintArgs(argv);
353
+ // --workspace names a folder from the working directory (`starci app lint --workspace .` is an fe workspace script); the app
354
+ // root is then the nearest folder above it that holds hfs.json, and the workspace is passed on app-relative.
355
+ const workspaceDir = opts.workspace === undefined ? null : path.resolve(cwd, opts.workspace);
356
+ const repoRoot = path.resolve(workspaceDir ? appRootAbove(workspaceDir) : cwd);
357
+ if (workspaceDir)
358
+ opts.workspace = path.relative(repoRoot, workspaceDir).split(path.sep).join('/');
359
+ const { report, sonar, exit } = await lintRepository({
360
+ repoRoot, opts, trackedFiles, runLinter,
361
+ hfsCheck: (root) => checkApp({ repoRoot: root, harness, only: opts.changed ?? undefined, presets, prettier }),
362
+ });
363
+ if (opts.out !== undefined)
364
+ writeReport(path.resolve(cwd, opts.out), sonar);
365
+ if (opts.format === 'json')
366
+ stdout(`${JSON.stringify(report, null, 2)}
367
+ `);
368
+ else
369
+ printLintText(report, stdout);
370
+ return exit;
301
371
  }
302
-
303
372
  /**
304
373
  * The jest preset a new app renders its Sonar exclusions from: the copy this @starci/hfs ships (bundledPresets), the same version the
305
374
  * scaffold pins, so `npx starci-harness app scaffold` works before any dependency of the app is installed.
306
375
  */
307
376
  const scaffoldPresets = () => bundledPresets();
308
-
309
- function globalValueArgument(arg, args) {
310
- const inline = arg.startsWith('--cwd=') || arg.startsWith('--edition=');
311
- const flag = inline ? arg.slice(0, arg.indexOf('=')) : arg;
312
- if (flag !== '--cwd' && flag !== '--edition') return null;
313
- const value = inline ? arg.slice(arg.indexOf('=') + 1) : args.next().value;
314
- if (!value || value.startsWith('--')) throw new Error(`${flag} needs a value`);
315
- if (flag === '--edition' && !['full', 'lite'].includes(value)) throw new Error('--edition accepts full or lite');
316
- return { flag, value };
377
+ /** The value of `--flag <value>` or `--flag=<value>`; a missing value, or one that is a flag, is refused. */
378
+ function flagValue(flag, arg, args) {
379
+ const value = arg.startsWith(`${flag}=`) ? arg.slice(flag.length + 1) : args.next().value;
380
+ if (!value || value.startsWith('--'))
381
+ throw new Error(`${flag} needs a value`);
382
+ return value;
317
383
  }
318
-
384
+ /** The flags every verb takes (--cwd, --quiet, --help), taken out of argv before the verb parses the rest. */
319
385
  function globalOptions(argv, baseCwd) {
320
- const options = { argv: [], cwd: baseCwd, quiet: false, help: false, edition: undefined };
321
- const args = argv.values();
322
- for (const arg of args) {
323
- const valued = globalValueArgument(arg, args);
324
- if (valued) {
325
- if (valued.flag === '--cwd') options.cwd = path.resolve(baseCwd, valued.value);
326
- else options.edition = valued.value;
327
- } else if (arg === '--quiet') options.quiet = true;
328
- else if (arg === '--help') options.help = true;
329
- else options.argv.push(arg);
330
- }
331
- return options;
386
+ const options = { argv: [], cwd: baseCwd, quiet: false, help: false };
387
+ const args = argv.values();
388
+ for (const arg of args) {
389
+ if (arg === '--cwd' || arg.startsWith('--cwd='))
390
+ options.cwd = path.resolve(baseCwd, flagValue('--cwd', arg, args));
391
+ else if (arg === '--quiet')
392
+ options.quiet = true;
393
+ else if (arg === '--help')
394
+ options.help = true;
395
+ else
396
+ options.argv.push(arg);
397
+ }
398
+ return options;
399
+ }
400
+ /**
401
+ * Takes --edition out of the arguments of a verb that reads it: scaffold chooses the edition, check judges only the declared one and
402
+ * world refuses a lite app. Any other verb receives --edition as its own argument and refuses it (upgrade with
403
+ * HFS_UPGRADE_USAGE: editions are fixed at scaffold).
404
+ */
405
+ function editionOption(verb, argv) {
406
+ if (PARSED[verb]?.edition !== true && verb !== 'world')
407
+ return { edition: undefined, argv };
408
+ let edition;
409
+ const rest = [];
410
+ const args = argv.values();
411
+ for (const arg of args) {
412
+ if (arg !== '--edition' && !arg.startsWith('--edition=')) {
413
+ rest.push(arg);
414
+ continue;
415
+ }
416
+ edition = flagValue('--edition', arg, args);
417
+ if (!['full', 'lite'].includes(edition))
418
+ throw new Error('--edition accepts full or lite');
419
+ }
420
+ return { edition, argv: rest };
332
421
  }
333
-
334
422
  async function installedStackMain(cwd) {
335
- const require = createRequire(path.join(cwd, 'package.json'));
336
- let entry;
337
- try { entry = require.resolve('@starci/test-world/cli'); } catch {
338
- throw new Error('starci app stack needs @starci/test-world installed in the app; run npm install --save-dev @starci/test-world');
339
- }
340
- const loaded = await import(pathToFileURL(entry).href);
341
- const candidate = loaded.main ?? loaded.default?.main;
342
- if (typeof candidate !== 'function') throw new Error('@starci/test-world/cli does not export main');
343
- return candidate;
423
+ const require = createRequire(path.join(cwd, 'package.json'));
424
+ let entry;
425
+ try {
426
+ entry = require.resolve('@starci/test-world/cli');
427
+ }
428
+ catch {
429
+ throw new Error('starci app world needs @starci/test-world installed in the app; run npm install --save-dev @starci/test-world');
430
+ }
431
+ const loaded = await import(__rewriteRelativeImportExtension(pathToFileURL(entry).href)); // reason: the app's own @starci/test-world/cli, imported at run time
432
+ const candidate = loaded.main ?? loaded.default?.main;
433
+ if (typeof candidate !== 'function')
434
+ throw new Error('@starci/test-world/cli does not export main');
435
+ return candidate;
344
436
  }
345
-
346
437
  function databaseMain(argv, io) {
347
- const [verb, ...rest] = argv;
348
- const dispatch = DATABASE_VERBS.get(verb);
349
- if (!dispatch) throw new Error('starci app db takes new, baseline, restamp, plan, migrate, post-cutover, dump or drift');
350
- return dispatch(rest, io);
438
+ const [verb, ...rest] = argv;
439
+ const dispatch = DATABASE_VERBS.get(verb);
440
+ if (!dispatch)
441
+ throw new Error('starci app db takes new, baseline, restamp, migrate, post-cutover, dump or drift');
442
+ return dispatch(rest, io);
351
443
  }
352
-
353
444
  function printCheckProofs(result, out) {
354
- if (result.wiring) out(`boot wiring: ${result.wiring.status}, ${result.wiring.apps.length} app(s), ${result.wiring.findings.length} failure(s)\n`);
355
- if (result.coverage) out(formatCoverageReport(result.coverage));
445
+ if (result.wiring)
446
+ out(`boot wiring: ${result.wiring.status}, ${result.wiring.apps.length} app(s), ${result.wiring.findings.length} failure(s)\n`);
447
+ if (result.coverage)
448
+ out(formatCoverageReport(result.coverage));
356
449
  }
357
-
450
+ /** The flags `check --staged` refuses: it is the pre-commit guard alone, so none of the whole-app pass's options means anything with it. */
451
+ const STAGED_REFUSES = ['--json', '--fast', '--base', '--wiring', '--coverage-from'];
358
452
  async function checkMain(opts, { cwd: repoRoot, harness, edition, stdout: out, presets, prettier, checkApp = runCheck, runLinter }) {
359
- if (opts.positional.length) throw new Error('starci app check takes no path');
360
- if (opts.base !== undefined && opts.fast !== true) throw new Error('--base names the ref --fast compares with; it needs --fast');
361
- const checked = await checkEdition({ repoRoot, edition, normal: () => checkApp({ repoRoot, harness, fast: opts.fast === true, base: opts.base, presets, prettier }), presets, prettier });
362
- const proof = withCheckProofs(checked, { repoRoot, edition, wiring: opts.wiring === true, coverageFrom: opts['coverage-from'] });
363
- const changed = opts.fast === true ? changedSince(repoRoot, proof.fast?.base ?? opts.base).files : null;
364
- const existing = changed ? changed.filter(file => fs.existsSync(path.join(repoRoot, file))) : [];
365
- const eslint = await eslintRepository({ repoRoot, changed, existing, run: runLinter });
366
- const findings = [...proof.findings, ...eslint.findings.map(finding => ({ ...finding, code: finding.code ?? finding.rule, level: 'error' }))];
367
- // Green under the threshold (gate-threshold.mjs): every finding is still listed, only the verdict changes.
368
- const verdict = gateVerdict(findings.filter(finding => finding.level === 'error'));
369
- const result = { ...proof, findings, counts: { ...proof.counts, error: proof.counts.error + eslint.findings.length }, eslint: { ...eslint.engine, errors: eslint.errors }, ok: verdict.pass && eslint.errors.length === 0, gate: verdict };
370
- if (opts.json) out(`${JSON.stringify(result, null, 2)}\n`);
371
- else { printCheck(result, out); printCheckProofs(result, out); if (verdict.line) out(`${verdict.line}\n`); }
372
- return eslint.errors.length ? 2 : result.ok ? 0 : 1;
453
+ if (opts.positional.length)
454
+ throw new Error('starci app check takes no path');
455
+ if (opts.staged === true) {
456
+ const given = [...STAGED_REFUSES.filter((flag) => opts[flag.slice(2)] !== undefined), ...(edition === undefined ? [] : ['--edition'])];
457
+ if (given.length)
458
+ throw new Error(`starci app check --staged is the pre-commit guard alone and takes no ${given.join(', ')}`);
459
+ return runWorkHygiene({ cwd: repoRoot, out: (text) => out(`${text}\n`) });
460
+ }
461
+ if (opts.base !== undefined && opts.fast !== true)
462
+ throw new Error('--base names the ref --fast compares with; it needs --fast');
463
+ const checked = await checkEdition({ repoRoot, edition, normal: () => checkApp({ repoRoot, harness, fast: opts.fast === true, base: opts.base, presets, prettier }), presets, prettier });
464
+ const proof = withCheckProofs(checked, { repoRoot, edition, wiring: opts.wiring === true, coverageFrom: valueFlag(opts, 'coverage-from') });
465
+ const changed = opts.fast === true ? changedSince(repoRoot, proof.fast?.base ?? valueFlag(opts, 'base')).files : null;
466
+ const existing = changed ? changed.filter((file) => fs.existsSync(path.join(repoRoot, file))) : [];
467
+ const eslint = await eslintRepository({ repoRoot, changed, existing, run: runLinter });
468
+ const findings = [...proof.findings, ...eslint.findings.map(finding => ({ ...finding, code: finding.code ?? finding.rule, level: 'error' }))];
469
+ // Green under the threshold (gate-threshold.mjs): every finding is still listed, only the verdict changes.
470
+ const verdict = gateVerdict(findings.filter(finding => finding.level === 'error'));
471
+ const result = { ...proof, findings, counts: { ...proof.counts, error: proof.counts.error + eslint.findings.length }, eslint: { ...eslint.engine, errors: eslint.errors }, ok: verdict.pass && eslint.errors.length === 0, gate: verdict };
472
+ if (opts.json)
473
+ out(`${JSON.stringify(result, null, 2)}\n`);
474
+ else {
475
+ printCheck(result, out);
476
+ printCheckProofs(result, out);
477
+ if (verdict.line)
478
+ out(`${verdict.line}\n`);
479
+ }
480
+ return eslint.errors.length ? 2 : result.ok ? 0 : 1;
373
481
  }
374
-
375
- function emitMain(opts, { cwd: repoRoot, stdout: out, run }) {
376
- if (opts.positional.length) throw new Error('starci app emit takes no path');
377
- const be = readRepoDeclaration(loadSlotManifest(), repoRoot).sides?.be;
378
- if (!be) throw new Error('starci app emit runs at the app root (the folder of hfs.json)');
379
- const { written, skipped, standIns } = emitContracts({ repoRoot: path.join(repoRoot, 'be'), declaration: be, run });
380
- for (const file of written) out(`wrote be/${file}\n`);
381
- const skipSummary = skipped.length ? `, ${skipped.join(', ')} serve no GraphQL` : '';
382
- out(`starci app emit: ${written.length} written${skipSummary}\n`);
383
- for (const [app, lines] of Object.entries(standIns)) {
384
- out(`${app}: ${lines.length} dependenc${lines.length === 1 ? 'y' : 'ies'} of the resolvers could not load here and stood in (no GraphQL type is affected):\n`);
385
- for (const line of lines) out(` ${line}\n`);
386
- }
387
- return 0;
482
+ function emitMain(opts, { cwd: repoRoot, stdout: out }) {
483
+ if (opts.positional.length)
484
+ throw new Error('starci app emit takes no path');
485
+ const be = readRepoDeclaration(loadSlotManifest(), repoRoot).sides?.be;
486
+ if (!be)
487
+ throw new Error('starci app emit runs at the app root (the folder of hfs.json)');
488
+ const { written, skipped, standIns } = emitContracts({ repoRoot: path.join(repoRoot, 'be'), declaration: be });
489
+ for (const file of written)
490
+ out(`wrote be/${file}\n`);
491
+ const skipSummary = skipped.length ? `, ${skipped.join(', ')} serve no GraphQL` : '';
492
+ out(`starci app emit: ${written.length} written${skipSummary}\n`);
493
+ for (const [app, lines] of Object.entries(standIns)) {
494
+ out(`${app}: ${lines.length} dependenc${lines.length === 1 ? 'y' : 'ies'} of the resolvers could not load here and stood in (no GraphQL type is affected):\n`);
495
+ for (const line of lines)
496
+ out(` ${line}\n`);
497
+ }
498
+ return 0;
388
499
  }
389
-
390
- function newMain(opts, { cwd: repoRoot, stdout: out }) {
391
- const [kind, ...args] = opts.positional;
392
- let written;
393
- if (kind === 'service' && args.length === 2) written = newService({ repoRoot, dir: args[0], name: args[1], inject: opts.inject ?? [] });
394
- else if (kind === 'spec' && args.length === 1 && opts.inject === undefined) written = newSpec({ repoRoot, file: args[0] });
395
- else if (kind === 'image' && args.length === 0 && opts.inject === undefined) written = newImages({ repoRoot });
396
- else throw new Error('starci app new takes `service <dir> <name> [--inject ...]`, `spec <file>.service.ts` or `image`');
397
- for (const file of written) out(`created ${file}\n`);
398
- return 0;
500
+ /** The nouns of `add` that write into an existing app's files by their own generators (scaffold/service.mjs, scaffold/image.mjs) and take no pattern option. */
501
+ const ADD_FILE_NOUNS = ['service', 'spec', 'image'];
502
+ /** `add service <dir> <name> [--inject ...]`, `add spec <file>.service.ts` and `add image`: never overwrites; an option another noun takes is refused. */
503
+ function addFileNoun(noun, opts, repoRoot, out) {
504
+ const [, ...args] = opts.positional;
505
+ const [first = '', second = ''] = args;
506
+ const foreign = ADD_FLAGS_ALL.filter((flag) => opts[flag.slice(2)] !== undefined);
507
+ if (foreign.length)
508
+ throw new Error(`starci app add ${noun} takes no ${foreign.join(', ')}`);
509
+ if (noun !== 'service' && opts.inject !== undefined)
510
+ throw new Error(`starci app add ${noun} takes no --inject; only add service does`);
511
+ let written;
512
+ if (noun === 'service' && args.length === 2)
513
+ written = newService({ repoRoot, dir: first, name: second, inject: listFlag(opts, 'inject') ?? [] });
514
+ else if (noun === 'spec' && args.length === 1)
515
+ written = newSpec({ repoRoot, file: first });
516
+ else if (noun === 'image' && args.length === 0)
517
+ written = newImages({ repoRoot });
518
+ else
519
+ throw new Error('starci app add takes `service <dir> <name> [--inject ...]`, `spec <file>.service.ts` or `image`');
520
+ for (const file of written)
521
+ out(`created ${file}\n`);
522
+ return 0;
399
523
  }
400
-
401
524
  function addMain(opts, { cwd: repoRoot, stdout: out }) {
402
- const [noun, name, ...extra] = opts.positional;
403
- if (!noun || !name || extra.length) throw new Error('starci app add takes `<noun> <name>` and the options of the noun');
404
- const { created, registered } = addKind({ repoRoot, noun, name, options: { event: opts.event, from: opts.from, service: opts.service, connection: opts.connection, owner: opts.owner, failed: opts.failed, done: opts.done, fe: opts.fe, shapes: opts.shapes, read: opts.read, app: opts.app, kind: opts.kind, form: opts.form, blocks: opts.blocks, tabs: opts.tabs } });
405
- for (const file of created) out(`created ${file}\n`);
406
- const kinds = registered.kinds.length ? `; kinds ${registered.kinds.join(', ')}` : '';
407
- // A noun that registers nothing in hfs.json (a table, an app, a front-end unit) ends with what it wrote.
408
- if (registered.patterns.length || registered.kinds.length) out(`starci app add ${noun}: registered patterns ${registered.patterns.join(', ')}${kinds}\n`);
409
- return 0;
525
+ const [noun, name, ...extra] = opts.positional;
526
+ if (noun !== undefined && ADD_FILE_NOUNS.includes(noun))
527
+ return addFileNoun(noun, opts, repoRoot, out);
528
+ if (opts.inject !== undefined)
529
+ throw new Error(`starci app add ${noun ?? '<noun>'} takes no --inject; only add service does`);
530
+ if (!noun || !name || extra.length)
531
+ throw new Error('starci app add takes `<noun> <name>` and the options of the noun');
532
+ const { created, registered } = addKind({ repoRoot, noun, name, options: { event: opts.event, from: opts.from, service: opts.service, connection: opts.connection, owner: opts.owner, failed: opts.failed, done: opts.done, fe: booleanFlag(opts, 'fe'), shapes: valueFlag(opts, 'shapes'), read: valueFlag(opts, 'read'), app: valueFlag(opts, 'app'), kind: valueFlag(opts, 'kind'), form: booleanFlag(opts, 'form'), blocks: valueFlag(opts, 'blocks'), tabs: valueFlag(opts, 'tabs') } });
533
+ for (const file of created)
534
+ out(`created ${file}\n`);
535
+ const kinds = registered.kinds.length ? `; kinds ${registered.kinds.join(', ')}` : '';
536
+ // A noun that registers nothing in hfs.json (a table, an app, a front-end unit) ends with what it wrote.
537
+ if (registered.patterns.length || registered.kinds.length)
538
+ out(`starci app add ${noun}: registered patterns ${registered.patterns.join(', ')}${kinds}\n`);
539
+ return 0;
410
540
  }
411
-
412
541
  async function scaffoldMain(opts, { cwd, harness, edition = 'full', presets, lock, stdout: out }) {
413
- const [name, ...extra] = opts.positional;
414
- if (!name || extra.length) throw new Error('starci app scaffold takes `<name> [--into <dir>] [--edition full|lite] [--registry-visibility public|private]`');
415
- const { root: created, files } = scaffoldApp({ name, into: path.resolve(cwd, opts.into ?? '.'), harness, edition, presets: presets ?? scaffoldPresets(), ...(opts['registry-visibility'] === undefined ? {} : { registryVisibility: opts['registry-visibility'] }), ...(lock ? { lock } : {}) });
416
- out(`starci app scaffold: created ${created} (${files.length} files); next: starci npm ci (the lockfile, then the git hooks through npm run prepare; after a raw npm ci --ignore-scripts run npm run prepare), then starci app lint\n`);
417
- return 0;
542
+ const [name, ...extra] = opts.positional;
543
+ const registryVisibility = valueFlag(opts, 'registry-visibility');
544
+ if (!name || extra.length)
545
+ throw new Error(`starci app scaffold takes \`${VERB_USAGE.scaffold[0].slice('starci app scaffold '.length)}\``);
546
+ const { root: created, files } = scaffoldApp({ name, into: path.resolve(cwd), harness, edition, presets: presets ?? scaffoldPresets(), ...(registryVisibility === undefined ? {} : { registryVisibility }), ...(lock ? { lock } : {}) });
547
+ out(`starci app scaffold: created ${created} (${files.length} files); next: npm ci (the lockfile, then the git hooks through npm run prepare; after npm ci --ignore-scripts run npm run prepare), then starci app lint\n`);
548
+ return 0;
418
549
  }
419
-
420
- function explainMain(opts, { cwd: repoRoot, stdout: out }) {
421
- if (opts.positional.length !== 1) throw new Error('starci app explain takes exactly one path');
422
- const explained = explainPath({ repoRoot, input: opts.positional[0] });
423
- if (opts.json) out(`${JSON.stringify(explained, null, 2)}\n`); else printExplain(explained, out);
424
- return explained.status === 'no-slot' || explained.status === 'ambiguous' ? 1 : 0;
550
+ function slotMain(opts, { cwd: repoRoot, stdout: out }) {
551
+ if (opts.positional.length !== 1)
552
+ throw new Error('starci app slot takes exactly one path');
553
+ const [input = ''] = opts.positional;
554
+ const explained = explainPath({ repoRoot, input });
555
+ if (opts.json)
556
+ out(`${JSON.stringify(explained, null, 2)}\n`);
557
+ else
558
+ printExplain(explained, out);
559
+ return explained.status === 'no-slot' || explained.status === 'ambiguous' ? 1 : 0;
425
560
  }
426
-
427
- async function upgradeAppMain(argv, { cwd, edition, stdout }) {
428
- await checkEdition({ repoRoot: cwd, edition, normal: () => null });
429
- return upgradeMain(['--repo', cwd, ...argv], { stdout });
561
+ function upgradeAppMain(argv, { cwd, stdout }) {
562
+ return upgradeMain(['--repo', cwd, ...argv], { stdout });
430
563
  }
431
-
432
564
  /** The edition `hfs.json` declares, or undefined when it cannot be read (the test-world verbs then decide on their own). */
433
565
  function declaredEdition(cwd) {
434
- try { return JSON.parse(fs.readFileSync(path.join(cwd, HFS_DECLARATION_FILE), 'utf8')).edition; } catch { return undefined; }
566
+ try {
567
+ return JSON.parse(fs.readFileSync(path.join(cwd, HFS_DECLARATION_FILE), 'utf8')).edition;
568
+ }
569
+ catch {
570
+ return undefined;
571
+ }
435
572
  }
436
-
437
- /**
438
- * `starci app stack`: the deploy actions (prepare, doctor, render, deploy, converge, verify, rollback, prune, backup, jobs, ...) are the Swarm
439
- * tooling of stack/cli.mjs; up, down and status are the full edition's test-world infrastructure.
440
- */
441
- async function stackAppMain(argv, { cwd, edition, stackMain, stdout: out, stderr: err, env, sops, hostIdentity, stackIo, harness }) {
442
- if (STACK_ACTIONS.includes(argv[0])) return deployStackMain(argv, { ...stackIo, cwd, stdout: out, stderr: err, env, hostIdentity, harness, ...(sops ? { sops } : {}) });
443
- if ((edition ?? declaredEdition(cwd)) === 'lite') throw new Error('starci app stack up|down|status manage the local test world of the full edition; a lite app starts its local database with npm run db:start');
444
- const run = stackMain ?? await installedStackMain(cwd);
445
- return run(argv, { cwd, out, err });
573
+ /** `starci app stack`: the deploy actions (prepare, render, deploy, converge, verify, rollback, prune, backup, jobs, ...) are the Swarm tooling of stack/cli.mjs. */
574
+ async function stackAppMain(argv, { cwd, stdout: out, stderr: err, env, sops, hostIdentity, stackIo, harness }) {
575
+ return deployStackMain(argv, { ...stackIo, cwd, stdout: out, stderr: err, env, hostIdentity, harness, ...(sops ? { sops } : {}) });
446
576
  }
447
-
448
- const DIRECT_VERBS = new Map([['ci', async (argv, io) => (await import('../ci/cli.mjs')).ciMain(argv, io)], ['lint', lintMain], ['secret', secretMain], ['db', databaseMain], ['upgrade', upgradeAppMain], ['stack', stackAppMain], ['release', releaseMain], ['coverage', async (argv, io) => (await import('../coverage/cli.mjs')).coverageMain(argv, io)], ['codemod', codemodMain]]);
449
- const PARSED_VERBS = new Map([['check', checkMain], ['emit', emitMain], ['new', newMain], ['add', addMain], ['scaffold', scaffoldMain], ['explain', explainMain]]);
450
-
577
+ /** The actions of `starci app world`: the full edition's test-world infrastructure, run by the app's installed @starci/test-world cli. */
578
+ const WORLD_ACTIONS = ['up', 'down', 'status'];
579
+ /** `starci app world <up|down|status>`: the local test world. */
580
+ async function worldAppMain(argv, { cwd, edition, stackMain, stdout: out, stderr: err }) {
581
+ if (!WORLD_ACTIONS.includes(argv[0]))
582
+ throw new Error(`starci app world takes ${WORLD_ACTIONS.join(', ')}`);
583
+ if ((edition ?? declaredEdition(cwd)) === 'lite')
584
+ throw new Error('starci app world up|down|status manage the local test world of the full edition; a lite app starts its local database with npm run db:start');
585
+ const run = stackMain ?? await installedStackMain(cwd);
586
+ return run(argv, { cwd, out, err });
587
+ }
588
+ const DIRECT_VERBS = new Map([['ci', async (argv, io) => (await import('../ci/cli.mjs')).ciMain(argv, io)], ['lint', lintMain], ['secret', secretMain], ['db', databaseMain], ['upgrade', upgradeAppMain], ['stack', stackAppMain], ['world', worldAppMain], ['release', releaseMain], ['coverage', async (argv, io) => (await import('../coverage/cli.mjs')).coverageMain(argv, io)], ['codemod', codemodMain]]);
451
589
  function dispatchMain(verb, argv, io) {
452
- if (verb === 'sync' || verb === 'hygiene') return syncMain([verb, ...argv], io);
453
- const direct = DIRECT_VERBS.get(verb);
454
- if (direct) return direct(argv, io);
455
- return PARSED_VERBS.get(verb)(parse(argv), io);
590
+ if (verb === 'sync')
591
+ return syncMain([verb, ...argv], io);
592
+ const direct = DIRECT_VERBS.get(verb);
593
+ if (direct)
594
+ return direct(argv, io);
595
+ return PARSED[verb].run(parse(verb, argv), io);
456
596
  }
457
-
458
597
  function errorMessage(error) {
459
- if (error instanceof EditionRefusal || error instanceof UpgradeError || error instanceof HfsSlotsError || error instanceof SyncError) return `${error.message}\n`;
460
- if (error instanceof ScaffoldError) return `${error.code}: ${error.message}\n`;
461
- return `starci app: ${error.message}\n${USAGE}`;
598
+ if (error instanceof EditionRefusal || error instanceof UpgradeError || error instanceof HfsSlotsError || error instanceof SyncError)
599
+ return `${error.message}\n`;
600
+ if (error instanceof ScaffoldError)
601
+ return `${error.code}: ${error.message}\n`;
602
+ return `starci app: ${error.message}\n${USAGE}`;
462
603
  }
463
-
464
604
  /**
465
605
  * `harness` ({ version }) is the CLI that runs this package in-process: its version is the starci-harness an app is judged and
466
606
  * scaffolded at (runtime/scripts/hfs/canon-pins.mjs). `run` injects the database runner, `runLinter` the linter transport, `checkApp`
467
607
  * the HFS check and `stackIo` Swarm tools; production defaults execute every check. `hostIdentity` ({ label, read }) is the
468
608
  * harness CLI's own secret.env SOPS_AGE_KEY, which every verb that opens a sealed member (secret, stack, release, db) reads last for the age identity (decryptionIdentity); `prompt` replaces its masked prompt.
469
609
  */
470
- export async function main(argv, {
471
- cwd: baseCwd = process.cwd(), harness, stdout = (s) => process.stdout.write(s), stderr = (s) => process.stderr.write(s), presets, prettier, lock, run, stackMain,
472
- env = process.env, stdin, prompt, hostIdentity, sops, tools, platform, stackIo, runLinter, checkApp,
473
- } = {}) {
474
- try {
475
- const global = globalOptions(argv, path.resolve(baseCwd));
476
- const [verb, ...rest] = global.argv;
477
- const out = global.quiet ? () => {} : stdout;
478
- if (global.help) { out(USAGE); return 0; }
479
- if (!VERBS.includes(verb)) { stderr(USAGE); return 2; }
480
- return await dispatchMain(verb, rest, { cwd: global.cwd, harness, edition: global.edition, stdout: out, stderr, presets, prettier, lock, run, stackMain, env, stdin, prompt, hostIdentity, sops, tools, platform, stackIo, runLinter, checkApp });
481
- } catch (error) {
482
- stderr(errorMessage(error));
483
- return 2;
484
- }
610
+ export async function main(argv, { cwd: baseCwd = process.cwd(), harness, stdout = (s) => process.stdout.write(s), stderr = (s) => process.stderr.write(s), presets, prettier, lock, run, stackMain, env = process.env, stdin, prompt, hostIdentity, sops, tools, platform, stackIo, runLinter, checkApp, } = {}) {
611
+ try {
612
+ const global = globalOptions(argv, path.resolve(baseCwd));
613
+ const [verb, ...given] = global.argv;
614
+ const out = global.quiet ? () => { } : stdout;
615
+ if (global.help) {
616
+ out(USAGE);
617
+ return 0;
618
+ }
619
+ if (!VERBS.includes(verb)) {
620
+ stderr(USAGE);
621
+ return 2;
622
+ }
623
+ const { edition, argv: rest } = editionOption(verb, given);
624
+ return await dispatchMain(verb, rest, { cwd: global.cwd, harness, edition, stdout: out, stderr, presets, prettier, lock, run, stackMain, env, stdin, prompt, hostIdentity, sops, tools, platform, stackIo, runLinter, checkApp });
625
+ }
626
+ catch (error) {
627
+ stderr(errorMessage(error));
628
+ return 2;
629
+ }
485
630
  }
486
-
487
631
  // Run when this file is the entry point, compared by real path. The package itself has no bin; this is useful for local diagnostics.
488
- if (isMain(import.meta.url)) process.exitCode = await main(process.argv.slice(2));
632
+ if (isMain(import.meta.url))
633
+ process.exitCode = await main(process.argv.slice(2));