@sun-asterisk/sungen 3.2.35 → 3.3.0-alpha.10

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 (969) hide show
  1. package/dist/basis/anchor-grammar.d.ts +32 -0
  2. package/dist/basis/anchor-grammar.d.ts.map +1 -0
  3. package/dist/basis/anchor-grammar.js +82 -0
  4. package/dist/basis/anchor-grammar.js.map +1 -0
  5. package/dist/basis/anchor-hash.d.ts +6 -0
  6. package/dist/basis/anchor-hash.d.ts.map +1 -0
  7. package/dist/basis/anchor-hash.js +28 -0
  8. package/dist/basis/anchor-hash.js.map +1 -0
  9. package/dist/basis/bm51-tables.d.ts +20 -0
  10. package/dist/basis/bm51-tables.d.ts.map +1 -0
  11. package/dist/basis/bm51-tables.js +71 -0
  12. package/dist/basis/bm51-tables.js.map +1 -0
  13. package/dist/basis/extract-spec-anchors.d.ts +39 -0
  14. package/dist/basis/extract-spec-anchors.d.ts.map +1 -0
  15. package/dist/basis/extract-spec-anchors.js +81 -0
  16. package/dist/basis/extract-spec-anchors.js.map +1 -0
  17. package/dist/basis/migration-sentinel.d.ts +47 -0
  18. package/dist/basis/migration-sentinel.d.ts.map +1 -0
  19. package/dist/basis/migration-sentinel.js +219 -0
  20. package/dist/basis/migration-sentinel.js.map +1 -0
  21. package/dist/basis/spec-frontmatter.d.ts +18 -0
  22. package/dist/basis/spec-frontmatter.d.ts.map +1 -0
  23. package/dist/basis/spec-frontmatter.js +55 -0
  24. package/dist/basis/spec-frontmatter.js.map +1 -0
  25. package/dist/basis/spec-sections.d.ts +18 -0
  26. package/dist/basis/spec-sections.d.ts.map +1 -0
  27. package/dist/basis/spec-sections.js +27 -0
  28. package/dist/basis/spec-sections.js.map +1 -0
  29. package/dist/basis/test-basis-schema.d.ts +28 -0
  30. package/dist/basis/test-basis-schema.d.ts.map +1 -0
  31. package/dist/basis/test-basis-schema.js +141 -0
  32. package/dist/basis/test-basis-schema.js.map +1 -0
  33. package/dist/capabilities/discover.d.ts +4 -0
  34. package/dist/capabilities/discover.d.ts.map +1 -1
  35. package/dist/capabilities/discover.js +16 -2
  36. package/dist/capabilities/discover.js.map +1 -1
  37. package/dist/capabilities/registry.d.ts +15 -0
  38. package/dist/capabilities/registry.d.ts.map +1 -1
  39. package/dist/capabilities/registry.js.map +1 -1
  40. package/dist/cli/case-triage-hint.d.ts +14 -0
  41. package/dist/cli/case-triage-hint.d.ts.map +1 -0
  42. package/dist/cli/case-triage-hint.js +23 -0
  43. package/dist/cli/case-triage-hint.js.map +1 -0
  44. package/dist/cli/commands/audit.js +1 -1
  45. package/dist/cli/commands/audit.js.map +1 -1
  46. package/dist/cli/commands/capability.js +1 -1
  47. package/dist/cli/commands/capability.js.map +1 -1
  48. package/dist/cli/commands/contract-derive-command.d.ts +12 -0
  49. package/dist/cli/commands/contract-derive-command.d.ts.map +1 -0
  50. package/dist/cli/commands/contract-derive-command.js +113 -0
  51. package/dist/cli/commands/contract-derive-command.js.map +1 -0
  52. package/dist/cli/commands/contract.d.ts +20 -0
  53. package/dist/cli/commands/contract.d.ts.map +1 -0
  54. package/dist/cli/commands/contract.js +195 -0
  55. package/dist/cli/commands/contract.js.map +1 -0
  56. package/dist/cli/commands/delivery.d.ts.map +1 -1
  57. package/dist/cli/commands/delivery.js +109 -19
  58. package/dist/cli/commands/delivery.js.map +1 -1
  59. package/dist/cli/commands/gate.d.ts.map +1 -1
  60. package/dist/cli/commands/gate.js +2 -1
  61. package/dist/cli/commands/gate.js.map +1 -1
  62. package/dist/cli/commands/generate.d.ts.map +1 -1
  63. package/dist/cli/commands/generate.js +17 -3
  64. package/dist/cli/commands/generate.js.map +1 -1
  65. package/dist/cli/commands/journey.d.ts.map +1 -1
  66. package/dist/cli/commands/journey.js +47 -17
  67. package/dist/cli/commands/journey.js.map +1 -1
  68. package/dist/cli/commands/next.d.ts +13 -0
  69. package/dist/cli/commands/next.d.ts.map +1 -1
  70. package/dist/cli/commands/next.js +98 -9
  71. package/dist/cli/commands/next.js.map +1 -1
  72. package/dist/cli/commands/triage.d.ts +2 -1
  73. package/dist/cli/commands/triage.d.ts.map +1 -1
  74. package/dist/cli/commands/triage.js +45 -3
  75. package/dist/cli/commands/triage.js.map +1 -1
  76. package/dist/cli/commands/update.d.ts +11 -0
  77. package/dist/cli/commands/update.d.ts.map +1 -1
  78. package/dist/cli/commands/update.js +37 -8
  79. package/dist/cli/commands/update.js.map +1 -1
  80. package/dist/cli/index.js +24 -33
  81. package/dist/cli/index.js.map +1 -1
  82. package/dist/cli/json-error-on-exit.d.ts +34 -0
  83. package/dist/cli/json-error-on-exit.d.ts.map +1 -0
  84. package/dist/cli/json-error-on-exit.js +63 -0
  85. package/dist/cli/json-error-on-exit.js.map +1 -0
  86. package/dist/cli/project-sungen-invocation.d.ts +13 -0
  87. package/dist/cli/project-sungen-invocation.d.ts.map +1 -0
  88. package/dist/cli/project-sungen-invocation.js +95 -0
  89. package/dist/cli/project-sungen-invocation.js.map +1 -0
  90. package/dist/cli/run-command-hints.d.ts +9 -0
  91. package/dist/cli/run-command-hints.d.ts.map +1 -0
  92. package/dist/cli/run-command-hints.js +84 -0
  93. package/dist/cli/run-command-hints.js.map +1 -0
  94. package/dist/cli/waiting-for-you-block.d.ts +18 -0
  95. package/dist/cli/waiting-for-you-block.d.ts.map +1 -0
  96. package/dist/cli/waiting-for-you-block.js +22 -0
  97. package/dist/cli/waiting-for-you-block.js.map +1 -0
  98. package/dist/contract/accept-opaque-steps.d.ts +3 -0
  99. package/dist/contract/accept-opaque-steps.d.ts.map +1 -0
  100. package/dist/contract/accept-opaque-steps.js +114 -0
  101. package/dist/contract/accept-opaque-steps.js.map +1 -0
  102. package/dist/contract/approve-contract.d.ts +38 -0
  103. package/dist/contract/approve-contract.d.ts.map +1 -0
  104. package/dist/contract/approve-contract.js +93 -0
  105. package/dist/contract/approve-contract.js.map +1 -0
  106. package/dist/contract/assertion-matcher-vocabulary.d.ts +24 -0
  107. package/dist/contract/assertion-matcher-vocabulary.d.ts.map +1 -0
  108. package/dist/contract/assertion-matcher-vocabulary.js +100 -0
  109. package/dist/contract/assertion-matcher-vocabulary.js.map +1 -0
  110. package/dist/contract/build-contract-verdict.d.ts +32 -0
  111. package/dist/contract/build-contract-verdict.d.ts.map +1 -0
  112. package/dist/contract/build-contract-verdict.js +123 -0
  113. package/dist/contract/build-contract-verdict.js.map +1 -0
  114. package/dist/contract/build-trace-conformance.d.ts +22 -0
  115. package/dist/contract/build-trace-conformance.d.ts.map +1 -0
  116. package/dist/contract/build-trace-conformance.js +151 -0
  117. package/dist/contract/build-trace-conformance.js.map +1 -0
  118. package/dist/contract/classify-contract-change.d.ts +24 -0
  119. package/dist/contract/classify-contract-change.d.ts.map +1 -0
  120. package/dist/contract/classify-contract-change.js +98 -0
  121. package/dist/contract/classify-contract-change.js.map +1 -0
  122. package/dist/contract/classify-contract-unit.d.ts +18 -0
  123. package/dist/contract/classify-contract-unit.d.ts.map +1 -0
  124. package/dist/contract/classify-contract-unit.js +49 -0
  125. package/dist/contract/classify-contract-unit.js.map +1 -0
  126. package/dist/contract/classify-trace-conformance.d.ts +47 -0
  127. package/dist/contract/classify-trace-conformance.d.ts.map +1 -0
  128. package/dist/contract/classify-trace-conformance.js +164 -0
  129. package/dist/contract/classify-trace-conformance.js.map +1 -0
  130. package/dist/contract/contract-git.d.ts +24 -0
  131. package/dist/contract/contract-git.d.ts.map +1 -0
  132. package/dist/contract/contract-git.js +144 -0
  133. package/dist/contract/contract-git.js.map +1 -0
  134. package/dist/contract/contract-hash.d.ts +7 -0
  135. package/dist/contract/contract-hash.d.ts.map +1 -0
  136. package/dist/contract/contract-hash.js +38 -0
  137. package/dist/contract/contract-hash.js.map +1 -0
  138. package/dist/contract/contract-report-file.d.ts +4 -0
  139. package/dist/contract/contract-report-file.d.ts.map +1 -0
  140. package/dist/contract/contract-report-file.js +60 -0
  141. package/dist/contract/contract-report-file.js.map +1 -0
  142. package/dist/contract/contract-schema.d.ts +92 -0
  143. package/dist/contract/contract-schema.d.ts.map +1 -0
  144. package/dist/contract/contract-schema.js +124 -0
  145. package/dist/contract/contract-schema.js.map +1 -0
  146. package/dist/contract/contract-units.d.ts +12 -0
  147. package/dist/contract/contract-units.d.ts.map +1 -0
  148. package/dist/contract/contract-units.js +96 -0
  149. package/dist/contract/contract-units.js.map +1 -0
  150. package/dist/contract/contracts-lock-file.d.ts +24 -0
  151. package/dist/contract/contracts-lock-file.d.ts.map +1 -0
  152. package/dist/contract/contracts-lock-file.js +141 -0
  153. package/dist/contract/contracts-lock-file.js.map +1 -0
  154. package/dist/contract/data-normalize.d.ts +10 -0
  155. package/dist/contract/data-normalize.d.ts.map +1 -0
  156. package/dist/contract/data-normalize.js +110 -0
  157. package/dist/contract/data-normalize.js.map +1 -0
  158. package/dist/contract/derive-free-feature.d.ts +49 -0
  159. package/dist/contract/derive-free-feature.d.ts.map +1 -0
  160. package/dist/contract/derive-free-feature.js +183 -0
  161. package/dist/contract/derive-free-feature.js.map +1 -0
  162. package/dist/contract/field-semantic-redaction.d.ts +21 -0
  163. package/dist/contract/field-semantic-redaction.d.ts.map +1 -0
  164. package/dist/contract/field-semantic-redaction.js +118 -0
  165. package/dist/contract/field-semantic-redaction.js.map +1 -0
  166. package/dist/contract/free-feature-blocks.d.ts +10 -0
  167. package/dist/contract/free-feature-blocks.d.ts.map +1 -0
  168. package/dist/contract/free-feature-blocks.js +94 -0
  169. package/dist/contract/free-feature-blocks.js.map +1 -0
  170. package/dist/contract/lock-secret-guard.d.ts +22 -0
  171. package/dist/contract/lock-secret-guard.d.ts.map +1 -0
  172. package/dist/contract/lock-secret-guard.js +134 -0
  173. package/dist/contract/lock-secret-guard.js.map +1 -0
  174. package/dist/contract/lock-vs-git-head.d.ts +26 -0
  175. package/dist/contract/lock-vs-git-head.d.ts.map +1 -0
  176. package/dist/contract/lock-vs-git-head.js +28 -0
  177. package/dist/contract/lock-vs-git-head.js.map +1 -0
  178. package/dist/contract/normalize-contract-step.d.ts +21 -0
  179. package/dist/contract/normalize-contract-step.d.ts.map +1 -0
  180. package/dist/contract/normalize-contract-step.js +70 -0
  181. package/dist/contract/normalize-contract-step.js.map +1 -0
  182. package/dist/contract/normalize-feature-steps.d.ts +7 -0
  183. package/dist/contract/normalize-feature-steps.d.ts.map +1 -0
  184. package/dist/contract/normalize-feature-steps.js +127 -0
  185. package/dist/contract/normalize-feature-steps.js.map +1 -0
  186. package/dist/contract/oracle-strength.d.ts +12 -0
  187. package/dist/contract/oracle-strength.d.ts.map +1 -0
  188. package/dist/contract/oracle-strength.js +88 -0
  189. package/dist/contract/oracle-strength.js.map +1 -0
  190. package/dist/contract/project-contract-blockers.d.ts +10 -0
  191. package/dist/contract/project-contract-blockers.d.ts.map +1 -0
  192. package/dist/contract/project-contract-blockers.js +75 -0
  193. package/dist/contract/project-contract-blockers.js.map +1 -0
  194. package/dist/contract/record-contract-approval.d.ts +36 -0
  195. package/dist/contract/record-contract-approval.d.ts.map +1 -0
  196. package/dist/contract/record-contract-approval.js +126 -0
  197. package/dist/contract/record-contract-approval.js.map +1 -0
  198. package/dist/contract/render-free-gherkin.d.ts +42 -0
  199. package/dist/contract/render-free-gherkin.d.ts.map +1 -0
  200. package/dist/contract/render-free-gherkin.js +147 -0
  201. package/dist/contract/render-free-gherkin.js.map +1 -0
  202. package/dist/contract/render-trace-sentence.d.ts +20 -0
  203. package/dist/contract/render-trace-sentence.d.ts.map +1 -0
  204. package/dist/contract/render-trace-sentence.js +109 -0
  205. package/dist/contract/render-trace-sentence.js.map +1 -0
  206. package/dist/contract/render-trace-target.d.ts +14 -0
  207. package/dist/contract/render-trace-target.d.ts.map +1 -0
  208. package/dist/contract/render-trace-target.js +70 -0
  209. package/dist/contract/render-trace-target.js.map +1 -0
  210. package/dist/contract/resolve-unit-trace-identities.d.ts +20 -0
  211. package/dist/contract/resolve-unit-trace-identities.d.ts.map +1 -0
  212. package/dist/contract/resolve-unit-trace-identities.js +62 -0
  213. package/dist/contract/resolve-unit-trace-identities.js.map +1 -0
  214. package/dist/contract/trace/collect-trace-evidence.d.ts +44 -0
  215. package/dist/contract/trace/collect-trace-evidence.d.ts.map +1 -0
  216. package/dist/contract/trace/collect-trace-evidence.js +219 -0
  217. package/dist/contract/trace/collect-trace-evidence.js.map +1 -0
  218. package/dist/contract/trace/identity-cache.d.ts +19 -0
  219. package/dist/contract/trace/identity-cache.d.ts.map +1 -0
  220. package/dist/contract/trace/identity-cache.js +104 -0
  221. package/dist/contract/trace/identity-cache.js.map +1 -0
  222. package/dist/contract/trace/read-file-once.d.ts +20 -0
  223. package/dist/contract/trace/read-file-once.d.ts.map +1 -0
  224. package/dist/contract/trace/read-file-once.js +135 -0
  225. package/dist/contract/trace/read-file-once.js.map +1 -0
  226. package/dist/contract/trace/scenario-id-claims.d.ts +11 -0
  227. package/dist/contract/trace/scenario-id-claims.d.ts.map +1 -0
  228. package/dist/contract/trace/scenario-id-claims.js +89 -0
  229. package/dist/contract/trace/scenario-id-claims.js.map +1 -0
  230. package/dist/contract/trace/select-final-attempt.d.ts +29 -0
  231. package/dist/contract/trace/select-final-attempt.d.ts.map +1 -0
  232. package/dist/contract/trace/select-final-attempt.js +119 -0
  233. package/dist/contract/trace/select-final-attempt.js.map +1 -0
  234. package/dist/contract/trace/snapshot-html-renderer.d.ts +31 -0
  235. package/dist/contract/trace/snapshot-html-renderer.d.ts.map +1 -0
  236. package/dist/contract/trace/snapshot-html-renderer.js +172 -0
  237. package/dist/contract/trace/snapshot-html-renderer.js.map +1 -0
  238. package/dist/contract/trace/snapshot-resolver.d.ts +21 -0
  239. package/dist/contract/trace/snapshot-resolver.d.ts.map +1 -0
  240. package/dist/contract/trace/snapshot-resolver.js +65 -0
  241. package/dist/contract/trace/snapshot-resolver.js.map +1 -0
  242. package/dist/contract/trace/snapshot-store.d.ts +66 -0
  243. package/dist/contract/trace/snapshot-store.d.ts.map +1 -0
  244. package/dist/contract/trace/snapshot-store.js +173 -0
  245. package/dist/contract/trace/snapshot-store.js.map +1 -0
  246. package/dist/contract/trace/target-identity.d.ts +74 -0
  247. package/dist/contract/trace/target-identity.d.ts.map +1 -0
  248. package/dist/contract/trace/target-identity.js +68 -0
  249. package/dist/contract/trace/target-identity.js.map +1 -0
  250. package/dist/contract/trace/test-step-join.d.ts +65 -0
  251. package/dist/contract/trace/test-step-join.d.ts.map +1 -0
  252. package/dist/contract/trace/test-step-join.js +80 -0
  253. package/dist/contract/trace/test-step-join.js.map +1 -0
  254. package/dist/contract/trace/trace-binding.d.ts +22 -0
  255. package/dist/contract/trace/trace-binding.d.ts.map +1 -0
  256. package/dist/contract/trace/trace-binding.js +91 -0
  257. package/dist/contract/trace/trace-binding.js.map +1 -0
  258. package/dist/contract/trace/trace-file-reader.d.ts +47 -0
  259. package/dist/contract/trace/trace-file-reader.d.ts.map +1 -0
  260. package/dist/contract/trace/trace-file-reader.js +137 -0
  261. package/dist/contract/trace/trace-file-reader.js.map +1 -0
  262. package/dist/contract/trace/trace-fingerprint.d.ts +22 -0
  263. package/dist/contract/trace/trace-fingerprint.d.ts.map +1 -0
  264. package/dist/contract/trace/trace-fingerprint.js +96 -0
  265. package/dist/contract/trace/trace-fingerprint.js.map +1 -0
  266. package/dist/contract/trace/trace-freshness.d.ts +27 -0
  267. package/dist/contract/trace/trace-freshness.d.ts.map +1 -0
  268. package/dist/contract/trace/trace-freshness.js +146 -0
  269. package/dist/contract/trace/trace-freshness.js.map +1 -0
  270. package/dist/contract/trace/trace-identity-resolution.d.ts +28 -0
  271. package/dist/contract/trace/trace-identity-resolution.d.ts.map +1 -0
  272. package/dist/contract/trace/trace-identity-resolution.js +87 -0
  273. package/dist/contract/trace/trace-identity-resolution.js.map +1 -0
  274. package/dist/contract/trace/trace-run-record.d.ts +32 -0
  275. package/dist/contract/trace/trace-run-record.d.ts.map +1 -0
  276. package/dist/contract/trace/trace-run-record.js +135 -0
  277. package/dist/contract/trace/trace-run-record.js.map +1 -0
  278. package/dist/contract/trace/trace-steps.d.ts +19 -0
  279. package/dist/contract/trace/trace-steps.d.ts.map +1 -0
  280. package/dist/contract/trace/trace-steps.js +79 -0
  281. package/dist/contract/trace/trace-steps.js.map +1 -0
  282. package/dist/contract/trace/trace-zip-limits.d.ts +45 -0
  283. package/dist/contract/trace/trace-zip-limits.d.ts.map +1 -0
  284. package/dist/contract/trace/trace-zip-limits.js +52 -0
  285. package/dist/contract/trace/trace-zip-limits.js.map +1 -0
  286. package/dist/contract/trace/trace-zip-reader.d.ts +10 -0
  287. package/dist/contract/trace/trace-zip-reader.d.ts.map +1 -0
  288. package/dist/contract/trace/trace-zip-reader.js +186 -0
  289. package/dist/contract/trace/trace-zip-reader.js.map +1 -0
  290. package/dist/contract/verify-approval-decisions.d.ts +5 -0
  291. package/dist/contract/verify-approval-decisions.d.ts.map +1 -0
  292. package/dist/contract/verify-approval-decisions.js +109 -0
  293. package/dist/contract/verify-approval-decisions.js.map +1 -0
  294. package/dist/decisions/append-decision.d.ts +12 -0
  295. package/dist/decisions/append-decision.d.ts.map +1 -0
  296. package/dist/decisions/append-decision.js +73 -0
  297. package/dist/decisions/append-decision.js.map +1 -0
  298. package/dist/decisions/confirmed-decision-commands.d.ts +41 -0
  299. package/dist/decisions/confirmed-decision-commands.d.ts.map +1 -0
  300. package/dist/decisions/confirmed-decision-commands.js +190 -0
  301. package/dist/decisions/confirmed-decision-commands.js.map +1 -0
  302. package/dist/decisions/decision-file.d.ts +31 -0
  303. package/dist/decisions/decision-file.d.ts.map +1 -0
  304. package/dist/decisions/decision-file.js +139 -0
  305. package/dist/decisions/decision-file.js.map +1 -0
  306. package/dist/decisions/decision-identity.d.ts +12 -0
  307. package/dist/decisions/decision-identity.d.ts.map +1 -0
  308. package/dist/decisions/decision-identity.js +78 -0
  309. package/dist/decisions/decision-identity.js.map +1 -0
  310. package/dist/decisions/decision-integrity-check.d.ts +12 -0
  311. package/dist/decisions/decision-integrity-check.d.ts.map +1 -0
  312. package/dist/decisions/decision-integrity-check.js +102 -0
  313. package/dist/decisions/decision-integrity-check.js.map +1 -0
  314. package/dist/decisions/decision-schema.d.ts +43 -0
  315. package/dist/decisions/decision-schema.d.ts.map +1 -0
  316. package/dist/decisions/decision-schema.js +76 -0
  317. package/dist/decisions/decision-schema.js.map +1 -0
  318. package/dist/decisions/decision-source.d.ts +2 -0
  319. package/dist/decisions/decision-source.d.ts.map +1 -0
  320. package/dist/decisions/decision-source.js +18 -0
  321. package/dist/decisions/decision-source.js.map +1 -0
  322. package/dist/decisions/exclusive-file-create.d.ts +3 -0
  323. package/dist/decisions/exclusive-file-create.d.ts.map +1 -0
  324. package/dist/decisions/exclusive-file-create.js +84 -0
  325. package/dist/decisions/exclusive-file-create.js.map +1 -0
  326. package/dist/decisions/git-head-trust.d.ts +19 -0
  327. package/dist/decisions/git-head-trust.d.ts.map +1 -0
  328. package/dist/decisions/git-head-trust.js +128 -0
  329. package/dist/decisions/git-head-trust.js.map +1 -0
  330. package/dist/decisions/human-confirmation.d.ts +35 -0
  331. package/dist/decisions/human-confirmation.d.ts.map +1 -0
  332. package/dist/decisions/human-confirmation.js +161 -0
  333. package/dist/decisions/human-confirmation.js.map +1 -0
  334. package/dist/decisions/legacy-waiver-migration.d.ts +38 -0
  335. package/dist/decisions/legacy-waiver-migration.d.ts.map +1 -0
  336. package/dist/decisions/legacy-waiver-migration.js +179 -0
  337. package/dist/decisions/legacy-waiver-migration.js.map +1 -0
  338. package/dist/decisions/read-decisions.d.ts +19 -0
  339. package/dist/decisions/read-decisions.d.ts.map +1 -0
  340. package/dist/decisions/read-decisions.js +90 -0
  341. package/dist/decisions/read-decisions.js.map +1 -0
  342. package/dist/decisions/viewpoint-baseline-adapter.d.ts +7 -0
  343. package/dist/decisions/viewpoint-baseline-adapter.d.ts.map +1 -0
  344. package/dist/decisions/viewpoint-baseline-adapter.js +109 -0
  345. package/dist/decisions/viewpoint-baseline-adapter.js.map +1 -0
  346. package/dist/decisions/waiver-decisions.d.ts +24 -0
  347. package/dist/decisions/waiver-decisions.d.ts.map +1 -0
  348. package/dist/decisions/waiver-decisions.js +46 -0
  349. package/dist/decisions/waiver-decisions.js.map +1 -0
  350. package/dist/exporters/csv-exporter.d.ts +11 -2
  351. package/dist/exporters/csv-exporter.d.ts.map +1 -1
  352. package/dist/exporters/csv-exporter.js +8 -4
  353. package/dist/exporters/csv-exporter.js.map +1 -1
  354. package/dist/exporters/matrix/build.d.ts +3 -0
  355. package/dist/exporters/matrix/build.d.ts.map +1 -1
  356. package/dist/exporters/matrix/build.js +10 -9
  357. package/dist/exporters/matrix/build.js.map +1 -1
  358. package/dist/exporters/matrix/export.d.ts +9 -1
  359. package/dist/exporters/matrix/export.d.ts.map +1 -1
  360. package/dist/exporters/matrix/export.js +13 -4
  361. package/dist/exporters/matrix/export.js.map +1 -1
  362. package/dist/exporters/matrix/gates.d.ts +6 -1
  363. package/dist/exporters/matrix/gates.d.ts.map +1 -1
  364. package/dist/exporters/matrix/gates.js +57 -128
  365. package/dist/exporters/matrix/gates.js.map +1 -1
  366. package/dist/exporters/matrix/render-csv.d.ts.map +1 -1
  367. package/dist/exporters/matrix/render-csv.js +3 -0
  368. package/dist/exporters/matrix/render-csv.js.map +1 -1
  369. package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts +13 -0
  370. package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts.map +1 -0
  371. package/dist/exporters/matrix/render-gate-overrides-sheet.js +44 -0
  372. package/dist/exporters/matrix/render-gate-overrides-sheet.js.map +1 -0
  373. package/dist/exporters/matrix/render-xlsx.d.ts +1 -0
  374. package/dist/exporters/matrix/render-xlsx.d.ts.map +1 -1
  375. package/dist/exporters/matrix/render-xlsx.js +3 -0
  376. package/dist/exporters/matrix/render-xlsx.js.map +1 -1
  377. package/dist/exporters/matrix/types.d.ts +4 -1
  378. package/dist/exporters/matrix/types.d.ts.map +1 -1
  379. package/dist/exporters/matrix/types.js.map +1 -1
  380. package/dist/exporters/matrix/xlsx-cells.js +1 -1
  381. package/dist/exporters/matrix/xlsx-cells.js.map +1 -1
  382. package/dist/exporters/test-data-resolver.d.ts.map +1 -1
  383. package/dist/exporters/test-data-resolver.js +2 -12
  384. package/dist/exporters/test-data-resolver.js.map +1 -1
  385. package/dist/exporters/xlsx-exporter.d.ts +3 -2
  386. package/dist/exporters/xlsx-exporter.d.ts.map +1 -1
  387. package/dist/exporters/xlsx-exporter.js +4 -4
  388. package/dist/exporters/xlsx-exporter.js.map +1 -1
  389. package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
  390. package/dist/generators/gherkin-parser/index.js +0 -1
  391. package/dist/generators/gherkin-parser/index.js.map +1 -1
  392. package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/contain-text-assertion.hbs +1 -2
  393. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/fill-action.hbs +1 -13
  394. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +1 -9
  395. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  396. package/dist/generators/test-generator/code-generator.js +18 -4
  397. package/dist/generators/test-generator/code-generator.js.map +1 -1
  398. package/dist/generators/test-generator/diagnostics.d.ts +3 -9
  399. package/dist/generators/test-generator/diagnostics.d.ts.map +1 -1
  400. package/dist/generators/test-generator/diagnostics.js +3 -9
  401. package/dist/generators/test-generator/diagnostics.js.map +1 -1
  402. package/dist/generators/test-generator/patterns/types.d.ts +1 -1
  403. package/dist/generators/test-generator/patterns/types.d.ts.map +1 -1
  404. package/dist/generators/test-generator/step-mapper.d.ts +0 -8
  405. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
  406. package/dist/generators/test-generator/step-mapper.js +8 -52
  407. package/dist/generators/test-generator/step-mapper.js.map +1 -1
  408. package/dist/generators/test-generator/utils/data-resolver.d.ts +0 -16
  409. package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
  410. package/dist/generators/test-generator/utils/data-resolver.js +0 -59
  411. package/dist/generators/test-generator/utils/data-resolver.js.map +1 -1
  412. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
  413. package/dist/generators/test-generator/utils/selector-resolver.js +2 -10
  414. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
  415. package/dist/graph/board-human-actions.d.ts +5 -0
  416. package/dist/graph/board-human-actions.d.ts.map +1 -0
  417. package/dist/graph/board-human-actions.js +83 -0
  418. package/dist/graph/board-human-actions.js.map +1 -0
  419. package/dist/graph/evaluate-graph.d.ts +41 -0
  420. package/dist/graph/evaluate-graph.d.ts.map +1 -0
  421. package/dist/graph/evaluate-graph.js +77 -0
  422. package/dist/graph/evaluate-graph.js.map +1 -0
  423. package/dist/graph/human-action.d.ts +21 -0
  424. package/dist/graph/human-action.d.ts.map +1 -0
  425. package/dist/graph/human-action.js +3 -0
  426. package/dist/graph/human-action.js.map +1 -0
  427. package/dist/graph/locate-finding.d.ts +20 -0
  428. package/dist/graph/locate-finding.d.ts.map +1 -0
  429. package/dist/graph/locate-finding.js +137 -0
  430. package/dist/graph/locate-finding.js.map +1 -0
  431. package/dist/graph/manual-triage-decisions.d.ts +19 -0
  432. package/dist/graph/manual-triage-decisions.d.ts.map +1 -0
  433. package/dist/graph/manual-triage-decisions.js +53 -0
  434. package/dist/graph/manual-triage-decisions.js.map +1 -0
  435. package/dist/graph/node-decl.d.ts +75 -0
  436. package/dist/graph/node-decl.d.ts.map +1 -0
  437. package/dist/graph/node-decl.js +11 -0
  438. package/dist/graph/node-decl.js.map +1 -0
  439. package/dist/graph/nodes/core-node-catalog.d.ts +7 -0
  440. package/dist/graph/nodes/core-node-catalog.d.ts.map +1 -0
  441. package/dist/graph/nodes/core-node-catalog.js +13 -0
  442. package/dist/graph/nodes/core-node-catalog.js.map +1 -0
  443. package/dist/graph/nodes/test-case-contract-nodes.d.ts +21 -0
  444. package/dist/graph/nodes/test-case-contract-nodes.d.ts.map +1 -0
  445. package/dist/graph/nodes/test-case-contract-nodes.js +72 -0
  446. package/dist/graph/nodes/test-case-contract-nodes.js.map +1 -0
  447. package/dist/graph/nodes/test-case-nodes.d.ts +29 -0
  448. package/dist/graph/nodes/test-case-nodes.d.ts.map +1 -0
  449. package/dist/graph/nodes/test-case-nodes.js +95 -0
  450. package/dist/graph/nodes/test-case-nodes.js.map +1 -0
  451. package/dist/graph/nodes/unit-audit-nodes.d.ts +18 -0
  452. package/dist/graph/nodes/unit-audit-nodes.d.ts.map +1 -0
  453. package/dist/graph/nodes/unit-audit-nodes.js +96 -0
  454. package/dist/graph/nodes/unit-audit-nodes.js.map +1 -0
  455. package/dist/graph/nodes/unit-contract-node.d.ts +21 -0
  456. package/dist/graph/nodes/unit-contract-node.d.ts.map +1 -0
  457. package/dist/graph/nodes/unit-contract-node.js +96 -0
  458. package/dist/graph/nodes/unit-contract-node.js.map +1 -0
  459. package/dist/graph/nodes/unit-design-nodes.d.ts +14 -0
  460. package/dist/graph/nodes/unit-design-nodes.d.ts.map +1 -0
  461. package/dist/graph/nodes/unit-design-nodes.js +91 -0
  462. package/dist/graph/nodes/unit-design-nodes.js.map +1 -0
  463. package/dist/graph/nodes/unit-execution-nodes.d.ts +16 -0
  464. package/dist/graph/nodes/unit-execution-nodes.d.ts.map +1 -0
  465. package/dist/graph/nodes/unit-execution-nodes.js +79 -0
  466. package/dist/graph/nodes/unit-execution-nodes.js.map +1 -0
  467. package/dist/graph/test-case-identity.d.ts +13 -0
  468. package/dist/graph/test-case-identity.d.ts.map +1 -0
  469. package/dist/graph/test-case-identity.js +106 -0
  470. package/dist/graph/test-case-identity.js.map +1 -0
  471. package/dist/graph/test-case-results.d.ts +12 -0
  472. package/dist/graph/test-case-results.d.ts.map +1 -0
  473. package/dist/graph/test-case-results.js +161 -0
  474. package/dist/graph/test-case-results.js.map +1 -0
  475. package/dist/graph/test-case-satisfied.d.ts +26 -0
  476. package/dist/graph/test-case-satisfied.d.ts.map +1 -0
  477. package/dist/graph/test-case-satisfied.js +55 -0
  478. package/dist/graph/test-case-satisfied.js.map +1 -0
  479. package/dist/graph/test-case-state-shape.d.ts +73 -0
  480. package/dist/graph/test-case-state-shape.d.ts.map +1 -0
  481. package/dist/graph/test-case-state-shape.js +3 -0
  482. package/dist/graph/test-case-state-shape.js.map +1 -0
  483. package/dist/graph/test-case-states.d.ts +9 -0
  484. package/dist/graph/test-case-states.d.ts.map +1 -0
  485. package/dist/graph/test-case-states.js +116 -0
  486. package/dist/graph/test-case-states.js.map +1 -0
  487. package/dist/graph/unit-artifact-probes.d.ts +19 -0
  488. package/dist/graph/unit-artifact-probes.d.ts.map +1 -0
  489. package/dist/graph/unit-artifact-probes.js +135 -0
  490. package/dist/graph/unit-artifact-probes.js.map +1 -0
  491. package/dist/graph/unit-results-freshness.d.ts +29 -0
  492. package/dist/graph/unit-results-freshness.d.ts.map +1 -0
  493. package/dist/graph/unit-results-freshness.js +213 -0
  494. package/dist/graph/unit-results-freshness.js.map +1 -0
  495. package/dist/graph/unit-state-facts.d.ts +43 -0
  496. package/dist/graph/unit-state-facts.d.ts.map +1 -0
  497. package/dist/graph/unit-state-facts.js +87 -0
  498. package/dist/graph/unit-state-facts.js.map +1 -0
  499. package/dist/harness/audit.d.ts +14 -2
  500. package/dist/harness/audit.d.ts.map +1 -1
  501. package/dist/harness/audit.js +20 -21
  502. package/dist/harness/audit.js.map +1 -1
  503. package/dist/harness/catalog/gate-rules.yaml +647 -0
  504. package/dist/harness/defect-draft.d.ts.map +1 -1
  505. package/dist/harness/defect-draft.js +12 -2
  506. package/dist/harness/defect-draft.js.map +1 -1
  507. package/dist/harness/defects.d.ts +14 -0
  508. package/dist/harness/defects.d.ts.map +1 -1
  509. package/dist/harness/defects.js +14 -10
  510. package/dist/harness/defects.js.map +1 -1
  511. package/dist/harness/flow-check.d.ts +9 -0
  512. package/dist/harness/flow-check.d.ts.map +1 -1
  513. package/dist/harness/flow-check.js +11 -0
  514. package/dist/harness/flow-check.js.map +1 -1
  515. package/dist/harness/gates/audit-gate-terms.d.ts +41 -0
  516. package/dist/harness/gates/audit-gate-terms.d.ts.map +1 -0
  517. package/dist/harness/gates/audit-gate-terms.js +72 -0
  518. package/dist/harness/gates/audit-gate-terms.js.map +1 -0
  519. package/dist/harness/gates/audit-gate-verdict.d.ts +31 -0
  520. package/dist/harness/gates/audit-gate-verdict.d.ts.map +1 -0
  521. package/dist/harness/gates/audit-gate-verdict.js +102 -0
  522. package/dist/harness/gates/audit-gate-verdict.js.map +1 -0
  523. package/dist/harness/gates/audit-input-hash.d.ts +6 -0
  524. package/dist/harness/gates/audit-input-hash.d.ts.map +1 -0
  525. package/dist/harness/gates/audit-input-hash.js +124 -0
  526. package/dist/harness/gates/audit-input-hash.js.map +1 -0
  527. package/dist/harness/gates/audit-report-verification.d.ts +43 -0
  528. package/dist/harness/gates/audit-report-verification.d.ts.map +1 -0
  529. package/dist/harness/gates/audit-report-verification.js +241 -0
  530. package/dist/harness/gates/audit-report-verification.js.map +1 -0
  531. package/dist/harness/gates/decisions-hash.d.ts +13 -0
  532. package/dist/harness/gates/decisions-hash.d.ts.map +1 -0
  533. package/dist/harness/gates/decisions-hash.js +72 -0
  534. package/dist/harness/gates/decisions-hash.js.map +1 -0
  535. package/dist/harness/gates/delivery-checklist.d.ts +24 -0
  536. package/dist/harness/gates/delivery-checklist.d.ts.map +1 -0
  537. package/dist/harness/gates/delivery-checklist.js +161 -0
  538. package/dist/harness/gates/delivery-checklist.js.map +1 -0
  539. package/dist/harness/gates/delivery-decision-gate.d.ts +33 -0
  540. package/dist/harness/gates/delivery-decision-gate.d.ts.map +1 -0
  541. package/dist/harness/gates/delivery-decision-gate.js +116 -0
  542. package/dist/harness/gates/delivery-decision-gate.js.map +1 -0
  543. package/dist/harness/gates/delivery-decision-step.d.ts +19 -0
  544. package/dist/harness/gates/delivery-decision-step.d.ts.map +1 -0
  545. package/dist/harness/gates/delivery-decision-step.js +86 -0
  546. package/dist/harness/gates/delivery-decision-step.js.map +1 -0
  547. package/dist/harness/gates/gate-override-report.d.ts +59 -0
  548. package/dist/harness/gates/gate-override-report.d.ts.map +1 -0
  549. package/dist/harness/gates/gate-override-report.js +86 -0
  550. package/dist/harness/gates/gate-override-report.js.map +1 -0
  551. package/dist/harness/gates/gate-override-scope.d.ts +18 -0
  552. package/dist/harness/gates/gate-override-scope.d.ts.map +1 -0
  553. package/dist/harness/gates/gate-override-scope.js +98 -0
  554. package/dist/harness/gates/gate-override-scope.js.map +1 -0
  555. package/dist/harness/gates/gate-override-validation.d.ts +25 -0
  556. package/dist/harness/gates/gate-override-validation.d.ts.map +1 -0
  557. package/dist/harness/gates/gate-override-validation.js +81 -0
  558. package/dist/harness/gates/gate-override-validation.js.map +1 -0
  559. package/dist/harness/gates/gate-rule-catalog.d.ts +24 -0
  560. package/dist/harness/gates/gate-rule-catalog.d.ts.map +1 -0
  561. package/dist/harness/gates/gate-rule-catalog.js +112 -0
  562. package/dist/harness/gates/gate-rule-catalog.js.map +1 -0
  563. package/dist/harness/gates/gate-terms.d.ts +33 -0
  564. package/dist/harness/gates/gate-terms.d.ts.map +1 -0
  565. package/dist/harness/gates/gate-terms.js +41 -0
  566. package/dist/harness/gates/gate-terms.js.map +1 -0
  567. package/dist/harness/gates/in-run-decision-check.d.ts +21 -0
  568. package/dist/harness/gates/in-run-decision-check.d.ts.map +1 -0
  569. package/dist/harness/gates/in-run-decision-check.js +166 -0
  570. package/dist/harness/gates/in-run-decision-check.js.map +1 -0
  571. package/dist/harness/gates/journey-gate-inputs.d.ts +37 -0
  572. package/dist/harness/gates/journey-gate-inputs.d.ts.map +1 -0
  573. package/dist/harness/gates/journey-gate-inputs.js +81 -0
  574. package/dist/harness/gates/journey-gate-inputs.js.map +1 -0
  575. package/dist/harness/gates/migrated-waiver-import-bounds.d.ts +13 -0
  576. package/dist/harness/gates/migrated-waiver-import-bounds.d.ts.map +1 -0
  577. package/dist/harness/gates/migrated-waiver-import-bounds.js +141 -0
  578. package/dist/harness/gates/migrated-waiver-import-bounds.js.map +1 -0
  579. package/dist/harness/gates/migrated-waiver-review.d.ts +16 -0
  580. package/dist/harness/gates/migrated-waiver-review.d.ts.map +1 -0
  581. package/dist/harness/gates/migrated-waiver-review.js +114 -0
  582. package/dist/harness/gates/migrated-waiver-review.js.map +1 -0
  583. package/dist/harness/gates/resolve-rule.d.ts +59 -0
  584. package/dist/harness/gates/resolve-rule.d.ts.map +1 -0
  585. package/dist/harness/gates/resolve-rule.js +41 -0
  586. package/dist/harness/gates/resolve-rule.js.map +1 -0
  587. package/dist/harness/gates/unit-gate-overrides.d.ts +25 -0
  588. package/dist/harness/gates/unit-gate-overrides.d.ts.map +1 -0
  589. package/dist/harness/gates/unit-gate-overrides.js +122 -0
  590. package/dist/harness/gates/unit-gate-overrides.js.map +1 -0
  591. package/dist/harness/journey.d.ts +64 -1
  592. package/dist/harness/journey.d.ts.map +1 -1
  593. package/dist/harness/journey.js +258 -34
  594. package/dist/harness/journey.js.map +1 -1
  595. package/dist/harness/manifest.d.ts +12 -0
  596. package/dist/harness/manifest.d.ts.map +1 -1
  597. package/dist/harness/manifest.js +71 -43
  598. package/dist/harness/manifest.js.map +1 -1
  599. package/dist/harness/next-step.d.ts +58 -4
  600. package/dist/harness/next-step.d.ts.map +1 -1
  601. package/dist/harness/next-step.js +55 -204
  602. package/dist/harness/next-step.js.map +1 -1
  603. package/dist/harness/parse.d.ts +7 -0
  604. package/dist/harness/parse.d.ts.map +1 -1
  605. package/dist/harness/parse.js +18 -2
  606. package/dist/harness/parse.js.map +1 -1
  607. package/dist/harness/provenance.d.ts +29 -0
  608. package/dist/harness/provenance.d.ts.map +1 -1
  609. package/dist/harness/provenance.js +109 -9
  610. package/dist/harness/provenance.js.map +1 -1
  611. package/dist/harness/script-check.d.ts.map +1 -1
  612. package/dist/harness/script-check.js +22 -5
  613. package/dist/harness/script-check.js.map +1 -1
  614. package/dist/harness/sensors.d.ts +14 -3
  615. package/dist/harness/sensors.d.ts.map +1 -1
  616. package/dist/harness/sensors.js +41 -38
  617. package/dist/harness/sensors.js.map +1 -1
  618. package/dist/harness/triage-manual-classification.d.ts +32 -0
  619. package/dist/harness/triage-manual-classification.d.ts.map +1 -0
  620. package/dist/harness/triage-manual-classification.js +56 -0
  621. package/dist/harness/triage-manual-classification.js.map +1 -0
  622. package/dist/harness/unit-paths.d.ts +8 -0
  623. package/dist/harness/unit-paths.d.ts.map +1 -1
  624. package/dist/harness/unit-paths.js +23 -1
  625. package/dist/harness/unit-paths.js.map +1 -1
  626. package/dist/hooks/bash-read-only-segment.d.ts +9 -0
  627. package/dist/hooks/bash-read-only-segment.d.ts.map +1 -0
  628. package/dist/hooks/bash-read-only-segment.js +168 -0
  629. package/dist/hooks/bash-read-only-segment.js.map +1 -0
  630. package/dist/hooks/bash-write-targets.d.ts +25 -0
  631. package/dist/hooks/bash-write-targets.d.ts.map +1 -0
  632. package/dist/hooks/bash-write-targets.js +266 -0
  633. package/dist/hooks/bash-write-targets.js.map +1 -0
  634. package/dist/hooks/claude-hook-entry.d.ts +11 -0
  635. package/dist/hooks/claude-hook-entry.d.ts.map +1 -0
  636. package/dist/hooks/claude-hook-entry.js +137 -0
  637. package/dist/hooks/claude-hook-entry.js.map +1 -0
  638. package/dist/hooks/claude-transcript-turn.d.ts +11 -0
  639. package/dist/hooks/claude-transcript-turn.d.ts.map +1 -0
  640. package/dist/hooks/claude-transcript-turn.js +143 -0
  641. package/dist/hooks/claude-transcript-turn.js.map +1 -0
  642. package/dist/hooks/guard-delivery-contract-rule.d.ts +10 -0
  643. package/dist/hooks/guard-delivery-contract-rule.d.ts.map +1 -0
  644. package/dist/hooks/guard-delivery-contract-rule.js +152 -0
  645. package/dist/hooks/guard-delivery-contract-rule.js.map +1 -0
  646. package/dist/hooks/guard-protected-paths.d.ts +13 -0
  647. package/dist/hooks/guard-protected-paths.d.ts.map +1 -0
  648. package/dist/hooks/guard-protected-paths.js +116 -0
  649. package/dist/hooks/guard-protected-paths.js.map +1 -0
  650. package/dist/hooks/guard-rules.d.ts +20 -0
  651. package/dist/hooks/guard-rules.d.ts.map +1 -0
  652. package/dist/hooks/guard-rules.js +130 -0
  653. package/dist/hooks/guard-rules.js.map +1 -0
  654. package/dist/hooks/guard-tty-spoof-rule.d.ts +17 -0
  655. package/dist/hooks/guard-tty-spoof-rule.d.ts.map +1 -0
  656. package/dist/hooks/guard-tty-spoof-rule.js +22 -0
  657. package/dist/hooks/guard-tty-spoof-rule.js.map +1 -0
  658. package/dist/hooks/hand-back-core.d.ts +42 -0
  659. package/dist/hooks/hand-back-core.d.ts.map +1 -0
  660. package/dist/hooks/hand-back-core.js +128 -0
  661. package/dist/hooks/hand-back-core.js.map +1 -0
  662. package/dist/hooks/hook-cli-command.d.ts +9 -0
  663. package/dist/hooks/hook-cli-command.d.ts.map +1 -0
  664. package/dist/hooks/hook-cli-command.js +46 -0
  665. package/dist/hooks/hook-cli-command.js.map +1 -0
  666. package/dist/hooks/hook-registry.d.ts +10 -0
  667. package/dist/hooks/hook-registry.d.ts.map +1 -0
  668. package/dist/hooks/hook-registry.js +24 -0
  669. package/dist/hooks/hook-registry.js.map +1 -0
  670. package/dist/hooks/hook-result-contract.d.ts +50 -0
  671. package/dist/hooks/hook-result-contract.d.ts.map +1 -0
  672. package/dist/hooks/hook-result-contract.js +80 -0
  673. package/dist/hooks/hook-result-contract.js.map +1 -0
  674. package/dist/hooks/hook-toggles.d.ts +10 -0
  675. package/dist/hooks/hook-toggles.d.ts.map +1 -0
  676. package/dist/hooks/hook-toggles.js +107 -0
  677. package/dist/hooks/hook-toggles.js.map +1 -0
  678. package/dist/hooks/pre-tool-guard-hook.d.ts +10 -0
  679. package/dist/hooks/pre-tool-guard-hook.d.ts.map +1 -0
  680. package/dist/hooks/pre-tool-guard-hook.js +105 -0
  681. package/dist/hooks/pre-tool-guard-hook.js.map +1 -0
  682. package/dist/hooks/session-start-unit-state-hook.d.ts +14 -0
  683. package/dist/hooks/session-start-unit-state-hook.d.ts.map +1 -0
  684. package/dist/hooks/session-start-unit-state-hook.js +60 -0
  685. package/dist/hooks/session-start-unit-state-hook.js.map +1 -0
  686. package/dist/hooks/stop-next-step-hook.d.ts +16 -0
  687. package/dist/hooks/stop-next-step-hook.d.ts.map +1 -0
  688. package/dist/hooks/stop-next-step-hook.js +43 -0
  689. package/dist/hooks/stop-next-step-hook.js.map +1 -0
  690. package/dist/hooks/sungen-project-root.d.ts +19 -0
  691. package/dist/hooks/sungen-project-root.d.ts.map +1 -0
  692. package/dist/hooks/sungen-project-root.js +130 -0
  693. package/dist/hooks/sungen-project-root.js.map +1 -0
  694. package/dist/index.d.ts.map +1 -1
  695. package/dist/index.js +1 -2
  696. package/dist/index.js.map +1 -1
  697. package/dist/orchestrator/ai-skills/command-partial-includes.d.ts +15 -0
  698. package/dist/orchestrator/ai-skills/command-partial-includes.d.ts.map +1 -0
  699. package/dist/orchestrator/ai-skills/command-partial-includes.js +106 -0
  700. package/dist/orchestrator/ai-skills/command-partial-includes.js.map +1 -0
  701. package/dist/orchestrator/ai-skills/commands.d.ts +5 -1
  702. package/dist/orchestrator/ai-skills/commands.d.ts.map +1 -1
  703. package/dist/orchestrator/ai-skills/commands.js +11 -3
  704. package/dist/orchestrator/ai-skills/commands.js.map +1 -1
  705. package/dist/orchestrator/assets-drift.d.ts +5 -0
  706. package/dist/orchestrator/assets-drift.d.ts.map +1 -1
  707. package/dist/orchestrator/assets-drift.js +12 -3
  708. package/dist/orchestrator/assets-drift.js.map +1 -1
  709. package/dist/orchestrator/claude-hooks-install.d.ts +27 -0
  710. package/dist/orchestrator/claude-hooks-install.d.ts.map +1 -0
  711. package/dist/orchestrator/claude-hooks-install.js +203 -0
  712. package/dist/orchestrator/claude-hooks-install.js.map +1 -0
  713. package/dist/orchestrator/lockstep-version.d.ts +15 -5
  714. package/dist/orchestrator/lockstep-version.d.ts.map +1 -1
  715. package/dist/orchestrator/lockstep-version.js +30 -17
  716. package/dist/orchestrator/lockstep-version.js.map +1 -1
  717. package/dist/orchestrator/project-initializer.d.ts +6 -0
  718. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  719. package/dist/orchestrator/project-initializer.js +24 -0
  720. package/dist/orchestrator/project-initializer.js.map +1 -1
  721. package/dist/orchestrator/templates/ai-src/commands/add-api.md +2 -0
  722. package/dist/orchestrator/templates/ai-src/commands/add-flow.md +6 -26
  723. package/dist/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
  724. package/dist/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
  725. package/dist/orchestrator/templates/ai-src/commands/create-test.md +17 -16
  726. package/dist/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
  727. package/dist/orchestrator/templates/ai-src/commands/delivery.md +4 -0
  728. package/dist/orchestrator/templates/ai-src/commands/design.md +2 -0
  729. package/dist/orchestrator/templates/ai-src/commands/feedback.md +2 -0
  730. package/dist/orchestrator/templates/ai-src/commands/locale.md +2 -0
  731. package/dist/orchestrator/templates/ai-src/commands/review.md +4 -0
  732. package/dist/orchestrator/templates/ai-src/commands/run-test.md +6 -8
  733. package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
  734. package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
  735. package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
  736. package/dist/orchestrator/templates/ai-src/partials/waiting-for-you.claude.md +11 -0
  737. package/dist/orchestrator/templates/ai-src/partials/waiting-for-you.codex.md +11 -0
  738. package/dist/orchestrator/templates/ai-src/partials/waiting-for-you.copilot.md +11 -0
  739. package/dist/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +1 -2
  740. package/dist/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +4 -5
  741. package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +8 -24
  742. package/dist/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +3 -4
  743. package/dist/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
  744. package/dist/orchestrator/templates/specs-test-data.ts +4 -22
  745. package/dist/utils/safe-yaml-parse.d.ts +8 -0
  746. package/dist/utils/safe-yaml-parse.d.ts.map +1 -0
  747. package/dist/utils/safe-yaml-parse.js +51 -0
  748. package/dist/utils/safe-yaml-parse.js.map +1 -0
  749. package/package.json +3 -3
  750. package/src/basis/anchor-grammar.ts +83 -0
  751. package/src/basis/anchor-hash.ts +27 -0
  752. package/src/basis/bm51-tables.ts +65 -0
  753. package/src/basis/extract-spec-anchors.ts +95 -0
  754. package/src/basis/migration-sentinel.ts +175 -0
  755. package/src/basis/spec-frontmatter.ts +68 -0
  756. package/src/basis/spec-sections.ts +35 -0
  757. package/src/basis/test-basis-schema.ts +81 -0
  758. package/src/capabilities/discover.ts +15 -2
  759. package/src/capabilities/registry.ts +16 -0
  760. package/src/cli/case-triage-hint.ts +31 -0
  761. package/src/cli/commands/audit.ts +1 -1
  762. package/src/cli/commands/capability.ts +1 -1
  763. package/src/cli/commands/contract-derive-command.ts +72 -0
  764. package/src/cli/commands/contract.ts +164 -0
  765. package/src/cli/commands/delivery.ts +106 -19
  766. package/src/cli/commands/gate.ts +2 -1
  767. package/src/cli/commands/generate.ts +16 -3
  768. package/src/cli/commands/journey.ts +45 -18
  769. package/src/cli/commands/next.ts +92 -11
  770. package/src/cli/commands/triage.ts +41 -3
  771. package/src/cli/commands/update.ts +41 -10
  772. package/src/cli/index.ts +24 -30
  773. package/src/cli/json-error-on-exit.ts +72 -0
  774. package/src/cli/project-sungen-invocation.ts +59 -0
  775. package/src/cli/run-command-hints.ts +47 -0
  776. package/src/cli/waiting-for-you-block.ts +27 -0
  777. package/src/contract/accept-opaque-steps.ts +114 -0
  778. package/src/contract/approve-contract.ts +101 -0
  779. package/src/contract/assertion-matcher-vocabulary.ts +93 -0
  780. package/src/contract/build-contract-verdict.ts +108 -0
  781. package/src/contract/build-trace-conformance.ts +103 -0
  782. package/src/contract/classify-contract-change.ts +92 -0
  783. package/src/contract/classify-contract-unit.ts +47 -0
  784. package/src/contract/classify-trace-conformance.ts +170 -0
  785. package/src/contract/contract-git.ts +106 -0
  786. package/src/contract/contract-hash.ts +34 -0
  787. package/src/contract/contract-report-file.ts +25 -0
  788. package/src/contract/contract-schema.ts +166 -0
  789. package/src/contract/contract-units.ts +52 -0
  790. package/src/contract/contracts-lock-file.ts +98 -0
  791. package/src/contract/data-normalize.ts +66 -0
  792. package/src/contract/derive-free-feature.ts +153 -0
  793. package/src/contract/field-semantic-redaction.ts +80 -0
  794. package/src/contract/free-feature-blocks.ts +56 -0
  795. package/src/contract/lock-secret-guard.ts +95 -0
  796. package/src/contract/lock-vs-git-head.ts +38 -0
  797. package/src/contract/normalize-contract-step.ts +74 -0
  798. package/src/contract/normalize-feature-steps.ts +93 -0
  799. package/src/contract/oracle-strength.ts +80 -0
  800. package/src/contract/project-contract-blockers.ts +38 -0
  801. package/src/contract/record-contract-approval.ts +110 -0
  802. package/src/contract/render-free-gherkin.ts +118 -0
  803. package/src/contract/render-trace-sentence.ts +98 -0
  804. package/src/contract/render-trace-target.ts +68 -0
  805. package/src/contract/resolve-unit-trace-identities.ts +58 -0
  806. package/src/contract/trace/collect-trace-evidence.ts +178 -0
  807. package/src/contract/trace/identity-cache.ts +61 -0
  808. package/src/contract/trace/read-file-once.ts +95 -0
  809. package/src/contract/trace/scenario-id-claims.ts +60 -0
  810. package/src/contract/trace/select-final-attempt.ts +77 -0
  811. package/src/contract/trace/snapshot-html-renderer.ts +136 -0
  812. package/src/contract/trace/snapshot-resolver.ts +66 -0
  813. package/src/contract/trace/snapshot-store.ts +151 -0
  814. package/src/contract/trace/target-identity.ts +104 -0
  815. package/src/contract/trace/test-step-join.ts +104 -0
  816. package/src/contract/trace/trace-binding.ts +59 -0
  817. package/src/contract/trace/trace-file-reader.ts +144 -0
  818. package/src/contract/trace/trace-fingerprint.ts +68 -0
  819. package/src/contract/trace/trace-freshness.ts +110 -0
  820. package/src/contract/trace/trace-identity-resolution.ts +77 -0
  821. package/src/contract/trace/trace-run-record.ts +96 -0
  822. package/src/contract/trace/trace-steps.ts +88 -0
  823. package/src/contract/trace/trace-zip-limits.ts +77 -0
  824. package/src/contract/trace/trace-zip-reader.ts +127 -0
  825. package/src/contract/verify-approval-decisions.ts +64 -0
  826. package/src/decisions/append-decision.ts +35 -0
  827. package/src/decisions/confirmed-decision-commands.ts +149 -0
  828. package/src/decisions/decision-file.ts +93 -0
  829. package/src/decisions/decision-identity.ts +73 -0
  830. package/src/decisions/decision-integrity-check.ts +61 -0
  831. package/src/decisions/decision-schema.ts +77 -0
  832. package/src/decisions/decision-source.ts +14 -0
  833. package/src/decisions/exclusive-file-create.ts +42 -0
  834. package/src/decisions/git-head-trust.ts +76 -0
  835. package/src/decisions/human-confirmation.ts +119 -0
  836. package/src/decisions/legacy-waiver-migration.ts +146 -0
  837. package/src/decisions/read-decisions.ts +61 -0
  838. package/src/decisions/viewpoint-baseline-adapter.ts +74 -0
  839. package/src/decisions/waiver-decisions.ts +56 -0
  840. package/src/exporters/csv-exporter.ts +12 -4
  841. package/src/exporters/matrix/build.ts +11 -9
  842. package/src/exporters/matrix/export.ts +16 -4
  843. package/src/exporters/matrix/gates.ts +62 -129
  844. package/src/exporters/matrix/render-csv.ts +3 -0
  845. package/src/exporters/matrix/render-gate-overrides-sheet.ts +50 -0
  846. package/src/exporters/matrix/render-xlsx.ts +3 -0
  847. package/src/exporters/matrix/types.ts +4 -1
  848. package/src/exporters/matrix/xlsx-cells.ts +1 -1
  849. package/src/exporters/test-data-resolver.ts +2 -10
  850. package/src/exporters/xlsx-exporter.ts +5 -4
  851. package/src/generators/gherkin-parser/index.ts +0 -1
  852. package/src/generators/test-generator/adapters/appium/templates/steps/assertions/contain-text-assertion.hbs +1 -2
  853. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/fill-action.hbs +1 -13
  854. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +1 -9
  855. package/src/generators/test-generator/code-generator.ts +17 -4
  856. package/src/generators/test-generator/diagnostics.ts +3 -9
  857. package/src/generators/test-generator/patterns/types.ts +0 -2
  858. package/src/generators/test-generator/step-mapper.ts +9 -56
  859. package/src/generators/test-generator/utils/data-resolver.ts +0 -53
  860. package/src/generators/test-generator/utils/selector-resolver.ts +2 -10
  861. package/src/graph/board-human-actions.ts +80 -0
  862. package/src/graph/evaluate-graph.ts +97 -0
  863. package/src/graph/human-action.ts +33 -0
  864. package/src/graph/locate-finding.ts +93 -0
  865. package/src/graph/manual-triage-decisions.ts +55 -0
  866. package/src/graph/node-decl.ts +83 -0
  867. package/src/graph/nodes/core-node-catalog.ts +15 -0
  868. package/src/graph/nodes/test-case-contract-nodes.ts +90 -0
  869. package/src/graph/nodes/test-case-nodes.ts +100 -0
  870. package/src/graph/nodes/unit-audit-nodes.ts +96 -0
  871. package/src/graph/nodes/unit-contract-node.ts +100 -0
  872. package/src/graph/nodes/unit-design-nodes.ts +89 -0
  873. package/src/graph/nodes/unit-execution-nodes.ts +77 -0
  874. package/src/graph/test-case-identity.ts +75 -0
  875. package/src/graph/test-case-results.ts +111 -0
  876. package/src/graph/test-case-satisfied.ts +58 -0
  877. package/src/graph/test-case-state-shape.ts +67 -0
  878. package/src/graph/test-case-states.ts +84 -0
  879. package/src/graph/unit-artifact-probes.ts +79 -0
  880. package/src/graph/unit-results-freshness.ts +165 -0
  881. package/src/graph/unit-state-facts.ts +112 -0
  882. package/src/harness/audit.ts +31 -18
  883. package/src/harness/catalog/gate-rules.yaml +647 -0
  884. package/src/harness/defect-draft.ts +13 -2
  885. package/src/harness/defects.ts +22 -9
  886. package/src/harness/flow-check.ts +11 -0
  887. package/src/harness/gates/audit-gate-terms.ts +80 -0
  888. package/src/harness/gates/audit-gate-verdict.ts +79 -0
  889. package/src/harness/gates/audit-input-hash.ts +79 -0
  890. package/src/harness/gates/audit-report-verification.ts +206 -0
  891. package/src/harness/gates/decisions-hash.ts +42 -0
  892. package/src/harness/gates/delivery-checklist.ts +152 -0
  893. package/src/harness/gates/delivery-decision-gate.ts +139 -0
  894. package/src/harness/gates/delivery-decision-step.ts +89 -0
  895. package/src/harness/gates/gate-override-report.ts +114 -0
  896. package/src/harness/gates/gate-override-scope.ts +66 -0
  897. package/src/harness/gates/gate-override-validation.ts +75 -0
  898. package/src/harness/gates/gate-rule-catalog.ts +82 -0
  899. package/src/harness/gates/gate-terms.ts +59 -0
  900. package/src/harness/gates/in-run-decision-check.ts +124 -0
  901. package/src/harness/gates/journey-gate-inputs.ts +89 -0
  902. package/src/harness/gates/migrated-waiver-import-bounds.ts +103 -0
  903. package/src/harness/gates/migrated-waiver-review.ts +121 -0
  904. package/src/harness/gates/resolve-rule.ts +94 -0
  905. package/src/harness/gates/unit-gate-overrides.ts +99 -0
  906. package/src/harness/journey.ts +287 -39
  907. package/src/harness/manifest.ts +67 -43
  908. package/src/harness/next-step.ts +91 -193
  909. package/src/harness/parse.ts +20 -2
  910. package/src/harness/provenance.ts +99 -11
  911. package/src/harness/script-check.ts +20 -5
  912. package/src/harness/sensors.ts +47 -40
  913. package/src/harness/triage-manual-classification.ts +76 -0
  914. package/src/harness/unit-paths.ts +19 -0
  915. package/src/hooks/bash-read-only-segment.ts +130 -0
  916. package/src/hooks/bash-write-targets.ts +195 -0
  917. package/src/hooks/claude-hook-entry.ts +85 -0
  918. package/src/hooks/claude-transcript-turn.ts +96 -0
  919. package/src/hooks/guard-delivery-contract-rule.ts +110 -0
  920. package/src/hooks/guard-protected-paths.ts +80 -0
  921. package/src/hooks/guard-rules.ts +117 -0
  922. package/src/hooks/guard-tty-spoof-rule.ts +34 -0
  923. package/src/hooks/hand-back-core.ts +118 -0
  924. package/src/hooks/hook-cli-command.ts +17 -0
  925. package/src/hooks/hook-registry.ts +24 -0
  926. package/src/hooks/hook-result-contract.ts +114 -0
  927. package/src/hooks/hook-toggles.ts +66 -0
  928. package/src/hooks/pre-tool-guard-hook.ts +67 -0
  929. package/src/hooks/session-start-unit-state-hook.ts +59 -0
  930. package/src/hooks/stop-next-step-hook.ts +38 -0
  931. package/src/hooks/sungen-project-root.ts +80 -0
  932. package/src/index.ts +1 -2
  933. package/src/orchestrator/ai-skills/command-partial-includes.ts +72 -0
  934. package/src/orchestrator/ai-skills/commands.ts +17 -5
  935. package/src/orchestrator/assets-drift.ts +12 -5
  936. package/src/orchestrator/claude-hooks-install.ts +168 -0
  937. package/src/orchestrator/lockstep-version.ts +28 -15
  938. package/src/orchestrator/project-initializer.ts +22 -0
  939. package/src/orchestrator/templates/ai-src/commands/add-api.md +2 -0
  940. package/src/orchestrator/templates/ai-src/commands/add-flow.md +6 -26
  941. package/src/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
  942. package/src/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
  943. package/src/orchestrator/templates/ai-src/commands/create-test.md +17 -16
  944. package/src/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
  945. package/src/orchestrator/templates/ai-src/commands/delivery.md +4 -0
  946. package/src/orchestrator/templates/ai-src/commands/design.md +2 -0
  947. package/src/orchestrator/templates/ai-src/commands/feedback.md +2 -0
  948. package/src/orchestrator/templates/ai-src/commands/locale.md +2 -0
  949. package/src/orchestrator/templates/ai-src/commands/review.md +4 -0
  950. package/src/orchestrator/templates/ai-src/commands/run-test.md +6 -8
  951. package/src/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
  952. package/src/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
  953. package/src/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
  954. package/src/orchestrator/templates/ai-src/partials/waiting-for-you.claude.md +11 -0
  955. package/src/orchestrator/templates/ai-src/partials/waiting-for-you.codex.md +11 -0
  956. package/src/orchestrator/templates/ai-src/partials/waiting-for-you.copilot.md +11 -0
  957. package/src/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +1 -2
  958. package/src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +4 -5
  959. package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +8 -24
  960. package/src/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +3 -4
  961. package/src/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
  962. package/src/orchestrator/templates/specs-test-data.ts +4 -22
  963. package/src/utils/safe-yaml-parse.ts +44 -0
  964. package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/expanded-assertion.hbs +0 -2
  965. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/date-picker-unsupported.hbs +0 -5
  966. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/expanded-assertion.hbs +0 -12
  967. package/src/generators/test-generator/adapters/appium/templates/steps/assertions/expanded-assertion.hbs +0 -2
  968. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/date-picker-unsupported.hbs +0 -5
  969. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/expanded-assertion.hbs +0 -12
@@ -3,12 +3,33 @@
3
3
  *
4
4
  * The next step is derived from what the project HOLDS, not from which command just ran, so a
5
5
  * session cannot lose the thread by finishing somewhere that has no footer of its own (#597).
6
+ *
7
+ * sungen next [unit] every unit (or one), unit-level steps; test-case work folds
8
+ * into one line per node ("N test case(s) …")
9
+ * sungen next <unit> --case <id> one test case: its state, and its steps after the blocking
10
+ * unit steps before them (OES-10.3)
11
+ * --json the same, machine-readable; steps add nodeId, granularity,
12
+ * testCase?, gates?; the unit adds `results` (#942) and
13
+ * `humanActions: [{command, reason, kind, rendered}]` (#954) —
14
+ * `command` canonical, `rendered` as this project runs it (#963),
15
+ * and `humanActionsHeldBy[Command]` when a blocking step holds them (#966);
16
+ * every older field is kept. stdout is the payload alone (#660, #836)
17
+ * The text names the run the results come from and warns when they are older than the suite (#942),
18
+ * and ends with "Waiting for you": every pending human-only command, with why (#954).
6
19
  */
7
20
  import { Command } from 'commander';
8
21
  import * as fs from 'fs';
9
22
  import * as path from 'path';
10
- import { readUnitState, UnitState } from '../../harness/next-step';
23
+ import { CLI_GIT_TIMEOUT_MS, headSnapshot } from '../../contract/contract-git';
24
+ import { testCaseStatusLabel } from '../../graph/test-case-satisfied';
25
+ import { testCaseStates } from '../../graph/test-case-states';
26
+ import { describeResultsRun } from '../../graph/unit-results-freshness';
27
+ import { deriveSteps, NextStep, readUnitState, UnitState } from '../../harness/next-step';
11
28
  import { resolveUnit, resolveUnitCandidates, AmbiguousUnitError } from '../resolve-unit';
29
+ import { withProjectInvocation, withProjectInvocationInText } from '../project-sungen-invocation';
30
+ import { waitingForYouLines } from '../waiting-for-you-block';
31
+ import { caseTriageLines } from '../case-triage-hint';
32
+ import { testCaseNeed } from '../../graph/test-case-satisfied';
12
33
 
13
34
  /** Every unit the project holds, so `sungen next` with no argument still answers. */
14
35
  function allUnits(cwd: string): Array<{ name: string; kind: UnitState['kind']; dir: string }> {
@@ -24,7 +45,25 @@ function allUnits(cwd: string): Array<{ name: string; kind: UnitState['kind']; d
24
45
  return out;
25
46
  }
26
47
 
27
- function render(s: UnitState): void {
48
+ /** Steps as text, each `sungen …` command — the reason's too (#963) — as this project runs it (#939); `--json` keeps them canonical. */
49
+ function renderSteps(steps: NextStep[], cwd: string): void {
50
+ for (const st of steps) {
51
+ const mark = st.kind === 'blocked' ? '⛔' : st.kind === 'optional' ? '○' : st.kind === 'decide' ? '⚖' : '→';
52
+ console.log(` ${mark} ${withProjectInvocationInText(st.command, cwd)}${st.kind === 'decide' ? ' (a QA decision — ask, do not run)' : ''}`);
53
+ console.log(` ${withProjectInvocationInText(st.because, cwd)}`);
54
+ }
55
+ }
56
+
57
+ /**
58
+ * `--json`: each human action keeps its canonical `command` and adds `rendered` — the line a human runs in
59
+ * this project (`npx sungen …` with a local install; an instruction unchanged), as the text shows it (#963).
60
+ */
61
+ function withRenderedHumanActions(s: UnitState, cwd: string): UnitState {
62
+ if (!s.humanActions) return s;
63
+ return { ...s, humanActions: s.humanActions.map((a) => ({ ...a, rendered: a.instruction ? a.command : withProjectInvocation(a.command, cwd) })) };
64
+ }
65
+
66
+ function render(s: UnitState, cwd: string): void {
28
67
  const L = console.log;
29
68
  L('');
30
69
  L(`━━━ Next steps: ${s.unit} (${s.kind}) ━━━`);
@@ -38,12 +77,48 @@ function render(s: UnitState): void {
38
77
  ].filter(Boolean);
39
78
  L(` state: ${held.length ? held.join(' · ') : '(nothing yet)'}`);
40
79
  if (s.audit) L(` audit: ${s.audit.overall}/10 [${s.audit.gateStatus}] · ${s.audit.findings.length} finding(s)`);
80
+ else if (s.auditNotCounted) L(` audit: ${s.auditNotCounted.state === 'stale' ? 'stale' : 'not trusted'} — ${withProjectInvocationInText(s.auditNotCounted.reason, cwd)}`);
81
+ if (s.results) {
82
+ L(` results: ${s.results.files.length} file${s.results.files.length === 1 ? '' : 's'}, ${describeResultsRun(s.results)}`);
83
+ if (s.results.warning) L(` ⚠ ${s.results.warning}`);
84
+ }
41
85
  L('');
42
- for (const st of s.steps) {
43
- const mark = st.kind === 'blocked' ? '⛔' : st.kind === 'optional' ? '○' : st.kind === 'decide' ? '⚖' : '→';
44
- L(` ${mark} ${st.command}${st.kind === 'decide' ? ' (a QA decision — ask, do not run)' : ''}`);
45
- L(` ${st.because}`);
86
+ renderSteps(s.steps, cwd);
87
+ L('');
88
+ const waiting = waitingForYouLines(s.humanActions, cwd, s.humanActionsHeldBy, s.humanActionsHeldByCommand);
89
+ if (waiting.length) { for (const line of waiting) L(line); L(''); }
90
+ }
91
+
92
+ /** `--case <id>`: the case's state and its frontier. Exits 1 when the case cannot be found. */
93
+ function caseView(s: UnitState, cwd: string, unitDir: string, id: string, json: boolean): void {
94
+ let cases = s.testCases;
95
+ if (!cases) {
96
+ try { cases = testCaseStates(cwd, s.unit, { unitDir }); } catch (e) {
97
+ throw new Error(`the test cases of ${s.unit} could not be read: ${e instanceof Error ? e.message : e}`);
98
+ }
99
+ }
100
+ const tc = cases.find((c) => c.id === id);
101
+ if (!tc) {
102
+ const known = cases.slice(0, 8).map((c) => c.id).join(', ');
103
+ throw new Error(`no test case "${id}" in ${s.unit}${known ? ` — known: ${known}${cases.length > 8 ? ', …' : ''}` : ' (it holds no scenario)'}`);
46
104
  }
105
+ const steps = deriveSteps({ ...s, testCases: cases }, { testCase: id });
106
+ if (json) { console.log(JSON.stringify({ unit: s.unit, kind: s.kind, testCase: tc, steps }, null, 2)); return; }
107
+ const L = console.log;
108
+ L('');
109
+ L(`━━━ Next steps: ${s.unit} › ${tc.id} (${s.kind}) ━━━`);
110
+ L('');
111
+ L(` test case: ${tc.title}${tc.unstableId ? ' (no VP-id — this id changes when the title does)' : ''}`);
112
+ L(` where: ${tc.file}#L${tc.lines[0]}-L${tc.lines[1]}`);
113
+ L(` status: ${testCaseStatusLabel(tc)} · result ${tc.result}${tc.mocked && tc.result === 'passed' ? ' (mocked)' : ''}${tc.stale ? ` · stale: ${tc.stale}` : ''}${tc.triage ? ` · triage ${tc.triage.class}${tc.triage.ruleId === 'manual' ? ` (by hand, ${tc.triage.decision})` : ''}` : ''}`);
114
+ if (tc.contract) L(` contract: ${tc.contract.class}${tc.contract.uncommitted ? ' · lock entry not committed' : ''}${tc.contract.lowIdentity ? ' · low target identity' : ''}`);
115
+ if (tc.anchors.length) L(` anchors: ${tc.anchors.map((a) => `${a.anchor} (${a.change})`).join(', ')}`);
116
+ for (const f of tc.findings) L(` finding: ${f.code} [${f.confidence.label} ${f.confidence.score}] ${f.citation}`);
117
+ L('');
118
+ if (steps.length) renderSteps(steps, cwd);
119
+ else L(` ✓ nothing to do for this test case — ${testCaseStatusLabel(tc)}`);
120
+ // "needs triage" names how to classify the red, even while a unit step holds its own step back (#966).
121
+ if (testCaseNeed(tc) === 'triage') for (const line of caseTriageLines(s, tc, steps, cwd)) L(line);
47
122
  L('');
48
123
  }
49
124
 
@@ -51,10 +126,13 @@ export function registerNextCommand(program: Command): void {
51
126
  program
52
127
  .command('next [unit]')
53
128
  .description('What to do next for a unit (or every unit), derived from the project state')
129
+ .option('--case <id>', 'One test case of the unit (its VP-id): its state and its next steps')
54
130
  .option('--json', 'Machine-readable output')
55
- .action((unit: string | undefined, o: { json?: boolean }) => {
131
+ .action((unit: string | undefined, o: { json?: boolean; case?: string }) => {
56
132
  try {
57
133
  const cwd = process.cwd();
134
+ if (o.case && !unit) throw new Error('--case needs a unit: sungen next <unit> --case <id>');
135
+ const gitSnapshot = headSnapshot(cwd, CLI_GIT_TIMEOUT_MS);
58
136
  let states: UnitState[];
59
137
  if (unit) {
60
138
  const resolved = resolveUnit(unit, cwd);
@@ -62,7 +140,9 @@ export function registerNextCommand(program: Command): void {
62
140
  console.error(`Error: no unit named "${unit}" under qa/screens, qa/flows or qa/api.`);
63
141
  process.exit(1);
64
142
  }
65
- states = [readUnitState(cwd, resolved.dir, unit, resolved.kind)];
143
+ const state = readUnitState(cwd, resolved.dir, unit, resolved.kind, { gitSnapshot });
144
+ if (o.case) { caseView(state, cwd, resolved.dir, o.case, Boolean(o.json)); return; }
145
+ states = [state];
66
146
  } else {
67
147
  const units = allUnits(cwd);
68
148
  if (units.length === 0) {
@@ -72,14 +152,15 @@ export function registerNextCommand(program: Command): void {
72
152
  // A name in two places is ambiguous; report it rather than answering for one of them.
73
153
  states = units.map((u) => {
74
154
  if (resolveUnitCandidates(u.name, cwd).length > 1) throw new AmbiguousUnitError(u.name, resolveUnitCandidates(u.name, cwd));
75
- return readUnitState(cwd, u.dir, u.name, u.kind);
155
+ return readUnitState(cwd, u.dir, u.name, u.kind, { gitSnapshot });
76
156
  });
77
157
  }
78
158
  if (o.json) {
79
- console.log(JSON.stringify(states.length === 1 ? states[0] : states, null, 2));
159
+ const out = states.map((s) => withRenderedHumanActions(s, cwd));
160
+ console.log(JSON.stringify(out.length === 1 ? out[0] : out, null, 2));
80
161
  return;
81
162
  }
82
- for (const s of states) render(s);
163
+ for (const s of states) render(s, cwd);
83
164
  } catch (e) {
84
165
  console.error(`Error: ${e instanceof Error ? e.message : e}`);
85
166
  process.exit(1);
@@ -1,15 +1,44 @@
1
1
  import { Command } from 'commander';
2
2
  import * as path from 'path';
3
3
  import { resolveUnit } from '../resolve-unit';
4
+ import { withProjectInvocation, withProjectInvocationInText } from '../project-sungen-invocation';
5
+ import { processIO } from '../../decisions/human-confirmation';
6
+ import { manualClassifications } from '../../graph/manual-triage-decisions';
7
+ import { testCaseStates } from '../../graph/test-case-states';
4
8
  import { triageUnit, writeTriageReport } from '../../harness/triage-unit';
9
+ import { classifyRedCase } from '../../harness/triage-manual-classification';
5
10
  import type { TriageClass } from '../../harness/triage';
6
11
 
7
12
  /** Display order: what needs a decision first, green last. */
8
13
  const ORDER: TriageClass[] = ['product-candidate', 'unclassified', 'test-defect', 'environment', 'blocked-capability', 'known-defect', 'flaky'];
9
14
 
15
+ interface TriageOptions { screen?: string; api?: string; area?: string; json?: boolean; case?: string; as?: string; reason?: string }
16
+
17
+ /** The classifications by hand in force for the unit (they win over the automatic class of the same red). */
18
+ function printManual(cwd: string, unitDir: string, name: string): void {
19
+ const inForce = testCaseStates(cwd, name, { unitDir, auditFindings: [] }).filter((c) => c.triage?.ruleId === 'manual');
20
+ if (!inForce.length) return;
21
+ const why = new Map(manualClassifications(cwd, unitDir).map((m) => [m.decision, m]));
22
+ console.log(`\n classified by hand (${inForce.length}) — these win over the automatic class`);
23
+ for (const c of inForce) {
24
+ const m = why.get(c.triage!.decision ?? '');
25
+ console.log(` • ${c.id} → ${c.triage!.class}${m ? ` (${m.decision}, by ${m.by}): ${m.reason}` : ''}`);
26
+ }
27
+ }
28
+
29
+ /** `--case <id> --as <class> --reason "…"`: record one classification by hand (harness/triage-manual-classification.ts). */
30
+ async function classifyByHand(cwd: string, name: string, o: TriageOptions): Promise<void> {
31
+ if (!o.case || !o.as) throw new Error(o.as ? '--as needs --case <id>' : '--case needs --as product|test-defect|environment and --reason "…"');
32
+ const r = await classifyRedCase({ projectRoot: cwd, unit: name, caseId: o.case, as: o.as, reason: o.reason, io: processIO() });
33
+ if (o.json) { console.log(JSON.stringify({ status: r.status, caseId: r.caseId, class: r.class, path: path.relative(cwd, r.path), entry: r.entry }, null, 2)); return; }
34
+ console.log(`\n${r.status === 'created' ? '✓ Recorded' : '= Already recorded'} ${r.entry.id}: ${r.caseId} → ${r.class} (classified by hand) → ${path.relative(cwd, r.path)}`);
35
+ console.log(' It holds until the case runs again. Commit it through review with the run it judged.\n');
36
+ }
37
+
10
38
  /**
11
39
  * `sungen triage` — classify every red or flaky scenario of the latest run (see harness/triage.ts).
12
- * Reports, never gates: always exits 0 once the unit is found.
40
+ * Reports, never gates: always exits 0 once the unit is found. With `--case --as` it records one
41
+ * classification by hand instead (exit 1 when refused or invalid).
13
42
  */
14
43
  export function registerTriageCommand(program: Command): void {
15
44
  program
@@ -18,14 +47,18 @@ export function registerTriageCommand(program: Command): void {
18
47
  .option('-s, --screen <name>', 'Screen or flow name')
19
48
  .option('--api <name>', 'API-first area or api flow (qa/api/<name>)')
20
49
  .option('--area <name>', 'Alias of --api')
50
+ .option('--case <id>', 'Classify one red test case by hand (its VP-id) — with --as and --reason')
51
+ .option('--as <class>', 'product (anyone may record it) | test-defect | environment (test-defect and environment: a human types a confirmation on a TTY)')
52
+ .option('--reason <text>', 'Why the red is that class (mandatory with --as)')
21
53
  .option('--json', 'Output the raw JSON report')
22
- .action((o: { screen?: string; api?: string; area?: string; json?: boolean }) => {
54
+ .action(async (o: TriageOptions) => {
23
55
  try {
24
56
  const name = o.screen || o.api || o.area;
25
57
  if (!name) throw new Error('Provide --screen <name> (or --api <area>)');
26
58
  const cwd = process.cwd();
27
59
  const unit = resolveUnit(name, cwd);
28
60
  if (!unit) throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
61
+ if (o.case || o.as) { await classifyByHand(cwd, name, o); return; }
29
62
 
30
63
  const report = triageUnit(cwd, unit);
31
64
  if (report.resultFiles.length === 0) {
@@ -48,9 +81,14 @@ export function registerTriageCommand(program: Command): void {
48
81
  L(` ${r.ruleId}: ${r.evidence}`);
49
82
  }
50
83
  }
84
+ printManual(cwd, unit.dir, name);
85
+ if (report.rows.some((r) => r.class === 'unclassified')) {
86
+ L(`\n Unclassified: read the evidence (trace, error), then classify by hand:\n ${withProjectInvocation(`sungen triage --${unit.kind === 'api' ? 'api' : 'screen'} ${name} --case <id> --as product|test-defect|environment --reason "…"`, cwd)}`);
87
+ }
51
88
  L(`\n Report: ${path.relative(cwd, saved)}\n`);
52
89
  } catch (error) {
53
- console.error('Error:', error instanceof Error ? error.message : error);
90
+ // A refusal names the command a human runs instead: as this project runs sungen (#963).
91
+ console.error('Error:', error instanceof Error ? withProjectInvocationInText(error.message, process.cwd()) : error);
54
92
  process.exitCode = 1;
55
93
  }
56
94
  });
@@ -1,4 +1,4 @@
1
- import { Command } from 'commander';
1
+ import { Command, Option } from 'commander';
2
2
  import { spawnSync } from 'child_process';
3
3
  import * as fs from 'fs';
4
4
  import * as path from 'path';
@@ -26,7 +26,9 @@ import { syncProjectSungenDeps } from '../../orchestrator/project-deps-sync';
26
26
  *
27
27
  * The public `--skip-npm-install` flag is still available for users who
28
28
  * already installed the binary by other means (CI pipelines, corporate
29
- * mirror, manual download) and only want to refresh the project AI assets.
29
+ * mirror, manual download). It skips only step 1: the project sync still
30
+ * re-pins package.json (security overrides included) and runs `npm install`
31
+ * there — `--skip-project` skips that (#939).
30
32
  */
31
33
 
32
34
  const SKIP_NPM_ENV = 'SUNGEN_UPDATE_SKIP_NPM';
@@ -41,7 +43,7 @@ export function registerUpdateCommand(program: Command): void {
41
43
  program
42
44
  .command('update')
43
45
  .description(
44
- 'Reinstall @sun-asterisk/sungen (stable by default, --beta for prerelease) + refresh AI rules, commands, skills',
46
+ 'Reinstall @sun-asterisk/sungen (stable by default, --beta / --alpha for prerelease) + refresh AI rules, commands, skills',
45
47
  )
46
48
  .option('--dry-run', 'Show what would be updated without making changes')
47
49
  .option(
@@ -56,13 +58,25 @@ export function registerUpdateCommand(program: Command): void {
56
58
  'Switch to the BETA channel (installs @beta — prerelease builds for testing)',
57
59
  false,
58
60
  )
61
+ // `--beta --alpha` is ambiguous: commander refuses it while parsing — one usage-error line, exit 1,
62
+ // before the action (and any npm install) runs — rather than settling it by flag order.
63
+ .addOption(
64
+ new Option(
65
+ '--alpha',
66
+ 'Switch to the ALPHA channel (installs @alpha — early builds of the next big update, ahead of beta)',
67
+ )
68
+ .default(false)
69
+ .conflicts('beta'),
70
+ )
59
71
  .option(
60
72
  '--tag <dist-tag>',
61
- 'Install a specific npm dist-tag (e.g. latest, beta, next). Overrides --beta.',
73
+ 'Install a specific npm dist-tag (e.g. latest, beta, alpha, next). Overrides --beta / --alpha.',
62
74
  )
75
+ // #939: it skips only the GLOBAL install — the project is still synced, so the help says so.
63
76
  .option(
64
77
  '--skip-npm-install',
65
- 'Skip the global npm install step (refresh project AI assets only)',
78
+ 'Skip the global npm install step. The project is still synced: its sungen packages are re-pinned in package.json '
79
+ + '(security `overrides` included) and `npm install` runs in the project — add --skip-project to skip that too',
66
80
  false,
67
81
  )
68
82
  .option(
@@ -70,16 +84,14 @@ export function registerUpdateCommand(program: Command): void {
70
84
  'Skip reinstalling the project-local sungen packages (AI assets only — leaves node_modules stale)',
71
85
  false,
72
86
  )
73
- .action(async (options: { dryRun?: boolean; beta?: boolean; tag?: string; skipNpmInstall?: boolean; skipProject?: boolean; assistant?: string[]; force?: boolean }) => {
87
+ .action(async (options: { dryRun?: boolean; beta?: boolean; alpha?: boolean; tag?: string; skipNpmInstall?: boolean; skipProject?: boolean; assistant?: string[]; force?: boolean }) => {
74
88
  try {
75
89
  const skipNpm =
76
90
  Boolean(options.skipNpmInstall) || process.env[SKIP_NPM_ENV] === '1';
77
91
  const skipProject =
78
92
  Boolean(options.skipProject) || process.env[SKIP_PROJECT_ENV] === '1';
79
93
 
80
- // Channel resolution via npm dist-tags. Default `latest` = official/stable.
81
- // `--beta` → beta channel; running plain `sungen update` later switches back to stable.
82
- const channel = options.tag || (options.beta ? 'beta' : 'latest');
94
+ const channel = resolveUpdateChannel(options);
83
95
 
84
96
  if (!skipNpm) {
85
97
  reinstallSungen(channel);
@@ -106,6 +118,13 @@ export function registerUpdateCommand(program: Command): void {
106
118
  // …and move the old `trace: 'on-first-retry'` default, which never records a trace off CI.
107
119
  const { installTraceMode } = require('../../orchestrator/trace-mode-install');
108
120
  installTraceMode(process.cwd(), options.dryRun ?? false);
121
+ // Claude Code hooks: re-merged into .claude/settings.json (user hooks kept); sungen entries a
122
+ // newer version dropped, or qa/sungen.config.yaml turned off, are removed.
123
+ if (resolveAssistants(options.assistant).includes('claude')) {
124
+ const { installClaudeHooks, describeHooksInstall } = require('../../orchestrator/claude-hooks-install');
125
+ const hooks = installClaudeHooks(process.cwd(), { dryRun: options.dryRun ?? false });
126
+ console.log(`${hooks.settings === 'unreadable' ? '⚠️ ' : '🪝'} ${options.dryRun ? '[dry-run] ' : ''}${describeHooksInstall(hooks)}\n`);
127
+ }
109
128
  } catch (error) {
110
129
  console.error('❌ Update failed:', error);
111
130
  process.exit(1);
@@ -113,6 +132,18 @@ export function registerUpdateCommand(program: Command): void {
113
132
  });
114
133
  }
115
134
 
135
+ /**
136
+ * The npm dist-tag `sungen update` installs. `latest` = official/stable (the default, and how a
137
+ * plain `sungen update` switches back); `--beta` / `--alpha` pick a prerelease channel (each branch
138
+ * auto-publishes to the dist-tag of its name); `--tag` names any dist-tag and wins over both.
139
+ * `--beta` with `--alpha` never reaches here — the option definition refuses the pair.
140
+ */
141
+ export function resolveUpdateChannel(o: { tag?: string; beta?: boolean; alpha?: boolean }): string {
142
+ if (o.tag) return o.tag;
143
+ if (o.alpha) return 'alpha';
144
+ return o.beta ? 'beta' : 'latest';
145
+ }
146
+
116
147
  function reinstallSungen(channel: string): void {
117
148
  const spec = `@sun-asterisk/sungen@${channel}`;
118
149
  const label = channel === 'latest' ? 'stable (latest)' : `${channel} channel`;
@@ -139,7 +170,7 @@ function printCurrentVersion(channel: string): void {
139
170
  spawnSync('sungen', ['--version'], { stdio: 'inherit', shell: true });
140
171
  }
141
172
  if (channel === 'latest') {
142
- console.log(' Channel: stable. To try prereleases: sungen update --beta');
173
+ console.log(' Channel: stable. To try prereleases: sungen update --beta (or --alpha for the next big update)');
143
174
  } else {
144
175
  console.log(` Channel: ${channel} (prerelease). To return to stable: sungen update`);
145
176
  }
package/src/cli/index.ts CHANGED
@@ -44,12 +44,25 @@ import { registerLoginCommand } from './commands/login';
44
44
  import { capabilityRegistry } from '../capabilities/registry';
45
45
  import { discoverAndRegisterCapabilities } from '../capabilities/discover';
46
46
  import { warnAssetsDrift } from '../orchestrator/assets-drift';
47
+ import { attachCliHandBack } from '../hooks/hand-back-core';
48
+ import { attachJsonErrorOnExit, commandSupportsJson } from './json-error-on-exit';
49
+ import { registerHookCommand } from '../hooks/hook-cli-command';
47
50
 
48
51
  // Read version from package.json so `--version` never drifts from the released version.
49
52
  const { version } = require('../../package.json') as { version: string };
50
53
 
51
54
  async function main() {
55
+ // #597 + P0.1 — the hand-back, once, for EVERY command, and from the moment parsing starts: a
56
+ // usage error never reaches an action, and `main().catch` exits from outside one. It hangs off
57
+ // process exit (not postAction) because several commands exit with a MEANINGFUL code that skips
58
+ // commander's hooks (`depth-lint` → 2). It points at `sungen next` instead of restating a step,
59
+ // so it cannot drift from the project state. A failure prints it on stderr after the error;
60
+ // `--json`/`--grep` keep it off stdout (#836); `hook` never prints one, `next` only when it fails (#937). The line and
61
+ // those rules live in the hook core (src/hooks/hand-back-core.ts) — this file only wires it.
62
+ const handBack = attachCliHandBack(process.argv, process.cwd());
52
63
  const program = new Command();
64
+ // #939: a failed `--json` command prints {"error":{code,message}} on stdout (json-error-on-exit.ts).
65
+ const jsonErrors = attachJsonErrorOnExit(process.argv, (args) => commandSupportsJson(program, args));
53
66
 
54
67
  program
55
68
  .name('sungen')
@@ -97,6 +110,10 @@ registerSetupMobileEnvCommand(program);
97
110
  registerIngestCommand(program);
98
111
  registerEvalCommand(program);
99
112
  registerLoginCommand(program);
113
+ // Test Contract (DOS-14). Registered inline (typed require, still loaded eagerly like every command)
114
+ // so the phase that added it touches ONE line of this file — no import-block edit to merge-conflict.
115
+ (require('./commands/contract') as typeof import('./commands/contract')).registerContractCommand(program);
116
+ registerHookCommand(program); // hidden: Claude Code hooks, JSON on stdout
100
117
 
101
118
  // Capability-contributed CLI commands (Capability SPI): drivers own their authoring commands
102
119
  // (e.g. @sungen/driver-api → `sungen api import`). Discover, then register each.
@@ -108,38 +125,15 @@ registerSetupMobileEnvCommand(program);
108
125
  // Every command warns once when the project's AI assets came from a different
109
126
  // build — `update` is the only thing that refreshes them, and nothing used to
110
127
  // say so (stderr, so `--json` output stays parseable).
111
- program.hook('preAction', () => { warnAssetsDrift(process.cwd()); });
112
-
113
- // #597 — the hand-back, once, for EVERY command. It used to be hardcoded per command and only
114
- // two of twenty-nine printed one, so a run that finished anywhere else finished in silence:
115
- // `capability add` ended with a blank line and the session stopped mid-workflow. Adding a
116
- // footer to the other twenty-seven would repeat the mistake in bulk.
117
- //
118
- // It hangs off `process.on('exit')` rather than a postAction hook because several commands
119
- // exit with a MEANINGFUL code (`depth-lint` returns 2 when there are deepen candidates) and
120
- // `process.exit` skips commander's hooks entirely — a postAction version printed for `audit`
121
- // and silently not for `depth-lint`, which is the same class of gap all over again.
122
- //
123
- // It points at `sungen next` instead of restating a step, so it can never drift from the real
124
- // project state. Skipped on a hard error (code 1): there the error message is the actionable
125
- // thing, and burying it under a footer helps nobody. `--json` keeps stdout parseable.
126
- let handBack: { unit?: string; json: boolean } | null = null;
128
+ // `hook` speaks only JSON to Claude Code — no drift warning there.
127
129
  program.hook('preAction', (_thisCommand, actionCommand) => {
128
- if (actionCommand.name() === 'next') return; // `next` IS the answer
129
- const opts = actionCommand.opts() as Record<string, unknown>;
130
- const unit = [opts.screen, opts.flow, opts.area].find((v) => typeof v === 'string' && v)
131
- ?? (typeof actionCommand.args?.[0] === 'string' ? actionCommand.args[0] : undefined);
132
- // `--grep` is machine output too: callers capture it with `$(…)`, and a footer on stdout
133
- // became part of the regex — the last alternative of `changed --grep` silently matched
134
- // nothing, so `--change-only` skipped its last scenario (#836).
135
- handBack = { unit: unit as string | undefined, json: opts.json === true || opts.grep === true };
130
+ if (actionCommand.name() !== 'hook') warnAssetsDrift(process.cwd());
136
131
  });
137
- process.on('exit', (code) => {
138
- if (!handBack || code === 1) return;
139
- const line = `\nNext: sungen next${handBack.unit ? ` ${handBack.unit}` : ''}`;
140
- // stderr under --json / --grep so the hand-back never lands in the captured payload.
141
- if (handBack.json) process.stderr.write(`${line}\n`);
142
- else process.stdout.write(`${line}\n`);
132
+
133
+ // The action knows its unit and output mode; the hand-back default above is refined here.
134
+ program.hook('preAction', (_thisCommand, actionCommand) => {
135
+ handBack.onAction(actionCommand.name(), actionCommand.opts() as Record<string, unknown>, actionCommand.args);
136
+ jsonErrors.onAction();
143
137
  });
144
138
 
145
139
  await program.parseAsync(process.argv);
@@ -0,0 +1,72 @@
1
+ /**
2
+ * `--json` failures speak JSON too (#939 item 7). A command that supports `--json` and fails used to
3
+ * print its error on stderr and NOTHING on stdout, so a caller parsing stdout got an empty string. Now,
4
+ * when such a command exits non-zero without having written stdout, the exit prints one object:
5
+ *
6
+ * {"error":{"code":"command-failed" | "usage-error","message":"<the error it printed>"}}
7
+ *
8
+ * command-failed the action ran and failed (`next nope --json`)
9
+ * usage-error commander refused the arguments before any action ran (`audit --json --bogus`)
10
+ * The human error stays on stderr, unchanged. A command that printed its own JSON keeps it, whatever
11
+ * its exit code (`contract check --json` exits 2 with the verdict); a command without `--json` is never
12
+ * touched — commander's own "unknown option '--json'" is its usage error, not a JSON caller's.
13
+ * Like the hand-back, it hangs off process exit: commands exit from inside their actions.
14
+ */
15
+ import type { Command } from 'commander';
16
+
17
+ export type JsonErrorCode = 'command-failed' | 'usage-error';
18
+ export interface JsonError { error: { code: JsonErrorCode; message: string } }
19
+
20
+ const ANSI = /\u001b\[[0-9;]*m/g;
21
+ const ERROR_LINE = /^(?:Error|error|Fatal error|❌[^:]*):\s*/;
22
+ const MAX_CAPTURE = 64 * 1024;
23
+
24
+ /** The error object for what the command printed on stderr: from its first error line on, the hand-back dropped. */
25
+ export function jsonErrorPayload(stderr: string, actionRan: boolean, exitCode: number): JsonError {
26
+ const lines = stderr.replace(ANSI, '').split('\n').map((l) => l.trimEnd()).filter((l) => l && !/^Next: /.test(l));
27
+ const at = lines.findIndex((l) => ERROR_LINE.test(l));
28
+ const picked = at >= 0 ? lines.slice(at) : lines.slice(-1);
29
+ const message = picked.join('\n').replace(ERROR_LINE, '').trim() || `exited with code ${exitCode}`;
30
+ return { error: { code: actionRan ? 'command-failed' : 'usage-error', message } };
31
+ }
32
+
33
+ /** The (sub)command `args` name, walked down from `program`, defines `--json`. */
34
+ export function commandSupportsJson(program: Command, args: string[]): boolean {
35
+ let cmd: Command = program;
36
+ for (const a of args) {
37
+ if (a.startsWith('-')) continue;
38
+ const sub = cmd.commands.find((c) => c.name() === a || c.aliases().includes(a));
39
+ if (!sub) break;
40
+ cmd = sub;
41
+ }
42
+ return cmd !== program && cmd.options.some((o) => o.long === '--json');
43
+ }
44
+
45
+ /**
46
+ * Wire it to process exit for `argv` (a no-op without `--json`). `supportsJson` is asked at exit, once
47
+ * every command is registered; `onAction` marks that an action ran (a failure then is not a usage error).
48
+ */
49
+ export function attachJsonErrorOnExit(argv: string[], supportsJson: (args: string[]) => boolean): { onAction: () => void } {
50
+ const args = argv.slice(2);
51
+ if (!args.includes('--json')) return { onAction: () => undefined };
52
+ let wroteStdout = false;
53
+ let stderr = '';
54
+ let actionRan = false;
55
+ const writeOut = process.stdout.write.bind(process.stdout);
56
+ const writeErr = process.stderr.write.bind(process.stderr);
57
+ process.stdout.write = ((chunk: unknown, ...rest: unknown[]) => {
58
+ if (String(chunk).length) wroteStdout = true;
59
+ return (writeOut as (...a: unknown[]) => boolean)(chunk, ...rest);
60
+ }) as typeof process.stdout.write;
61
+ process.stderr.write = ((chunk: unknown, ...rest: unknown[]) => {
62
+ if (stderr.length < MAX_CAPTURE) stderr += String(chunk);
63
+ return (writeErr as (...a: unknown[]) => boolean)(chunk, ...rest);
64
+ }) as typeof process.stderr.write;
65
+ process.on('exit', (code) => {
66
+ try {
67
+ if (code === 0 || wroteStdout || !supportsJson(args)) return;
68
+ writeOut(`${JSON.stringify(jsonErrorPayload(stderr, actionRan, code))}\n`);
69
+ } catch { /* the exit code is the contract; this object is a courtesy */ }
70
+ });
71
+ return { onAction: () => { actionRan = true; } };
72
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * How a hint names sungen inside a project (#939, items 1–2).
3
+ *
4
+ * A project that installs its own sungen (`npm i -D @sun-asterisk/sungen`) runs it with `npx sungen`;
5
+ * a bare `sungen` is whatever global install the machine has — in the field test an older 3.2.24-beta
6
+ * beside the project's 3.3.0-alpha. And `sungen update` without a flag switches to the stable
7
+ * channel, so on an alpha or beta install the update hint must keep the channel it runs on.
8
+ *
9
+ * sungenInvocation(root) 'npx sungen' when <root>/node_modules/@sun-asterisk/sungen exists, else 'sungen'
10
+ * withProjectInvocation(cmd, root) a canonical `sungen …` command as this project runs it
11
+ * withProjectInvocationInText(text, root)
12
+ * every `sungen …` command inside printed text (a refusal, a hint, a
13
+ * step's reason) as this project runs it (#963); prose mentions stay
14
+ * updateCommand(root, version?) `<invocation> update` plus `--alpha` / `--beta` (`--tag <id>` for another prerelease)
15
+ *
16
+ * Only the project root itself is looked at — where `npm i` puts a QA project's install — so a
17
+ * monorepo checkout above a fixture does not turn its hints into `npx`.
18
+ */
19
+ import * as fs from 'fs';
20
+ import * as path from 'path';
21
+ import { getPackageVersion } from '../exporters/package-info';
22
+
23
+ export function sungenInvocation(projectRoot: string): string {
24
+ return fs.existsSync(path.join(projectRoot, 'node_modules', '@sun-asterisk', 'sungen', 'package.json')) ? 'npx sungen' : 'sungen';
25
+ }
26
+
27
+ /** `sungen audit --screen x` → `npx sungen audit --screen x` in a project with its own install; anything else unchanged. */
28
+ export function withProjectInvocation(command: string, projectRoot: string): string {
29
+ const inv = sungenInvocation(projectRoot);
30
+ return inv !== 'sungen' && /^sungen\b/.test(command) ? `${inv}${command.slice('sungen'.length)}` : command;
31
+ }
32
+
33
+ /**
34
+ * A `sungen` that starts a command inside text: at the start of a line (after indentation), after a
35
+ * backtick or `(`, after ": ", "run " or "then " — and followed by a subcommand or an option. A prose
36
+ * mention ("written by sungen 3.3.0", "an older sungen", "sungen: …") is none of these.
37
+ */
38
+ const COMMAND_IN_TEXT = /(^[ \t]*|[`(]|:[ \t]+|\b(?:[Rr]un|then)[ \t]+)sungen(?= [a-z-])/gm;
39
+
40
+ /**
41
+ * Printed text (a refusal, a hint, a step's reason) with every `sungen …` command in it as this project
42
+ * runs sungen (#963): the human-only commands a QA copies from a refusal must run the project's own
43
+ * install, not an older global one. Text for machines (`--json`) stays canonical; this is for the screen.
44
+ */
45
+ export function withProjectInvocationInText(text: string, projectRoot: string): string {
46
+ const inv = sungenInvocation(projectRoot);
47
+ return inv === 'sungen' ? text : text.replace(COMMAND_IN_TEXT, (_m, before: string) => `${before}${inv}`);
48
+ }
49
+
50
+ /** The `sungen update` flag that keeps the channel of `version` (its prerelease id); '' for stable. */
51
+ export function updateChannelFlag(version: string = getPackageVersion()): string {
52
+ const id = version.match(/^\d+\.\d+\.\d+-([0-9A-Za-z-]+)/)?.[1];
53
+ if (!id) return '';
54
+ return id === 'alpha' || id === 'beta' ? ` --${id}` : ` --tag ${id}`;
55
+ }
56
+
57
+ export function updateCommand(projectRoot: string, version: string = getPackageVersion()): string {
58
+ return `${sungenInvocation(projectRoot)} update${updateChannelFlag(version)}`;
59
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The run commands sungen suggests, each writing its results where the reader that asks for them
3
+ * looks (#964). A hint whose results nobody reads leaves a passing run invisible: the plain
4
+ * `npx playwright test` wrote `test-result.json` at the project root, which `sungen next` never reads.
5
+ *
6
+ * generatedSubdir(kind, unit) `specs/generated/<unit>` · `…/flows/<flow>` · `…/api/<area>` — where
7
+ * `generate` writes a unit's specs and `next` / `delivery` read its results
8
+ * plainRunCommand(genRel, feature) one compiled feature's spec with the JSON reporter pointed at
9
+ * `<genRel>/<feature>-test-result.json` (graph/unit-artifact-probes RESULT_FILE)
10
+ * freeRunCommand(cwd) hand-written @free / impl:code tests: the project's free-test config, which
11
+ * writes into its own outputDir `test-results-free/` (#941)
12
+ * freeRunHasResults(cwd) that run left its results (or a sungen run record) there
13
+ */
14
+ import * as fs from 'fs';
15
+ import * as path from 'path';
16
+ import { FREE_RUN_DIR } from '../contract/trace/trace-run-record';
17
+
18
+ export type RunUnitKind = 'screen' | 'flow' | 'api';
19
+
20
+ export function generatedSubdir(kind: RunUnitKind, unit: string): string {
21
+ return path.posix.join('specs', 'generated', ...(kind === 'flow' ? ['flows'] : kind === 'api' ? ['api'] : []), unit);
22
+ }
23
+
24
+ /** `[SUNGEN_ENV=<env> ]PLAYWRIGHT_JSON_OUTPUT_NAME=<genRel>/<feature>-test-result.json npx playwright test <genRel>/<feature>.spec.ts` */
25
+ export function plainRunCommand(genRel: string, featureBaseName: string, env?: string): string {
26
+ return `${env ? `SUNGEN_ENV=${env} ` : ''}PLAYWRIGHT_JSON_OUTPUT_NAME=${genRel}/${featureBaseName}-test-result.json npx playwright test ${genRel}/${featureBaseName}.spec.ts`;
27
+ }
28
+
29
+ const FREE_CONFIG = /^playwright\.free\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
30
+
31
+ /** The free run: `npx playwright test -c <playwright.free.config.*>` when the project has one, else what that config holds. */
32
+ export function freeRunCommand(cwd: string): string {
33
+ let config: string | undefined;
34
+ try { config = fs.readdirSync(cwd).find((f) => FREE_CONFIG.test(f)); } catch { /* no project dir: the generic form */ }
35
+ return config
36
+ ? `npx playwright test -c ${config}`
37
+ : `run the hand-written tests with the project's free-test config (outputDir '${FREE_RUN_DIR}', trace: 'on', the sungen run-record reporter — "Free tests" in the sungen docs)`;
38
+ }
39
+
40
+ /** The free run left its JSON results or a sungen run record in `test-results-free/`. */
41
+ export function freeRunHasResults(cwd: string): boolean {
42
+ try {
43
+ return fs.readdirSync(path.join(cwd, FREE_RUN_DIR)).some((f) => f === 'results.json' || /^sungen-run-record.*\.json$/.test(f));
44
+ } catch {
45
+ return false; // never run
46
+ }
47
+ }