@zigrivers/scaffold 2.1.2 → 2.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/README.md +505 -119
  2. package/dist/cli/commands/build.d.ts.map +1 -1
  3. package/dist/cli/commands/build.js +94 -14
  4. package/dist/cli/commands/build.js.map +1 -1
  5. package/dist/cli/commands/build.test.js +30 -5
  6. package/dist/cli/commands/build.test.js.map +1 -1
  7. package/dist/cli/commands/check.d.ts +12 -0
  8. package/dist/cli/commands/check.d.ts.map +1 -0
  9. package/dist/cli/commands/check.js +311 -0
  10. package/dist/cli/commands/check.js.map +1 -0
  11. package/dist/cli/commands/check.test.d.ts +2 -0
  12. package/dist/cli/commands/check.test.d.ts.map +1 -0
  13. package/dist/cli/commands/check.test.js +412 -0
  14. package/dist/cli/commands/check.test.js.map +1 -0
  15. package/dist/cli/commands/complete.d.ts +12 -0
  16. package/dist/cli/commands/complete.d.ts.map +1 -0
  17. package/dist/cli/commands/complete.js +101 -0
  18. package/dist/cli/commands/complete.js.map +1 -0
  19. package/dist/cli/commands/complete.test.d.ts +2 -0
  20. package/dist/cli/commands/complete.test.d.ts.map +1 -0
  21. package/dist/cli/commands/complete.test.js +133 -0
  22. package/dist/cli/commands/complete.test.js.map +1 -0
  23. package/dist/cli/commands/dashboard.d.ts.map +1 -1
  24. package/dist/cli/commands/dashboard.js +12 -8
  25. package/dist/cli/commands/dashboard.js.map +1 -1
  26. package/dist/cli/commands/info.d.ts.map +1 -1
  27. package/dist/cli/commands/info.js +4 -0
  28. package/dist/cli/commands/info.js.map +1 -1
  29. package/dist/cli/commands/knowledge.d.ts.map +1 -1
  30. package/dist/cli/commands/knowledge.js +6 -2
  31. package/dist/cli/commands/knowledge.js.map +1 -1
  32. package/dist/cli/commands/knowledge.test.js +16 -11
  33. package/dist/cli/commands/knowledge.test.js.map +1 -1
  34. package/dist/cli/commands/next.d.ts.map +1 -1
  35. package/dist/cli/commands/next.js +41 -13
  36. package/dist/cli/commands/next.js.map +1 -1
  37. package/dist/cli/commands/next.test.js +3 -0
  38. package/dist/cli/commands/next.test.js.map +1 -1
  39. package/dist/cli/commands/reset.d.ts +1 -0
  40. package/dist/cli/commands/reset.d.ts.map +1 -1
  41. package/dist/cli/commands/reset.js +179 -67
  42. package/dist/cli/commands/reset.js.map +1 -1
  43. package/dist/cli/commands/reset.test.js +360 -0
  44. package/dist/cli/commands/reset.test.js.map +1 -1
  45. package/dist/cli/commands/rework.d.ts +20 -0
  46. package/dist/cli/commands/rework.d.ts.map +1 -0
  47. package/dist/cli/commands/rework.js +332 -0
  48. package/dist/cli/commands/rework.js.map +1 -0
  49. package/dist/cli/commands/rework.test.d.ts +2 -0
  50. package/dist/cli/commands/rework.test.d.ts.map +1 -0
  51. package/dist/cli/commands/rework.test.js +297 -0
  52. package/dist/cli/commands/rework.test.js.map +1 -0
  53. package/dist/cli/commands/run.d.ts.map +1 -1
  54. package/dist/cli/commands/run.js +59 -31
  55. package/dist/cli/commands/run.js.map +1 -1
  56. package/dist/cli/commands/run.test.js +288 -6
  57. package/dist/cli/commands/run.test.js.map +1 -1
  58. package/dist/cli/commands/skill.d.ts +12 -0
  59. package/dist/cli/commands/skill.d.ts.map +1 -0
  60. package/dist/cli/commands/skill.js +123 -0
  61. package/dist/cli/commands/skill.js.map +1 -0
  62. package/dist/cli/commands/skill.test.d.ts +2 -0
  63. package/dist/cli/commands/skill.test.d.ts.map +1 -0
  64. package/dist/cli/commands/skill.test.js +297 -0
  65. package/dist/cli/commands/skill.test.js.map +1 -0
  66. package/dist/cli/commands/skip.d.ts +1 -1
  67. package/dist/cli/commands/skip.d.ts.map +1 -1
  68. package/dist/cli/commands/skip.js +123 -57
  69. package/dist/cli/commands/skip.js.map +1 -1
  70. package/dist/cli/commands/skip.test.js +91 -0
  71. package/dist/cli/commands/skip.test.js.map +1 -1
  72. package/dist/cli/commands/status.d.ts +1 -0
  73. package/dist/cli/commands/status.d.ts.map +1 -1
  74. package/dist/cli/commands/status.js +57 -10
  75. package/dist/cli/commands/status.js.map +1 -1
  76. package/dist/cli/commands/status.test.js +81 -0
  77. package/dist/cli/commands/status.test.js.map +1 -1
  78. package/dist/cli/commands/update.test.js +252 -0
  79. package/dist/cli/commands/update.test.js.map +1 -1
  80. package/dist/cli/commands/version.test.js +171 -1
  81. package/dist/cli/commands/version.test.js.map +1 -1
  82. package/dist/cli/index.d.ts.map +1 -1
  83. package/dist/cli/index.js +8 -0
  84. package/dist/cli/index.js.map +1 -1
  85. package/dist/core/adapters/adapter.d.ts +14 -0
  86. package/dist/core/adapters/adapter.d.ts.map +1 -1
  87. package/dist/core/adapters/adapter.js.map +1 -1
  88. package/dist/core/adapters/adapter.test.js +10 -0
  89. package/dist/core/adapters/adapter.test.js.map +1 -1
  90. package/dist/core/adapters/claude-code.d.ts.map +1 -1
  91. package/dist/core/adapters/claude-code.js +47 -10
  92. package/dist/core/adapters/claude-code.js.map +1 -1
  93. package/dist/core/adapters/claude-code.test.js +41 -20
  94. package/dist/core/adapters/claude-code.test.js.map +1 -1
  95. package/dist/core/adapters/codex.d.ts.map +1 -1
  96. package/dist/core/adapters/codex.js +5 -1
  97. package/dist/core/adapters/codex.js.map +1 -1
  98. package/dist/core/adapters/codex.test.js +5 -0
  99. package/dist/core/adapters/codex.test.js.map +1 -1
  100. package/dist/core/adapters/universal.d.ts.map +1 -1
  101. package/dist/core/adapters/universal.js +0 -1
  102. package/dist/core/adapters/universal.js.map +1 -1
  103. package/dist/core/adapters/universal.test.js +5 -0
  104. package/dist/core/adapters/universal.test.js.map +1 -1
  105. package/dist/core/assembly/context-gatherer.d.ts.map +1 -1
  106. package/dist/core/assembly/context-gatherer.js +5 -2
  107. package/dist/core/assembly/context-gatherer.js.map +1 -1
  108. package/dist/core/assembly/engine.d.ts.map +1 -1
  109. package/dist/core/assembly/engine.js +10 -2
  110. package/dist/core/assembly/engine.js.map +1 -1
  111. package/dist/core/assembly/engine.test.js +19 -0
  112. package/dist/core/assembly/engine.test.js.map +1 -1
  113. package/dist/core/assembly/knowledge-loader.d.ts +25 -0
  114. package/dist/core/assembly/knowledge-loader.d.ts.map +1 -1
  115. package/dist/core/assembly/knowledge-loader.js +75 -2
  116. package/dist/core/assembly/knowledge-loader.js.map +1 -1
  117. package/dist/core/assembly/knowledge-loader.test.js +388 -1
  118. package/dist/core/assembly/knowledge-loader.test.js.map +1 -1
  119. package/dist/core/assembly/meta-prompt-loader.d.ts +6 -0
  120. package/dist/core/assembly/meta-prompt-loader.d.ts.map +1 -1
  121. package/dist/core/assembly/meta-prompt-loader.js +41 -25
  122. package/dist/core/assembly/meta-prompt-loader.js.map +1 -1
  123. package/dist/core/assembly/preset-loader.d.ts +10 -0
  124. package/dist/core/assembly/preset-loader.d.ts.map +1 -1
  125. package/dist/core/assembly/preset-loader.js +26 -1
  126. package/dist/core/assembly/preset-loader.js.map +1 -1
  127. package/dist/core/assembly/preset-loader.test.js +65 -1
  128. package/dist/core/assembly/preset-loader.test.js.map +1 -1
  129. package/dist/core/assembly/update-mode.d.ts.map +1 -1
  130. package/dist/core/assembly/update-mode.js +10 -4
  131. package/dist/core/assembly/update-mode.js.map +1 -1
  132. package/dist/core/assembly/update-mode.test.js +47 -0
  133. package/dist/core/assembly/update-mode.test.js.map +1 -1
  134. package/dist/core/dependency/dependency.d.ts.map +1 -1
  135. package/dist/core/dependency/dependency.js +3 -2
  136. package/dist/core/dependency/dependency.js.map +1 -1
  137. package/dist/core/dependency/dependency.test.js +2 -0
  138. package/dist/core/dependency/dependency.test.js.map +1 -1
  139. package/dist/core/dependency/eligibility.js +3 -3
  140. package/dist/core/dependency/eligibility.js.map +1 -1
  141. package/dist/core/dependency/eligibility.test.js +2 -0
  142. package/dist/core/dependency/eligibility.test.js.map +1 -1
  143. package/dist/core/dependency/graph.d.ts.map +1 -1
  144. package/dist/core/dependency/graph.js +4 -0
  145. package/dist/core/dependency/graph.js.map +1 -1
  146. package/dist/core/dependency/graph.test.d.ts +2 -0
  147. package/dist/core/dependency/graph.test.d.ts.map +1 -0
  148. package/dist/core/dependency/graph.test.js +262 -0
  149. package/dist/core/dependency/graph.test.js.map +1 -0
  150. package/dist/core/rework/phase-selector.d.ts +24 -0
  151. package/dist/core/rework/phase-selector.d.ts.map +1 -0
  152. package/dist/core/rework/phase-selector.js +98 -0
  153. package/dist/core/rework/phase-selector.js.map +1 -0
  154. package/dist/core/rework/phase-selector.test.d.ts +2 -0
  155. package/dist/core/rework/phase-selector.test.d.ts.map +1 -0
  156. package/dist/core/rework/phase-selector.test.js +138 -0
  157. package/dist/core/rework/phase-selector.test.js.map +1 -0
  158. package/dist/dashboard/generator.d.ts +48 -17
  159. package/dist/dashboard/generator.d.ts.map +1 -1
  160. package/dist/dashboard/generator.js +75 -5
  161. package/dist/dashboard/generator.js.map +1 -1
  162. package/dist/dashboard/generator.test.js +213 -5
  163. package/dist/dashboard/generator.test.js.map +1 -1
  164. package/dist/dashboard/template.d.ts +1 -1
  165. package/dist/dashboard/template.d.ts.map +1 -1
  166. package/dist/dashboard/template.js +755 -114
  167. package/dist/dashboard/template.js.map +1 -1
  168. package/dist/e2e/knowledge.test.js +4 -3
  169. package/dist/e2e/knowledge.test.js.map +1 -1
  170. package/dist/e2e/pipeline.test.js +2 -0
  171. package/dist/e2e/pipeline.test.js.map +1 -1
  172. package/dist/e2e/rework.test.d.ts +6 -0
  173. package/dist/e2e/rework.test.d.ts.map +1 -0
  174. package/dist/e2e/rework.test.js +226 -0
  175. package/dist/e2e/rework.test.js.map +1 -0
  176. package/dist/index.js +0 -0
  177. package/dist/project/adopt.test.js +2 -0
  178. package/dist/project/adopt.test.js.map +1 -1
  179. package/dist/project/claude-md.js +2 -2
  180. package/dist/project/claude-md.js.map +1 -1
  181. package/dist/project/claude-md.test.js +4 -4
  182. package/dist/project/claude-md.test.js.map +1 -1
  183. package/dist/project/detector.d.ts.map +1 -1
  184. package/dist/project/detector.js +4 -1
  185. package/dist/project/detector.js.map +1 -1
  186. package/dist/project/frontmatter.d.ts.map +1 -1
  187. package/dist/project/frontmatter.js +54 -15
  188. package/dist/project/frontmatter.js.map +1 -1
  189. package/dist/project/frontmatter.test.js +2 -2
  190. package/dist/project/frontmatter.test.js.map +1 -1
  191. package/dist/state/rework-manager.d.ts +16 -0
  192. package/dist/state/rework-manager.d.ts.map +1 -0
  193. package/dist/state/rework-manager.js +126 -0
  194. package/dist/state/rework-manager.js.map +1 -0
  195. package/dist/state/rework-manager.test.d.ts +2 -0
  196. package/dist/state/rework-manager.test.d.ts.map +1 -0
  197. package/dist/state/rework-manager.test.js +191 -0
  198. package/dist/state/rework-manager.test.js.map +1 -0
  199. package/dist/state/state-manager.d.ts +13 -0
  200. package/dist/state/state-manager.d.ts.map +1 -1
  201. package/dist/state/state-manager.js +39 -2
  202. package/dist/state/state-manager.js.map +1 -1
  203. package/dist/state/state-manager.test.js +74 -1
  204. package/dist/state/state-manager.test.js.map +1 -1
  205. package/dist/state/state-migration.d.ts +23 -0
  206. package/dist/state/state-migration.d.ts.map +1 -0
  207. package/dist/state/state-migration.js +144 -0
  208. package/dist/state/state-migration.js.map +1 -0
  209. package/dist/state/state-migration.test.d.ts +2 -0
  210. package/dist/state/state-migration.test.d.ts.map +1 -0
  211. package/dist/state/state-migration.test.js +451 -0
  212. package/dist/state/state-migration.test.js.map +1 -0
  213. package/dist/types/assembly.d.ts +2 -0
  214. package/dist/types/assembly.d.ts.map +1 -1
  215. package/dist/types/dependency.d.ts +2 -2
  216. package/dist/types/dependency.d.ts.map +1 -1
  217. package/dist/types/frontmatter.d.ts +100 -7
  218. package/dist/types/frontmatter.d.ts.map +1 -1
  219. package/dist/types/frontmatter.js +89 -1
  220. package/dist/types/frontmatter.js.map +1 -1
  221. package/dist/types/index.d.ts +1 -0
  222. package/dist/types/index.d.ts.map +1 -1
  223. package/dist/types/index.js +1 -0
  224. package/dist/types/index.js.map +1 -1
  225. package/dist/types/lock.d.ts +1 -1
  226. package/dist/types/lock.d.ts.map +1 -1
  227. package/dist/types/rework.d.ts +36 -0
  228. package/dist/types/rework.d.ts.map +1 -0
  229. package/dist/types/rework.js +2 -0
  230. package/dist/types/rework.js.map +1 -0
  231. package/dist/utils/errors.d.ts +1 -0
  232. package/dist/utils/errors.d.ts.map +1 -1
  233. package/dist/utils/errors.js +8 -0
  234. package/dist/utils/errors.js.map +1 -1
  235. package/dist/utils/fs.d.ts +6 -0
  236. package/dist/utils/fs.d.ts.map +1 -1
  237. package/dist/utils/fs.js +13 -0
  238. package/dist/utils/fs.js.map +1 -1
  239. package/dist/validation/config-validator.test.d.ts +2 -0
  240. package/dist/validation/config-validator.test.d.ts.map +1 -0
  241. package/dist/validation/config-validator.test.js +210 -0
  242. package/dist/validation/config-validator.test.js.map +1 -0
  243. package/dist/validation/dependency-validator.test.d.ts +2 -0
  244. package/dist/validation/dependency-validator.test.d.ts.map +1 -0
  245. package/dist/validation/dependency-validator.test.js +215 -0
  246. package/dist/validation/dependency-validator.test.js.map +1 -0
  247. package/dist/validation/frontmatter-validator.test.d.ts +2 -0
  248. package/dist/validation/frontmatter-validator.test.d.ts.map +1 -0
  249. package/dist/validation/frontmatter-validator.test.js +371 -0
  250. package/dist/validation/frontmatter-validator.test.js.map +1 -0
  251. package/dist/validation/state-validator.test.d.ts +2 -0
  252. package/dist/validation/state-validator.test.d.ts.map +1 -0
  253. package/dist/validation/state-validator.test.js +325 -0
  254. package/dist/validation/state-validator.test.js.map +1 -0
  255. package/dist/wizard/suggestion.test.d.ts +2 -0
  256. package/dist/wizard/suggestion.test.d.ts.map +1 -0
  257. package/dist/wizard/suggestion.test.js +115 -0
  258. package/dist/wizard/suggestion.test.js.map +1 -0
  259. package/dist/wizard/wizard.d.ts.map +1 -1
  260. package/dist/wizard/wizard.js +34 -1
  261. package/dist/wizard/wizard.js.map +1 -1
  262. package/knowledge/core/adr-craft.md +57 -0
  263. package/knowledge/core/ai-memory-management.md +246 -0
  264. package/knowledge/core/api-design.md +8 -0
  265. package/knowledge/core/automated-review-tooling.md +203 -0
  266. package/knowledge/core/claude-md-patterns.md +254 -0
  267. package/knowledge/core/coding-conventions.md +246 -0
  268. package/knowledge/core/database-design.md +8 -0
  269. package/knowledge/core/design-system-tokens.md +469 -0
  270. package/knowledge/core/dev-environment.md +223 -0
  271. package/knowledge/core/domain-modeling.md +8 -0
  272. package/knowledge/core/eval-craft.md +1008 -0
  273. package/knowledge/core/git-workflow-patterns.md +200 -0
  274. package/knowledge/core/multi-model-review-dispatch.md +250 -0
  275. package/knowledge/core/operations-runbook.md +40 -225
  276. package/knowledge/core/project-structure-patterns.md +231 -0
  277. package/knowledge/core/review-step-template.md +247 -0
  278. package/knowledge/core/{security-review.md → security-best-practices.md} +9 -1
  279. package/knowledge/core/system-architecture.md +5 -1
  280. package/knowledge/core/task-decomposition.md +174 -36
  281. package/knowledge/core/task-tracking.md +225 -0
  282. package/knowledge/core/tech-stack-selection.md +214 -0
  283. package/knowledge/core/testing-strategy.md +63 -70
  284. package/knowledge/core/user-stories.md +69 -60
  285. package/knowledge/core/user-story-innovation.md +70 -0
  286. package/knowledge/core/ux-specification.md +18 -148
  287. package/knowledge/execution/enhancement-workflow.md +201 -0
  288. package/knowledge/execution/task-claiming-strategy.md +130 -0
  289. package/knowledge/execution/tdd-execution-loop.md +172 -0
  290. package/knowledge/execution/worktree-management.md +205 -0
  291. package/knowledge/finalization/apply-fixes-and-freeze.md +177 -14
  292. package/knowledge/finalization/developer-onboarding.md +4 -0
  293. package/knowledge/finalization/implementation-playbook.md +83 -5
  294. package/knowledge/product/gap-analysis.md +5 -1
  295. package/knowledge/product/prd-craft.md +55 -34
  296. package/knowledge/product/prd-innovation.md +12 -0
  297. package/knowledge/product/vision-craft.md +213 -0
  298. package/knowledge/review/review-adr.md +44 -0
  299. package/knowledge/review/{review-api-contracts.md → review-api-design.md} +47 -1
  300. package/knowledge/review/{review-database-schema.md → review-database-design.md} +40 -1
  301. package/knowledge/review/review-domain-modeling.md +38 -1
  302. package/knowledge/review/review-implementation-tasks.md +108 -1
  303. package/knowledge/review/review-methodology.md +11 -0
  304. package/knowledge/review/review-operations.md +67 -0
  305. package/knowledge/review/review-prd.md +46 -0
  306. package/knowledge/review/review-security.md +65 -0
  307. package/knowledge/review/review-system-architecture.md +32 -2
  308. package/knowledge/review/review-testing-strategy.md +62 -0
  309. package/knowledge/review/review-user-stories.md +65 -0
  310. package/knowledge/review/{review-ux-spec.md → review-ux-specification.md} +50 -2
  311. package/knowledge/review/review-vision.md +255 -0
  312. package/knowledge/tools/release-management.md +222 -0
  313. package/knowledge/tools/session-analysis.md +215 -0
  314. package/knowledge/tools/version-strategy.md +200 -0
  315. package/knowledge/validation/critical-path-analysis.md +1 -1
  316. package/knowledge/validation/cross-phase-consistency.md +12 -0
  317. package/knowledge/validation/decision-completeness.md +13 -1
  318. package/knowledge/validation/dependency-validation.md +12 -0
  319. package/knowledge/validation/scope-management.md +12 -0
  320. package/knowledge/validation/traceability.md +12 -0
  321. package/methodology/README.md +37 -0
  322. package/methodology/custom-defaults.yml +44 -4
  323. package/methodology/deep.yml +43 -3
  324. package/methodology/mvp.yml +43 -3
  325. package/package.json +4 -3
  326. package/pipeline/architecture/review-architecture.md +36 -13
  327. package/pipeline/architecture/system-architecture.md +24 -9
  328. package/pipeline/build/multi-agent-resume.md +245 -0
  329. package/pipeline/build/multi-agent-start.md +236 -0
  330. package/pipeline/build/new-enhancement.md +456 -0
  331. package/pipeline/build/quick-task.md +381 -0
  332. package/pipeline/build/single-agent-resume.md +210 -0
  333. package/pipeline/build/single-agent-start.md +207 -0
  334. package/pipeline/consolidation/claude-md-optimization.md +76 -0
  335. package/pipeline/consolidation/workflow-audit.md +77 -0
  336. package/pipeline/decisions/adrs.md +21 -7
  337. package/pipeline/decisions/review-adrs.md +32 -11
  338. package/pipeline/environment/ai-memory-setup.md +76 -0
  339. package/pipeline/environment/automated-pr-review.md +76 -0
  340. package/pipeline/environment/design-system.md +75 -0
  341. package/pipeline/environment/dev-env-setup.md +68 -0
  342. package/pipeline/environment/git-workflow.md +73 -0
  343. package/pipeline/finalization/apply-fixes-and-freeze.md +17 -6
  344. package/pipeline/finalization/developer-onboarding-guide.md +23 -9
  345. package/pipeline/finalization/implementation-playbook.md +43 -14
  346. package/pipeline/foundation/beads.md +71 -0
  347. package/pipeline/foundation/coding-standards.md +71 -0
  348. package/pipeline/foundation/project-structure.md +73 -0
  349. package/pipeline/foundation/tdd.md +64 -0
  350. package/pipeline/foundation/tech-stack.md +74 -0
  351. package/pipeline/integration/add-e2e-testing.md +80 -0
  352. package/pipeline/modeling/domain-modeling.md +23 -8
  353. package/pipeline/modeling/review-domain-modeling.md +35 -11
  354. package/pipeline/parity/platform-parity-review.md +90 -0
  355. package/pipeline/planning/implementation-plan-review.md +67 -0
  356. package/pipeline/planning/implementation-plan.md +110 -0
  357. package/pipeline/pre/create-prd.md +34 -10
  358. package/pipeline/pre/innovate-prd.md +46 -15
  359. package/pipeline/pre/innovate-user-stories.md +47 -14
  360. package/pipeline/pre/review-prd.md +29 -8
  361. package/pipeline/pre/review-user-stories.md +34 -8
  362. package/pipeline/pre/user-stories.md +23 -8
  363. package/pipeline/quality/create-evals.md +106 -0
  364. package/pipeline/quality/operations.md +46 -17
  365. package/pipeline/quality/review-operations.md +32 -11
  366. package/pipeline/quality/review-security.md +34 -12
  367. package/pipeline/quality/review-testing.md +37 -14
  368. package/pipeline/quality/security.md +36 -10
  369. package/pipeline/quality/story-tests.md +75 -0
  370. package/pipeline/specification/api-contracts.md +28 -8
  371. package/pipeline/specification/database-schema.md +29 -8
  372. package/pipeline/specification/review-api.md +32 -11
  373. package/pipeline/specification/review-database.md +32 -11
  374. package/pipeline/specification/review-ux.md +34 -12
  375. package/pipeline/specification/ux-spec.md +35 -13
  376. package/pipeline/validation/critical-path-walkthrough.md +45 -11
  377. package/pipeline/validation/cross-phase-consistency.md +45 -11
  378. package/pipeline/validation/decision-completeness.md +45 -11
  379. package/pipeline/validation/dependency-graph-validation.md +46 -11
  380. package/pipeline/validation/implementability-dry-run.md +46 -11
  381. package/pipeline/validation/scope-creep-check.md +46 -11
  382. package/pipeline/validation/traceability-matrix.md +51 -11
  383. package/pipeline/vision/create-vision.md +267 -0
  384. package/pipeline/vision/innovate-vision.md +157 -0
  385. package/pipeline/vision/review-vision.md +149 -0
  386. package/skills/multi-model-dispatch/SKILL.md +326 -0
  387. package/skills/scaffold-pipeline/SKILL.md +210 -0
  388. package/skills/scaffold-runner/SKILL.md +619 -0
  389. package/pipeline/planning/implementation-tasks.md +0 -57
  390. package/pipeline/planning/review-tasks.md +0 -38
  391. package/pipeline/quality/testing-strategy.md +0 -42
@@ -1,43 +1,40 @@
1
+ export function escapeHtml(s) {
2
+ return s
3
+ .replace(/&/g, '&')
4
+ .replace(/</g, '&lt;')
5
+ .replace(/>/g, '&gt;')
6
+ .replace(/"/g, '&quot;');
7
+ }
8
+ /* eslint-disable max-len */
1
9
  export function buildTemplate(dataJson, data) {
2
10
  const completedPct = data.progress.percentage;
3
11
  const skippedPct = data.progress.total > 0
4
12
  ? Math.round(data.progress.skipped / data.progress.total * 100)
5
13
  : 0;
6
- const icons = {
7
- completed: '&#10003;',
8
- skipped: '&#8594;',
9
- in_progress: '&#9679;',
10
- pending: '&#9675;',
11
- };
12
- const stepRows = data.steps.map(step => {
13
- const icon = icons[step.status] ?? '?';
14
- const statusClass = step.status.replace('_', '-');
15
- const name = escapeHtml(step.slug);
16
- return [
17
- `<div class="step-row status-${statusClass}">`,
18
- `<span class="step-icon">${icon}</span> `,
19
- `<span class="step-name">${name}</span></div>`,
20
- ].join('');
21
- }).join('\n');
22
- const decisionRows = data.decisions.map(d => {
23
- const prov = d.provisional
24
- ? ' <span class="provisional-badge">provisional</span>'
25
- : '';
26
- const id = escapeHtml(d.id);
27
- const step = escapeHtml(d.step);
28
- const decision = escapeHtml(d.decision);
29
- // eslint-disable-next-line max-len
30
- return `<div class="decision-row"><span class="decision-id">${id}</span> <span class="decision-step">[${step}]</span>${prov}: ${decision}</div>`;
31
- }).join('\n');
32
- // Check if data is stale (older than 1 hour)
14
+ // Stale notice (server-side rendered)
33
15
  const generatedAt = new Date(data.generatedAt);
34
16
  const ageMs = Date.now() - generatedAt.getTime();
35
- const staleHtml = [
36
- '<div id="stale-notice" class="stale-notice">',
37
- '&#9888; Data may be stale (generated more than 1 hour ago)',
38
- '</div>',
39
- ].join('');
40
- const staleNotice = ageMs > 3600000 ? staleHtml : '';
17
+ const staleNotice = ageMs > 3600000
18
+ ? [
19
+ '<div id="stale-notice" class="stale-notice">',
20
+ '&#9888; Data may be stale (generated more than 1 hour ago)',
21
+ '</div>',
22
+ ].join('')
23
+ : '';
24
+ // What's Next banner (server-side rendered)
25
+ const whatsNextBanner = data.nextEligible
26
+ ? [
27
+ '<div class="whats-next" id="whats-next">',
28
+ ' <div class="whats-next-label">What\'s Next</div>',
29
+ ` <div class="whats-next-title">${escapeHtml(data.nextEligible.slug)}</div>`,
30
+ data.nextEligible.summary
31
+ ? ` <div class="whats-next-summary">${escapeHtml(data.nextEligible.summary)}</div>`
32
+ : '',
33
+ ` <div class="whats-next-desc">${escapeHtml(data.nextEligible.description)}</div>`,
34
+ ` <code class="whats-next-cmd" onclick="copyCommand('${escapeHtml(data.nextEligible.command)}')">${escapeHtml(data.nextEligible.command)}</code>`,
35
+ '</div>',
36
+ ].filter(Boolean).join('\n')
37
+ : '';
41
38
  const methodology = escapeHtml(data.methodology);
42
39
  const pct = data.progress.percentage;
43
40
  return `<!DOCTYPE html>
@@ -50,102 +47,460 @@ export function buildTemplate(dataJson, data) {
50
47
  ${dataJson}
51
48
  </script>
52
49
  <style>
53
- :root {
54
- --color-success: #22c55e;
55
- --color-warning: #f59e0b;
56
- --color-danger: #ef4444;
57
- --color-pending: #94a3b8;
58
- --color-skipped: #60a5fa;
59
- --color-bg: #ffffff;
60
- --color-text: #1e293b;
61
- --color-border: #e2e8f0;
62
- --max-width: 1200px;
63
- }
50
+ /* --- Dark theme (default) --- */
64
51
  [data-theme="dark"] {
65
- --color-bg: #0f172a;
66
- --color-text: #f1f5f9;
67
- --color-border: #334155;
52
+ --bg: #0f172a;
53
+ --card-bg: #1e293b;
54
+ --border: #334155;
55
+ --text: #e2e8f0;
56
+ --muted: #94a3b8;
57
+ --faint: #64748b;
58
+ --status-completed: #4ade80;
59
+ --status-skipped: #818cf8;
60
+ --status-in-progress: #fbbf24;
61
+ --status-pending: #64748b;
62
+ --accent: #6366f1;
63
+ --accent-light: #818cf8;
64
+ --modal-backdrop: rgba(0,0,0,0.6);
65
+ --stale-bg: #451a03;
66
+ --stale-text: #fef3c7;
67
+ --badge-prov-bg: #451a03;
68
+ --badge-prov-text: #fbbf24;
68
69
  }
69
- @media (prefers-color-scheme: dark) {
70
- :root { --color-bg: #0f172a; --color-text: #f1f5f9; --color-border: #334155; }
70
+
71
+ /* --- Light theme --- */
72
+ [data-theme="light"] {
73
+ --bg: #f8fafc;
74
+ --card-bg: #ffffff;
75
+ --border: #e2e8f0;
76
+ --text: #1e293b;
77
+ --muted: #64748b;
78
+ --faint: #94a3b8;
79
+ --status-completed: #4ade80;
80
+ --status-skipped: #818cf8;
81
+ --status-in-progress: #fbbf24;
82
+ --status-pending: #64748b;
83
+ --accent: #6366f1;
84
+ --accent-light: #818cf8;
85
+ --modal-backdrop: rgba(0,0,0,0.4);
86
+ --stale-bg: #fef3c7;
87
+ --stale-text: #92400e;
88
+ --badge-prov-bg: #fef3c7;
89
+ --badge-prov-text: #92400e;
71
90
  }
91
+
92
+ *, *::before, *::after { box-sizing: border-box; }
93
+
72
94
  body {
73
- font-family: system-ui, sans-serif;
74
- background: var(--color-bg);
75
- color: var(--color-text);
95
+ font-family: system-ui, -apple-system, sans-serif;
96
+ background: var(--bg);
97
+ color: var(--text);
76
98
  margin: 0;
77
- padding: 16px;
99
+ padding: 24px;
100
+ line-height: 1.5;
78
101
  }
79
- .container { max-width: var(--max-width); margin: 0 auto; }
102
+
103
+ .container { max-width: 960px; margin: 0 auto; }
104
+
105
+ /* --- Header --- */
80
106
  .header {
81
107
  display: flex;
82
108
  justify-content: space-between;
83
- align-items: center;
109
+ align-items: flex-start;
84
110
  margin-bottom: 24px;
111
+ flex-wrap: wrap;
112
+ gap: 12px;
113
+ }
114
+ .header h1 { margin: 0 0 4px; font-size: 1.5rem; }
115
+ .header-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
116
+ .methodology-badge {
117
+ background: var(--accent);
118
+ color: #fff;
119
+ padding: 2px 10px;
120
+ border-radius: 12px;
121
+ font-size: 0.8rem;
122
+ font-weight: 600;
123
+ text-transform: uppercase;
124
+ }
125
+ .pct-label { color: var(--muted); font-size: 0.9rem; }
126
+ .theme-toggle {
127
+ cursor: pointer;
128
+ background: var(--card-bg);
129
+ border: 1px solid var(--border);
130
+ padding: 6px 14px;
131
+ border-radius: 6px;
132
+ color: var(--text);
133
+ font-size: 0.85rem;
134
+ }
135
+ .theme-toggle:hover { border-color: var(--accent); }
136
+
137
+ /* --- Stale notice --- */
138
+ .stale-notice {
139
+ background: var(--stale-bg);
140
+ color: var(--stale-text);
141
+ padding: 10px 16px;
142
+ border-radius: 6px;
143
+ margin-bottom: 16px;
144
+ font-size: 0.9rem;
85
145
  }
146
+
147
+ /* --- Progress bar --- */
86
148
  .progress-bar {
87
- height: 8px;
88
- background: var(--color-border);
89
- border-radius: 4px;
90
- margin: 16px 0;
149
+ height: 10px;
150
+ background: var(--border);
151
+ border-radius: 5px;
152
+ margin: 0 0 24px;
91
153
  overflow: hidden;
154
+ display: flex;
92
155
  }
93
- .progress-completed { height: 100%; background: var(--color-success); float: left; }
94
- .progress-skipped { height: 100%; background: var(--color-skipped); float: left; }
156
+ .progress-completed { height: 100%; background: var(--status-completed); }
157
+ .progress-skipped { height: 100%; background: var(--status-skipped); }
158
+
159
+ /* --- Summary cards --- */
95
160
  .summary-cards {
96
161
  display: grid;
97
- grid-template-columns: repeat(4, 1fr);
162
+ grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
98
163
  gap: 16px;
99
- margin-bottom: 24px;
164
+ margin-bottom: 28px;
100
165
  }
101
- .card { padding: 16px; border: 1px solid var(--color-border); border-radius: 8px; text-align: center; }
102
- .card-number { font-size: 2rem; font-weight: bold; }
103
- .step-row { padding: 8px; border-bottom: 1px solid var(--color-border); }
104
- .status-completed .step-icon { color: var(--color-success); }
105
- .status-pending .step-icon { color: var(--color-pending); }
106
- .status-in-progress .step-icon { color: var(--color-warning); }
107
- .status-skipped .step-icon { color: var(--color-skipped); }
108
- .stale-notice { background: #fef3c7; padding: 8px 16px; border-radius: 4px; margin-bottom: 16px; }
109
- [data-theme="dark"] .stale-notice { background: #451a03; color: #fef3c7; }
110
- .theme-toggle {
166
+ .card {
167
+ background: var(--card-bg);
168
+ padding: 16px;
169
+ border: 1px solid var(--border);
170
+ border-radius: 10px;
171
+ text-align: center;
172
+ }
173
+ .card-number { font-size: 2rem; font-weight: 700; }
174
+ .card-label { color: var(--muted); font-size: 0.85rem; margin-top: 2px; }
175
+ .card-completed .card-number { color: var(--status-completed); }
176
+ .card-skipped .card-number { color: var(--status-skipped); }
177
+ .card-pending .card-number { color: var(--status-pending); }
178
+ .card-in-progress .card-number { color: var(--status-in-progress); }
179
+
180
+ /* --- What's Next banner --- */
181
+ .whats-next {
182
+ background: linear-gradient(135deg, var(--accent) 0%, #4f46e5 100%);
183
+ border-left: 5px solid var(--accent-light);
184
+ border-radius: 10px;
185
+ padding: 20px 24px;
186
+ margin-bottom: 28px;
187
+ color: #fff;
188
+ }
189
+ .whats-next-label {
190
+ font-size: 0.75rem;
191
+ text-transform: uppercase;
192
+ letter-spacing: 0.05em;
193
+ opacity: 0.85;
194
+ margin-bottom: 4px;
195
+ }
196
+ .whats-next-title { font-size: 1.15rem; font-weight: 700; margin-bottom: 4px; }
197
+ .whats-next-summary { font-size: 0.9rem; opacity: 0.9; margin-bottom: 4px; }
198
+ .whats-next-desc { font-size: 0.85rem; opacity: 0.8; margin-bottom: 10px; }
199
+ .whats-next-cmd {
200
+ display: inline-block;
201
+ background: rgba(255,255,255,0.15);
202
+ padding: 4px 12px;
203
+ border-radius: 6px;
204
+ font-size: 0.85rem;
205
+ cursor: pointer;
206
+ }
207
+ .whats-next-cmd:hover { background: rgba(255,255,255,0.25); }
208
+
209
+ /* --- Phase sections --- */
210
+ .phase-section { margin-bottom: 16px; }
211
+ .phase-header {
212
+ display: flex;
213
+ align-items: center;
214
+ gap: 10px;
215
+ padding: 12px 16px;
216
+ background: var(--card-bg);
217
+ border: 1px solid var(--border);
218
+ border-radius: 8px;
219
+ cursor: pointer;
220
+ user-select: none;
221
+ }
222
+ .phase-header:hover { border-color: var(--accent); }
223
+ .phase-arrow {
224
+ transition: transform 0.2s;
225
+ font-size: 0.8rem;
226
+ color: var(--muted);
227
+ }
228
+ .phase-arrow.collapsed { transform: rotate(-90deg); }
229
+ .phase-title { font-weight: 600; flex: 1; }
230
+ .phase-number {
231
+ color: var(--faint);
232
+ font-size: 0.8rem;
233
+ font-weight: 600;
234
+ min-width: 28px;
235
+ }
236
+ .count-pill {
237
+ font-size: 0.75rem;
238
+ padding: 2px 8px;
239
+ border-radius: 10px;
240
+ font-weight: 600;
241
+ }
242
+ .count-completed { background: var(--status-completed); color: #064e3b; }
243
+ .count-skipped { background: var(--status-skipped); color: #1e1b4b; }
244
+ .count-pending { background: var(--border); color: var(--muted); }
245
+ .count-in-progress { background: var(--status-in-progress); color: #451a03; }
246
+
247
+ .phase-description {
248
+ padding: 8px 16px 4px;
249
+ color: var(--muted);
250
+ font-size: 0.85rem;
251
+ }
252
+ .phase-steps { padding: 4px 0 8px; }
253
+ .phase-steps.hidden, .phase-description.hidden { display: none; }
254
+
255
+ /* --- Step cards --- */
256
+ .step-card {
257
+ display: flex;
258
+ align-items: center;
259
+ gap: 12px;
260
+ padding: 10px 16px;
261
+ margin: 4px 0;
262
+ border-radius: 6px;
263
+ cursor: pointer;
264
+ transition: background 0.15s;
265
+ }
266
+ .step-card:hover { background: var(--card-bg); }
267
+ .step-icon { font-size: 1rem; flex-shrink: 0; width: 20px; text-align: center; }
268
+ .step-info { flex: 1; min-width: 0; }
269
+ .step-name { font-weight: 500; }
270
+ .step-summary { color: var(--muted); font-size: 0.8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
271
+ .step-meta { display: flex; gap: 8px; align-items: center; flex-shrink: 0; }
272
+ .step-badge {
273
+ font-size: 0.7rem;
274
+ padding: 2px 8px;
275
+ border-radius: 8px;
276
+ font-weight: 600;
277
+ text-transform: uppercase;
278
+ }
279
+ .status-completed .step-icon { color: var(--status-completed); }
280
+ .status-skipped .step-icon { color: var(--status-skipped); }
281
+ .status-in-progress .step-icon { color: var(--status-in-progress); }
282
+ .status-pending .step-icon { color: var(--status-pending); }
283
+ .badge-completed { background: var(--status-completed); color: #064e3b; }
284
+ .badge-skipped { background: var(--status-skipped); color: #1e1b4b; }
285
+ .badge-in-progress { background: var(--status-in-progress); color: #451a03; }
286
+ .badge-pending { background: var(--border); color: var(--muted); }
287
+ .badge-conditional { background: var(--border); color: var(--faint); font-size: 0.65rem; }
288
+
289
+ /* --- Modal --- */
290
+ .modal-overlay {
291
+ display: none;
292
+ position: fixed;
293
+ top: 0; left: 0; right: 0; bottom: 0;
294
+ background: var(--modal-backdrop);
295
+ z-index: 1000;
296
+ align-items: center;
297
+ justify-content: center;
298
+ }
299
+ .modal-overlay.visible { display: flex; }
300
+ .modal-dialog {
301
+ background: var(--card-bg);
302
+ border: 1px solid var(--border);
303
+ border-radius: 12px;
304
+ max-width: 680px;
305
+ width: 95%;
306
+ max-height: 85vh;
307
+ display: flex;
308
+ flex-direction: column;
309
+ }
310
+ .modal-header {
311
+ display: flex;
312
+ align-items: center;
313
+ gap: 12px;
314
+ padding: 20px 24px 16px;
315
+ border-bottom: 1px solid var(--border);
316
+ }
317
+ .modal-header .step-icon { font-size: 1.3rem; }
318
+ .modal-header-info { flex: 1; }
319
+ .modal-header-info h2 { margin: 0; font-size: 1.15rem; }
320
+ .modal-header-info .modal-phase { color: var(--muted); font-size: 0.8rem; }
321
+ .modal-close {
322
+ cursor: pointer;
323
+ background: none;
324
+ border: none;
325
+ color: var(--muted);
326
+ font-size: 1.5rem;
327
+ padding: 0 4px;
328
+ line-height: 1;
329
+ }
330
+ .modal-close:hover { color: var(--text); }
331
+ .modal-body {
332
+ padding: 20px 24px;
333
+ overflow-y: auto;
334
+ flex: 1;
335
+ }
336
+ .modal-summary { color: var(--muted); font-size: 0.9rem; margin-bottom: 16px; }
337
+ .meta-grid {
338
+ display: grid;
339
+ grid-template-columns: 1fr 1fr;
340
+ gap: 12px;
341
+ margin-bottom: 20px;
342
+ }
343
+ .meta-item label {
344
+ display: block;
345
+ font-size: 0.7rem;
346
+ text-transform: uppercase;
347
+ color: var(--faint);
348
+ margin-bottom: 2px;
349
+ letter-spacing: 0.03em;
350
+ }
351
+ .meta-item .meta-value { font-size: 0.85rem; }
352
+ .prompt-section { margin-top: 16px; }
353
+ .prompt-toggle {
111
354
  cursor: pointer;
112
355
  background: none;
113
- border: 1px solid var(--color-border);
114
- padding: 6px 12px;
356
+ border: 1px solid var(--border);
357
+ color: var(--text);
358
+ padding: 8px 14px;
115
359
  border-radius: 6px;
116
- color: var(--color-text);
360
+ font-size: 0.8rem;
361
+ display: flex;
362
+ align-items: center;
363
+ gap: 6px;
364
+ width: 100%;
365
+ text-align: left;
366
+ }
367
+ .prompt-toggle:hover { border-color: var(--accent); }
368
+ .prompt-body {
369
+ background: var(--bg);
370
+ border: 1px solid var(--border);
371
+ border-radius: 0 0 6px 6px;
372
+ padding: 16px;
373
+ margin-top: -1px;
374
+ max-height: 300px;
375
+ overflow-y: auto;
376
+ }
377
+ .prompt-body pre {
378
+ margin: 0;
379
+ white-space: pre-wrap;
380
+ word-break: break-word;
381
+ font-size: 0.8rem;
382
+ line-height: 1.6;
383
+ color: var(--text);
384
+ }
385
+ .prompt-body.hidden { display: none; }
386
+ .cmd-row {
387
+ display: flex;
388
+ align-items: center;
389
+ gap: 8px;
390
+ margin-top: 16px;
391
+ padding: 10px 14px;
392
+ background: var(--bg);
393
+ border-radius: 6px;
394
+ border: 1px solid var(--border);
395
+ }
396
+ .cmd-row code { flex: 1; font-size: 0.85rem; }
397
+ .cmd-copy {
398
+ cursor: pointer;
399
+ background: var(--accent);
400
+ color: #fff;
401
+ border: none;
402
+ padding: 4px 12px;
403
+ border-radius: 4px;
404
+ font-size: 0.75rem;
405
+ font-weight: 600;
406
+ }
407
+ .cmd-copy:hover { opacity: 0.9; }
408
+ .scaffold-hint {
409
+ color: var(--faint);
410
+ font-size: 0.75rem;
411
+ margin-top: 12px;
117
412
  }
118
- .section-heading { font-size: 1.25rem; font-weight: 600; margin: 24px 0 8px; }
119
- .decision-row { padding: 8px; border-bottom: 1px solid var(--color-border); }
120
- .decision-id { font-weight: bold; }
413
+
414
+ /* --- Decisions --- */
415
+ .decisions-section { margin-top: 32px; }
416
+ .decisions-header {
417
+ display: flex;
418
+ align-items: center;
419
+ gap: 10px;
420
+ cursor: pointer;
421
+ user-select: none;
422
+ padding: 12px 0;
423
+ }
424
+ .decisions-header h2 { margin: 0; font-size: 1.1rem; }
425
+ .decisions-arrow {
426
+ transition: transform 0.2s;
427
+ font-size: 0.8rem;
428
+ color: var(--muted);
429
+ }
430
+ .decisions-arrow.collapsed { transform: rotate(-90deg); }
431
+ .decisions-count {
432
+ font-size: 0.75rem;
433
+ background: var(--border);
434
+ color: var(--muted);
435
+ padding: 2px 8px;
436
+ border-radius: 10px;
437
+ }
438
+ .decisions-body.hidden { display: none; }
439
+ .decision-entry {
440
+ padding: 10px 0;
441
+ border-bottom: 1px solid var(--border);
442
+ font-size: 0.85rem;
443
+ }
444
+ .decision-step-tag {
445
+ color: var(--accent-light);
446
+ font-weight: 600;
447
+ margin-right: 6px;
448
+ }
449
+ .decision-text { color: var(--text); }
450
+ .decision-meta { color: var(--faint); font-size: 0.75rem; margin-top: 2px; }
121
451
  .provisional-badge {
122
- background: #fef3c7;
123
- color: #92400e;
124
- padding: 2px 6px;
452
+ background: var(--badge-prov-bg);
453
+ color: var(--badge-prov-text);
454
+ padding: 1px 6px;
125
455
  border-radius: 4px;
126
- font-size: 0.8em;
456
+ font-size: 0.7rem;
457
+ font-weight: 600;
458
+ margin-left: 6px;
459
+ }
460
+
461
+ /* --- Footer --- */
462
+ .footer {
463
+ margin-top: 40px;
464
+ padding-top: 16px;
465
+ border-top: 1px solid var(--border);
466
+ color: var(--faint);
467
+ font-size: 0.75rem;
468
+ display: flex;
469
+ justify-content: space-between;
470
+ flex-wrap: wrap;
471
+ gap: 8px;
127
472
  }
128
- @media (max-width: 768px) { .summary-cards { grid-template-columns: repeat(2, 1fr); } }
473
+
474
+ /* --- Responsive --- */
475
+ @media (max-width: 768px) {
476
+ .meta-grid { grid-template-columns: 1fr; }
477
+ }
478
+ @media (max-width: 480px) {
479
+ body { padding: 16px; }
480
+ .header { flex-direction: column; }
481
+ .summary-cards { grid-template-columns: 1fr; }
482
+ .step-card { flex-wrap: wrap; }
483
+ }
484
+
485
+ /* Body scroll lock when modal open */
486
+ body.modal-open { overflow: hidden; }
129
487
  </style>
130
488
  </head>
131
489
  <body>
132
490
  <script>
133
- const stored = localStorage.getItem('scaffold-theme')
134
- const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
135
- const theme = stored || (prefersDark ? 'dark' : 'light')
136
- document.documentElement.setAttribute('data-theme', theme)
137
- function toggleTheme() {
138
- const current = document.documentElement.getAttribute('data-theme')
139
- const next = current === 'dark' ? 'light' : 'dark'
140
- document.documentElement.setAttribute('data-theme', next)
141
- localStorage.setItem('scaffold-theme', next)
142
- }
491
+ var stored = localStorage.getItem('scaffold-theme');
492
+ var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
493
+ var theme = stored || (prefersDark ? 'dark' : 'light');
494
+ document.documentElement.setAttribute('data-theme', theme);
143
495
  </script>
144
496
  <div class="container">
145
497
  <div class="header">
146
498
  <div>
147
499
  <h1>Scaffold Pipeline</h1>
148
- <div>Methodology: ${methodology} | ${pct}% complete</div>
500
+ <div class="header-meta">
501
+ <span class="methodology-badge">${methodology}</span>
502
+ <span class="pct-label">${pct}% complete</span>
503
+ </div>
149
504
  </div>
150
505
  <button class="theme-toggle" onclick="toggleTheme()">Toggle theme</button>
151
506
  </div>
@@ -155,36 +510,322 @@ body {
155
510
  <div class="progress-skipped" style="width:${skippedPct}%"></div>
156
511
  </div>
157
512
  <div class="summary-cards">
158
- <div class="card">
513
+ <div class="card card-completed">
159
514
  <div class="card-number">${data.progress.completed}</div>
160
- <div>Completed</div>
515
+ <div class="card-label">Completed</div>
161
516
  </div>
162
- <div class="card">
517
+ <div class="card card-skipped">
163
518
  <div class="card-number">${data.progress.skipped}</div>
164
- <div>Skipped</div>
519
+ <div class="card-label">Skipped</div>
165
520
  </div>
166
- <div class="card">
521
+ <div class="card card-pending">
167
522
  <div class="card-number">${data.progress.pending}</div>
168
- <div>Pending</div>
523
+ <div class="card-label">Pending</div>
169
524
  </div>
170
- <div class="card">
525
+ <div class="card card-in-progress">
171
526
  <div class="card-number">${data.progress.inProgress}</div>
172
- <div>In Progress</div>
527
+ <div class="card-label">In Progress</div>
173
528
  </div>
174
529
  </div>
175
- <div class="section-heading">Pipeline Steps</div>
176
- ${stepRows}
177
- <div class="section-heading">Decision Log</div>
178
- ${data.decisions.length > 0 ? decisionRows : '<div>No decisions recorded yet.</div>'}
530
+ ${whatsNextBanner}
531
+ <div id="phases"></div>
532
+ <div id="decisions"></div>
533
+ <div class="footer">
534
+ <span>Generated ${escapeHtml(data.generatedAt)}</span>
535
+ <span>Scaffold v${escapeHtml(data.scaffoldVersion)}</span>
536
+ </div>
179
537
  </div>
538
+ <div class="modal-overlay" id="modal-overlay" onclick="if(event.target===this)closeModal()">
539
+ <div class="modal-dialog">
540
+ <div class="modal-header">
541
+ <span class="step-icon" id="modal-icon"></span>
542
+ <div class="modal-header-info">
543
+ <h2 id="modal-title"></h2>
544
+ <div class="modal-phase" id="modal-phase"></div>
545
+ </div>
546
+ <button class="modal-close" onclick="closeModal()">&times;</button>
547
+ </div>
548
+ <div class="modal-body" id="modal-body"></div>
549
+ </div>
550
+ </div>
551
+ <script>
552
+ (function() {
553
+ var icons = {
554
+ completed: '&#10003;',
555
+ skipped: '&#8594;',
556
+ in_progress: '&#9679;',
557
+ pending: '&#9675;'
558
+ };
559
+
560
+ var statusLabels = {
561
+ completed: 'Completed',
562
+ skipped: 'Skipped',
563
+ in_progress: 'In Progress',
564
+ pending: 'Pending'
565
+ };
566
+
567
+ function escapeHtml(s) {
568
+ if (!s) return '';
569
+ return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
570
+ }
571
+
572
+ function formatDate(iso) {
573
+ if (!iso) return '';
574
+ var d = new Date(iso);
575
+ var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
576
+ return months[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear();
577
+ }
578
+
579
+ function toggleTheme() {
580
+ var current = document.documentElement.getAttribute('data-theme');
581
+ var next = current === 'dark' ? 'light' : 'dark';
582
+ document.documentElement.setAttribute('data-theme', next);
583
+ localStorage.setItem('scaffold-theme', next);
584
+ }
585
+ window.toggleTheme = toggleTheme;
586
+
587
+ function renderPhases(data) {
588
+ var container = document.getElementById('phases');
589
+ if (!container) return;
590
+ var html = '';
591
+
592
+ for (var i = 0; i < data.phases.length; i++) {
593
+ var phase = data.phases[i];
594
+ if (phase.counts.total === 0) continue;
595
+
596
+ var allDone = (phase.counts.completed + phase.counts.skipped) === phase.counts.total;
597
+ var collapsed = allDone;
598
+ var arrowClass = 'phase-arrow' + (collapsed ? ' collapsed' : '');
599
+ var stepsClass = 'phase-steps' + (collapsed ? ' hidden' : '');
600
+ var descClass = 'phase-description' + (collapsed ? ' hidden' : '');
601
+
602
+ html += '<div class="phase-section" id="phase-' + escapeHtml(phase.slug) + '">';
603
+ html += '<div class="phase-header" onclick="togglePhase(\\'' + escapeHtml(phase.slug) + '\\')">';
604
+ html += '<span class="' + arrowClass + '" id="arrow-' + escapeHtml(phase.slug) + '">&#9660;</span>';
605
+ html += '<span class="phase-number">P' + phase.number + '</span>';
606
+ html += '<span class="phase-title">' + escapeHtml(phase.displayName) + '</span>';
607
+
608
+ if (phase.counts.completed > 0)
609
+ html += '<span class="count-pill count-completed">' + phase.counts.completed + '</span>';
610
+ if (phase.counts.skipped > 0)
611
+ html += '<span class="count-pill count-skipped">' + phase.counts.skipped + '</span>';
612
+ if (phase.counts.inProgress > 0)
613
+ html += '<span class="count-pill count-in-progress">' + phase.counts.inProgress + '</span>';
614
+ if (phase.counts.pending > 0)
615
+ html += '<span class="count-pill count-pending">' + phase.counts.pending + '</span>';
616
+
617
+ html += '</div>';
618
+ html += '<div class="' + descClass + '" id="desc-' + escapeHtml(phase.slug) + '">' + escapeHtml(phase.description) + '</div>';
619
+ html += '<div class="' + stepsClass + '" id="steps-' + escapeHtml(phase.slug) + '">';
620
+
621
+ for (var j = 0; j < phase.steps.length; j++) {
622
+ var step = phase.steps[j];
623
+ var statusClass = 'status-' + step.status.replace('_', '-');
624
+ var icon = icons[step.status] || '?';
625
+ html += '<div class="step-card ' + statusClass + '" onclick="openModal(\\'' + escapeHtml(step.slug) + '\\')">';
626
+ html += '<span class="step-icon">' + icon + '</span>';
627
+ html += '<div class="step-info">';
628
+ html += '<div class="step-name">' + escapeHtml(step.slug) + '</div>';
629
+ if (step.summary) html += '<div class="step-summary">' + escapeHtml(step.summary) + '</div>';
630
+ html += '</div>';
631
+ html += '<div class="step-meta">';
632
+ if (step.conditional)
633
+ html += '<span class="step-badge badge-conditional">' + escapeHtml(step.conditional) + '</span>';
634
+ html += '<span class="step-badge badge-' + step.status.replace('_', '-') + '">' + (statusLabels[step.status] || step.status) + '</span>';
635
+ html += '</div>';
636
+ html += '</div>';
637
+ }
638
+
639
+ html += '</div></div>';
640
+ }
641
+
642
+ container.innerHTML = html;
643
+ }
644
+
645
+ function togglePhase(slug) {
646
+ var steps = document.getElementById('steps-' + slug);
647
+ var desc = document.getElementById('desc-' + slug);
648
+ var arrow = document.getElementById('arrow-' + slug);
649
+ if (!steps) return;
650
+ var isHidden = steps.classList.contains('hidden');
651
+ if (isHidden) {
652
+ steps.classList.remove('hidden');
653
+ if (desc) desc.classList.remove('hidden');
654
+ if (arrow) arrow.classList.remove('collapsed');
655
+ } else {
656
+ steps.classList.add('hidden');
657
+ if (desc) desc.classList.add('hidden');
658
+ if (arrow) arrow.classList.add('collapsed');
659
+ }
660
+ }
661
+ window.togglePhase = togglePhase;
662
+
663
+ function findStep(data, slug) {
664
+ for (var i = 0; i < data.steps.length; i++) {
665
+ if (data.steps[i].slug === slug) return data.steps[i];
666
+ }
667
+ return null;
668
+ }
669
+
670
+ function openModal(slug) {
671
+ var dataEl = document.getElementById('scaffold-data');
672
+ if (!dataEl) return;
673
+ var data = JSON.parse(dataEl.textContent || '{}');
674
+ var step = findStep(data, slug);
675
+ if (!step) return;
676
+
677
+ var icon = icons[step.status] || '?';
678
+ document.getElementById('modal-icon').innerHTML = icon;
679
+ document.getElementById('modal-icon').className = 'step-icon status-' + step.status.replace('_', '-');
680
+ document.getElementById('modal-title').textContent = step.slug;
681
+ document.getElementById('modal-phase').textContent = step.phase ? ('Phase: ' + step.phase) : '';
682
+
683
+ var body = '';
684
+ if (step.summary) {
685
+ body += '<div class="modal-summary">' + escapeHtml(step.summary) + '</div>';
686
+ }
687
+
688
+ body += '<div class="meta-grid">';
689
+ body += '<div class="meta-item"><label>Status</label><div class="meta-value"><span class="step-badge badge-' + step.status.replace('_', '-') + '">' + (statusLabels[step.status] || step.status) + '</span></div></div>';
690
+ body += '<div class="meta-item"><label>Completed</label><div class="meta-value">' + (step.completedAt ? formatDate(step.completedAt) : '&mdash;') + (step.depth != null ? ' (depth ' + step.depth + ')' : '') + '</div></div>';
691
+ body += '<div class="meta-item"><label>Dependencies</label><div class="meta-value">' + (step.dependencies && step.dependencies.length > 0 ? step.dependencies.map(escapeHtml).join(', ') : 'None') + '</div></div>';
692
+ body += '<div class="meta-item"><label>Outputs</label><div class="meta-value">' + (step.outputs && step.outputs.length > 0 ? step.outputs.map(escapeHtml).join(', ') : 'None') + '</div></div>';
693
+ body += '</div>';
694
+
695
+ if (step.metaPromptBody) {
696
+ body += '<div class="prompt-section">';
697
+ body += '<button class="prompt-toggle" onclick="togglePrompt()"><span id="prompt-arrow">&#9660;</span> Prompt Body</button>';
698
+ body += '<div class="prompt-body" id="prompt-body"><pre>' + escapeHtml(step.metaPromptBody) + '</pre></div>';
699
+ body += '</div>';
700
+ }
701
+
702
+ var cmd = '/scaffold ' + step.slug;
703
+ body += '<div class="cmd-row"><code>' + escapeHtml(cmd) + '</code><button class="cmd-copy" id="copy-btn" onclick="copyCommand(\\'' + escapeHtml(cmd).replace(/'/g, "\\\\'") + '\\')"' + '>Copy</button></div>';
704
+ body += '<div class="scaffold-hint">Run this command in Claude Code to execute this pipeline step.</div>';
705
+
706
+ document.getElementById('modal-body').innerHTML = body;
707
+ document.getElementById('modal-overlay').classList.add('visible');
708
+ document.body.classList.add('modal-open');
709
+ }
710
+ window.openModal = openModal;
711
+
712
+ function closeModal() {
713
+ document.getElementById('modal-overlay').classList.remove('visible');
714
+ document.body.classList.remove('modal-open');
715
+ }
716
+ window.closeModal = closeModal;
717
+
718
+ function copyCommand(text) {
719
+ navigator.clipboard.writeText(text).then(function() {
720
+ var btn = document.getElementById('copy-btn');
721
+ if (btn) {
722
+ var orig = btn.textContent;
723
+ btn.textContent = 'Copied!';
724
+ setTimeout(function() { btn.textContent = orig; }, 1500);
725
+ }
726
+ });
727
+ }
728
+ window.copyCommand = copyCommand;
729
+
730
+ function togglePrompt() {
731
+ var body = document.getElementById('prompt-body');
732
+ var arrow = document.getElementById('prompt-arrow');
733
+ if (!body) return;
734
+ var isHidden = body.classList.contains('hidden');
735
+ if (isHidden) {
736
+ body.classList.remove('hidden');
737
+ if (arrow) arrow.innerHTML = '&#9660;';
738
+ } else {
739
+ body.classList.add('hidden');
740
+ if (arrow) arrow.innerHTML = '&#9654;';
741
+ }
742
+ }
743
+ window.togglePrompt = togglePrompt;
744
+
745
+ function renderDecisions(data) {
746
+ var container = document.getElementById('decisions');
747
+ if (!container) return;
748
+
749
+ if (!data.decisions || data.decisions.length === 0) {
750
+ container.innerHTML = '<div class="decisions-section"><div class="decisions-header" onclick="toggleDecisions()"><span class="decisions-arrow collapsed" id="decisions-arrow">&#9660;</span><h2>Decision Log</h2><span class="decisions-count">0</span></div><div class="decisions-body hidden" id="decisions-body"><div style="padding:12px 0;color:var(--muted);font-size:0.85rem;">No decisions recorded yet.</div></div></div>';
751
+ return;
752
+ }
753
+
754
+ var html = '<div class="decisions-section">';
755
+ html += '<div class="decisions-header" onclick="toggleDecisions()">';
756
+ html += '<span class="decisions-arrow collapsed" id="decisions-arrow">&#9660;</span>';
757
+ html += '<h2>Decision Log</h2>';
758
+ html += '<span class="decisions-count">' + data.decisions.length + '</span>';
759
+ html += '</div>';
760
+ html += '<div class="decisions-body hidden" id="decisions-body">';
761
+
762
+ for (var i = 0; i < data.decisions.length; i++) {
763
+ var d = data.decisions[i];
764
+ html += '<div class="decision-entry">';
765
+ html += '<span class="decision-step-tag">[' + escapeHtml(d.step) + ']</span>';
766
+ html += '<span class="decision-text">' + escapeHtml(d.decision) + '</span>';
767
+ if (d.provisional) html += '<span class="provisional-badge">provisional</span>';
768
+ html += '<div class="decision-meta">' + escapeHtml(d.id) + ' &middot; ' + formatDate(d.timestamp) + '</div>';
769
+ html += '</div>';
770
+ }
771
+
772
+ html += '</div></div>';
773
+ container.innerHTML = html;
774
+ }
775
+
776
+ function toggleDecisions() {
777
+ var body = document.getElementById('decisions-body');
778
+ var arrow = document.getElementById('decisions-arrow');
779
+ if (!body) return;
780
+ var isHidden = body.classList.contains('hidden');
781
+ if (isHidden) {
782
+ body.classList.remove('hidden');
783
+ if (arrow) arrow.classList.remove('collapsed');
784
+ } else {
785
+ body.classList.add('hidden');
786
+ if (arrow) arrow.classList.add('collapsed');
787
+ }
788
+ }
789
+ window.toggleDecisions = toggleDecisions;
790
+
791
+ // Stale check
792
+ (function() {
793
+ var dataEl = document.getElementById('scaffold-data');
794
+ if (!dataEl) return;
795
+ var data = JSON.parse(dataEl.textContent || '{}');
796
+ if (data.generatedAt) {
797
+ var age = Date.now() - new Date(data.generatedAt).getTime();
798
+ if (age > 3600000) {
799
+ var existing = document.getElementById('stale-notice');
800
+ if (!existing) {
801
+ var notice = document.createElement('div');
802
+ notice.id = 'stale-notice';
803
+ notice.className = 'stale-notice';
804
+ notice.innerHTML = '&#9888; Data may be stale (generated more than 1 hour ago)';
805
+ var container = document.querySelector('.container');
806
+ if (container) container.insertBefore(notice, container.children[1]);
807
+ }
808
+ }
809
+ }
810
+ })();
811
+
812
+ // Keyboard handler
813
+ document.addEventListener('keydown', function(e) {
814
+ if (e.key === 'Escape') closeModal();
815
+ });
816
+
817
+ // Init
818
+ document.addEventListener('DOMContentLoaded', function() {
819
+ var dataEl = document.getElementById('scaffold-data');
820
+ if (!dataEl) return;
821
+ var data = JSON.parse(dataEl.textContent || '{}');
822
+ renderPhases(data);
823
+ renderDecisions(data);
824
+ });
825
+ })();
826
+ </script>
180
827
  </body>
181
828
  </html>`;
182
829
  }
183
- export function escapeHtml(s) {
184
- return s
185
- .replace(/&/g, '&amp;')
186
- .replace(/</g, '&lt;')
187
- .replace(/>/g, '&gt;')
188
- .replace(/"/g, '&quot;');
189
- }
830
+ /* eslint-enable max-len */
190
831
  //# sourceMappingURL=template.js.map