quiver-cli 1.3.1 → 2.0.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 (407) hide show
  1. package/README.md +197 -239
  2. package/dist/cli.js +3163 -2040
  3. package/package.json +10 -11
  4. package/template/.agents/AGENTS.md +0 -26
  5. package/template/.agents/commands/cp.md +0 -108
  6. package/template/.agents/commands/next-setup.md +0 -1064
  7. package/template/.agents/commands/review.md +0 -68
  8. package/template/.agents/commands/terraform-readme.md +0 -38
  9. package/template/.agents/config.json +0 -80
  10. package/template/.agents/plugins/opencode/rtk.ts +0 -34
  11. package/template/.agents/skills/agent-browser/SKILL.md +0 -52
  12. package/template/.agents/skills/apps/skybridge/SKILL.md +0 -52
  13. package/template/.agents/skills/code/cleanup/SKILL.md +0 -26
  14. package/template/.agents/skills/code/improve/SKILL.md +0 -122
  15. package/template/.agents/skills/code/improve/references/audit-playbook.md +0 -130
  16. package/template/.agents/skills/code/improve/references/closing-the-loop.md +0 -96
  17. package/template/.agents/skills/code/improve/references/plan-template.md +0 -197
  18. package/template/.agents/skills/code/vercel-react-best-practices/AGENTS.md +0 -3810
  19. package/template/.agents/skills/code/vercel-react-best-practices/README.md +0 -123
  20. package/template/.agents/skills/code/vercel-react-best-practices/SKILL.md +0 -149
  21. package/template/.agents/skills/code/vercel-react-best-practices/metadata.json +0 -15
  22. package/template/.agents/skills/code/vercel-react-best-practices/rules/_sections.md +0 -46
  23. package/template/.agents/skills/code/vercel-react-best-practices/rules/_template.md +0 -28
  24. package/template/.agents/skills/code/vercel-react-best-practices/rules/advanced-effect-event-deps.md +0 -56
  25. package/template/.agents/skills/code/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  26. package/template/.agents/skills/code/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
  27. package/template/.agents/skills/code/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
  28. package/template/.agents/skills/code/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  29. package/template/.agents/skills/code/vercel-react-best-practices/rules/async-cheap-condition-before-await.md +0 -37
  30. package/template/.agents/skills/code/vercel-react-best-practices/rules/async-defer-await.md +0 -82
  31. package/template/.agents/skills/code/vercel-react-best-practices/rules/async-dependencies.md +0 -51
  32. package/template/.agents/skills/code/vercel-react-best-practices/rules/async-parallel.md +0 -28
  33. package/template/.agents/skills/code/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  34. package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-analyzable-paths.md +0 -63
  35. package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -60
  36. package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  37. package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  38. package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  39. package/template/.agents/skills/code/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  40. package/template/.agents/skills/code/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  41. package/template/.agents/skills/code/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  42. package/template/.agents/skills/code/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  43. package/template/.agents/skills/code/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  44. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
  45. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  46. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  47. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  48. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  49. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  50. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
  51. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  52. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  53. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  54. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  55. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-request-idle-callback.md +0 -105
  56. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  57. package/template/.agents/skills/code/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  58. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  59. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  60. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  61. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  62. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  63. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  64. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
  65. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
  66. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
  67. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  68. package/template/.agents/skills/code/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
  69. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  70. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  71. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
  72. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  73. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  74. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  75. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
  76. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  77. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
  78. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
  79. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
  80. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +0 -64
  81. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  82. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-use-deferred-value.md +0 -59
  83. package/template/.agents/skills/code/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
  84. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  85. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
  86. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  87. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  88. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
  89. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -149
  90. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-no-shared-module-state.md +0 -50
  91. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  92. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-parallel-nested-fetching.md +0 -34
  93. package/template/.agents/skills/code/vercel-react-best-practices/rules/server-serialization.md +0 -38
  94. package/template/.agents/skills/data/prisma-cli/SKILL.md +0 -265
  95. package/template/.agents/skills/data/prisma-cli/references/agent-safety.md +0 -27
  96. package/template/.agents/skills/data/prisma-cli/references/complete.md +0 -22
  97. package/template/.agents/skills/data/prisma-cli/references/db-execute.md +0 -78
  98. package/template/.agents/skills/data/prisma-cli/references/db-pull.md +0 -185
  99. package/template/.agents/skills/data/prisma-cli/references/db-push.md +0 -150
  100. package/template/.agents/skills/data/prisma-cli/references/db-seed.md +0 -188
  101. package/template/.agents/skills/data/prisma-cli/references/debug.md +0 -46
  102. package/template/.agents/skills/data/prisma-cli/references/dev.md +0 -157
  103. package/template/.agents/skills/data/prisma-cli/references/format.md +0 -48
  104. package/template/.agents/skills/data/prisma-cli/references/generate.md +0 -173
  105. package/template/.agents/skills/data/prisma-cli/references/init.md +0 -139
  106. package/template/.agents/skills/data/prisma-cli/references/mcp.md +0 -39
  107. package/template/.agents/skills/data/prisma-cli/references/migrate-deploy.md +0 -127
  108. package/template/.agents/skills/data/prisma-cli/references/migrate-dev.md +0 -145
  109. package/template/.agents/skills/data/prisma-cli/references/migrate-diff.md +0 -89
  110. package/template/.agents/skills/data/prisma-cli/references/migrate-reset.md +0 -80
  111. package/template/.agents/skills/data/prisma-cli/references/migrate-resolve.md +0 -57
  112. package/template/.agents/skills/data/prisma-cli/references/migrate-status.md +0 -65
  113. package/template/.agents/skills/data/prisma-cli/references/studio.md +0 -137
  114. package/template/.agents/skills/data/prisma-cli/references/validate.md +0 -53
  115. package/template/.agents/skills/data/prisma-client-api/SKILL.md +0 -216
  116. package/template/.agents/skills/data/prisma-client-api/references/client-methods.md +0 -223
  117. package/template/.agents/skills/data/prisma-client-api/references/constructor.md +0 -221
  118. package/template/.agents/skills/data/prisma-client-api/references/filters.md +0 -256
  119. package/template/.agents/skills/data/prisma-client-api/references/model-queries.md +0 -281
  120. package/template/.agents/skills/data/prisma-client-api/references/query-options.md +0 -276
  121. package/template/.agents/skills/data/prisma-client-api/references/raw-queries.md +0 -198
  122. package/template/.agents/skills/data/prisma-client-api/references/relations.md +0 -308
  123. package/template/.agents/skills/data/prisma-client-api/references/transactions.md +0 -184
  124. package/template/.agents/skills/design/impeccable/SKILL.md +0 -84
  125. package/template/.agents/skills/design/impeccable/reference/adapt.md +0 -312
  126. package/template/.agents/skills/design/impeccable/reference/adapt.native.md +0 -58
  127. package/template/.agents/skills/design/impeccable/reference/android.md +0 -46
  128. package/template/.agents/skills/design/impeccable/reference/animate.md +0 -89
  129. package/template/.agents/skills/design/impeccable/reference/audit.md +0 -136
  130. package/template/.agents/skills/design/impeccable/reference/audit.native.md +0 -139
  131. package/template/.agents/skills/design/impeccable/reference/bolder.md +0 -33
  132. package/template/.agents/skills/design/impeccable/reference/clarify.md +0 -94
  133. package/template/.agents/skills/design/impeccable/reference/colorize.md +0 -86
  134. package/template/.agents/skills/design/impeccable/reference/craft-floor.md +0 -44
  135. package/template/.agents/skills/design/impeccable/reference/craft.md +0 -5
  136. package/template/.agents/skills/design/impeccable/reference/critique.md +0 -806
  137. package/template/.agents/skills/design/impeccable/reference/degraded/asset-producer.md +0 -37
  138. package/template/.agents/skills/design/impeccable/reference/degraded/documenter.md +0 -24
  139. package/template/.agents/skills/design/impeccable/reference/degraded/finish-reviewer.md +0 -38
  140. package/template/.agents/skills/design/impeccable/reference/degraded/manual-edit-applier.md +0 -92
  141. package/template/.agents/skills/design/impeccable/reference/delight.md +0 -70
  142. package/template/.agents/skills/design/impeccable/reference/distill.md +0 -111
  143. package/template/.agents/skills/design/impeccable/reference/doctor.md +0 -54
  144. package/template/.agents/skills/design/impeccable/reference/document.md +0 -416
  145. package/template/.agents/skills/design/impeccable/reference/extract.md +0 -69
  146. package/template/.agents/skills/design/impeccable/reference/harden.md +0 -336
  147. package/template/.agents/skills/design/impeccable/reference/hooks.md +0 -111
  148. package/template/.agents/skills/design/impeccable/reference/init.md +0 -131
  149. package/template/.agents/skills/design/impeccable/reference/ios.md +0 -51
  150. package/template/.agents/skills/design/impeccable/reference/layout.md +0 -84
  151. package/template/.agents/skills/design/impeccable/reference/live-setup.md +0 -102
  152. package/template/.agents/skills/design/impeccable/reference/live.md +0 -323
  153. package/template/.agents/skills/design/impeccable/reference/new-work.md +0 -145
  154. package/template/.agents/skills/design/impeccable/reference/onboard.md +0 -234
  155. package/template/.agents/skills/design/impeccable/reference/operate.md +0 -61
  156. package/template/.agents/skills/design/impeccable/reference/optimize.md +0 -258
  157. package/template/.agents/skills/design/impeccable/reference/overdrive.md +0 -127
  158. package/template/.agents/skills/design/impeccable/reference/polish.md +0 -105
  159. package/template/.agents/skills/design/impeccable/reference/quieter.md +0 -99
  160. package/template/.agents/skills/design/impeccable/reference/routing.md +0 -18
  161. package/template/.agents/skills/design/impeccable/reference/shape.md +0 -59
  162. package/template/.agents/skills/design/impeccable/reference/typeset.md +0 -80
  163. package/template/.agents/skills/design/impeccable/reference/visualize.md +0 -46
  164. package/template/.agents/skills/design/impeccable/scripts/build-phase.mjs +0 -1022
  165. package/template/.agents/skills/design/impeccable/scripts/command-metadata.json +0 -94
  166. package/template/.agents/skills/design/impeccable/scripts/comp-diff.mjs +0 -391
  167. package/template/.agents/skills/design/impeccable/scripts/comp-spec.mjs +0 -513
  168. package/template/.agents/skills/design/impeccable/scripts/concept-seed.mjs +0 -814
  169. package/template/.agents/skills/design/impeccable/scripts/context-signals.mjs +0 -325
  170. package/template/.agents/skills/design/impeccable/scripts/context.mjs +0 -1565
  171. package/template/.agents/skills/design/impeccable/scripts/critique-storage.mjs +0 -473
  172. package/template/.agents/skills/design/impeccable/scripts/data/font-index-failures.json +0 -121
  173. package/template/.agents/skills/design/impeccable/scripts/data/font-index.json +0 -1
  174. package/template/.agents/skills/design/impeccable/scripts/detect-csp.mjs +0 -198
  175. package/template/.agents/skills/design/impeccable/scripts/detect.mjs +0 -30
  176. package/template/.agents/skills/design/impeccable/scripts/detector/browser/injected/index.mjs +0 -2204
  177. package/template/.agents/skills/design/impeccable/scripts/detector/cli/main.mjs +0 -432
  178. package/template/.agents/skills/design/impeccable/scripts/detector/design-system.mjs +0 -1311
  179. package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns-browser.js +0 -9043
  180. package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns.mjs +0 -51
  181. package/template/.agents/skills/design/impeccable/scripts/detector/engines/browser/detect-url.mjs +0 -434
  182. package/template/.agents/skills/design/impeccable/scripts/detector/engines/regex/detect-text.mjs +0 -1319
  183. package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +0 -1241
  184. package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/detect-html.mjs +0 -288
  185. package/template/.agents/skills/design/impeccable/scripts/detector/engines/visual/screenshot-contrast.mjs +0 -189
  186. package/template/.agents/skills/design/impeccable/scripts/detector/findings.mjs +0 -18
  187. package/template/.agents/skills/design/impeccable/scripts/detector/node/file-system.mjs +0 -213
  188. package/template/.agents/skills/design/impeccable/scripts/detector/profile/profiler.mjs +0 -166
  189. package/template/.agents/skills/design/impeccable/scripts/detector/registry/antipatterns.mjs +0 -635
  190. package/template/.agents/skills/design/impeccable/scripts/detector/rules/checks.mjs +0 -5681
  191. package/template/.agents/skills/design/impeccable/scripts/detector/shared/color.mjs +0 -596
  192. package/template/.agents/skills/design/impeccable/scripts/detector/shared/constants.mjs +0 -127
  193. package/template/.agents/skills/design/impeccable/scripts/detector/shared/fonts.mjs +0 -30
  194. package/template/.agents/skills/design/impeccable/scripts/detector/shared/inline-ignores.mjs +0 -148
  195. package/template/.agents/skills/design/impeccable/scripts/detector/shared/page.mjs +0 -7
  196. package/template/.agents/skills/design/impeccable/scripts/doctor.mjs +0 -329
  197. package/template/.agents/skills/design/impeccable/scripts/embed-prompt.mjs +0 -166
  198. package/template/.agents/skills/design/impeccable/scripts/font-match.mjs +0 -457
  199. package/template/.agents/skills/design/impeccable/scripts/generate-image.mjs +0 -447
  200. package/template/.agents/skills/design/impeccable/scripts/hook-admin.mjs +0 -819
  201. package/template/.agents/skills/design/impeccable/scripts/hook-before-edit.mjs +0 -538
  202. package/template/.agents/skills/design/impeccable/scripts/hook-lib.mjs +0 -2490
  203. package/template/.agents/skills/design/impeccable/scripts/hook.mjs +0 -79
  204. package/template/.agents/skills/design/impeccable/scripts/lib/artifact-schema.mjs +0 -93
  205. package/template/.agents/skills/design/impeccable/scripts/lib/composition-catalog.mjs +0 -200
  206. package/template/.agents/skills/design/impeccable/scripts/lib/concept-catalog.mjs +0 -396
  207. package/template/.agents/skills/design/impeccable/scripts/lib/design-parser.mjs +0 -880
  208. package/template/.agents/skills/design/impeccable/scripts/lib/font-fingerprint.mjs +0 -564
  209. package/template/.agents/skills/design/impeccable/scripts/lib/font-index.mjs +0 -130
  210. package/template/.agents/skills/design/impeccable/scripts/lib/hero-checks.mjs +0 -246
  211. package/template/.agents/skills/design/impeccable/scripts/lib/image-metrics.mjs +0 -306
  212. package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-config.mjs +0 -640
  213. package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-paths.mjs +0 -137
  214. package/template/.agents/skills/design/impeccable/scripts/lib/is-generated.mjs +0 -72
  215. package/template/.agents/skills/design/impeccable/scripts/lib/live-path-globs.mjs +0 -37
  216. package/template/.agents/skills/design/impeccable/scripts/lib/open-system-browser.mjs +0 -26
  217. package/template/.agents/skills/design/impeccable/scripts/lib/png.mjs +0 -281
  218. package/template/.agents/skills/design/impeccable/scripts/lib/provider.mjs +0 -5
  219. package/template/.agents/skills/design/impeccable/scripts/lib/raster.mjs +0 -194
  220. package/template/.agents/skills/design/impeccable/scripts/lib/roll-selection.mjs +0 -369
  221. package/template/.agents/skills/design/impeccable/scripts/lib/staleness-deep.mjs +0 -485
  222. package/template/.agents/skills/design/impeccable/scripts/lib/staleness-notice.mjs +0 -169
  223. package/template/.agents/skills/design/impeccable/scripts/lib/staleness.mjs +0 -533
  224. package/template/.agents/skills/design/impeccable/scripts/lib/surface-briefs.mjs +0 -149
  225. package/template/.agents/skills/design/impeccable/scripts/lib/target-args.mjs +0 -42
  226. package/template/.agents/skills/design/impeccable/scripts/lib/target-slug.mjs +0 -33
  227. package/template/.agents/skills/design/impeccable/scripts/lib/template-extensions.mjs +0 -146
  228. package/template/.agents/skills/design/impeccable/scripts/live/accept-css.mjs +0 -617
  229. package/template/.agents/skills/design/impeccable/scripts/live/accept-verify.mjs +0 -60
  230. package/template/.agents/skills/design/impeccable/scripts/live/browser-script-parts.mjs +0 -84
  231. package/template/.agents/skills/design/impeccable/scripts/live/completion.mjs +0 -28
  232. package/template/.agents/skills/design/impeccable/scripts/live/event-validation.mjs +0 -199
  233. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/astro.mjs +0 -47
  234. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/detect-utils.mjs +0 -73
  235. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/index.mjs +0 -143
  236. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/journal.mjs +0 -197
  237. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/nextjs.mjs +0 -49
  238. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/nuxt.mjs +0 -161
  239. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/script-src.mjs +0 -17
  240. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/static-html.mjs +0 -26
  241. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/sveltekit.mjs +0 -71
  242. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/tag-strategy.mjs +0 -247
  243. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/tanstack-start.mjs +0 -70
  244. package/template/.agents/skills/design/impeccable/scripts/live/frameworks/vite-generic.mjs +0 -42
  245. package/template/.agents/skills/design/impeccable/scripts/live/generation-preflight.mjs +0 -149
  246. package/template/.agents/skills/design/impeccable/scripts/live/insert-ui.mjs +0 -458
  247. package/template/.agents/skills/design/impeccable/scripts/live/instructions.mjs +0 -142
  248. package/template/.agents/skills/design/impeccable/scripts/live/manual-apply.mjs +0 -939
  249. package/template/.agents/skills/design/impeccable/scripts/live/manual-edit-routes.mjs +0 -357
  250. package/template/.agents/skills/design/impeccable/scripts/live/manual-edits-buffer.mjs +0 -152
  251. package/template/.agents/skills/design/impeccable/scripts/live/poll-lanes.mjs +0 -14
  252. package/template/.agents/skills/design/impeccable/scripts/live/project-ignores.mjs +0 -139
  253. package/template/.agents/skills/design/impeccable/scripts/live/roots.mjs +0 -508
  254. package/template/.agents/skills/design/impeccable/scripts/live/session-store.mjs +0 -563
  255. package/template/.agents/skills/design/impeccable/scripts/live/source-lock.mjs +0 -105
  256. package/template/.agents/skills/design/impeccable/scripts/live/source-search.mjs +0 -105
  257. package/template/.agents/skills/design/impeccable/scripts/live/svelte-ast.mjs +0 -969
  258. package/template/.agents/skills/design/impeccable/scripts/live/svelte-component.mjs +0 -1366
  259. package/template/.agents/skills/design/impeccable/scripts/live/sveltekit-adapter.mjs +0 -304
  260. package/template/.agents/skills/design/impeccable/scripts/live/tanstack-adapter.mjs +0 -259
  261. package/template/.agents/skills/design/impeccable/scripts/live/ui-surfaces.mjs +0 -75
  262. package/template/.agents/skills/design/impeccable/scripts/live/vocabulary.mjs +0 -171
  263. package/template/.agents/skills/design/impeccable/scripts/live-accept.mjs +0 -938
  264. package/template/.agents/skills/design/impeccable/scripts/live-browser-dom.js +0 -146
  265. package/template/.agents/skills/design/impeccable/scripts/live-browser-ignores.js +0 -242
  266. package/template/.agents/skills/design/impeccable/scripts/live-browser-session.js +0 -123
  267. package/template/.agents/skills/design/impeccable/scripts/live-browser.js +0 -12551
  268. package/template/.agents/skills/design/impeccable/scripts/live-commit-manual-edits.mjs +0 -1200
  269. package/template/.agents/skills/design/impeccable/scripts/live-complete.mjs +0 -107
  270. package/template/.agents/skills/design/impeccable/scripts/live-copy-edit-agent.mjs +0 -800
  271. package/template/.agents/skills/design/impeccable/scripts/live-discard-manual-edits.mjs +0 -51
  272. package/template/.agents/skills/design/impeccable/scripts/live-inject.mjs +0 -463
  273. package/template/.agents/skills/design/impeccable/scripts/live-insert.mjs +0 -292
  274. package/template/.agents/skills/design/impeccable/scripts/live-manual-edit-evidence.mjs +0 -368
  275. package/template/.agents/skills/design/impeccable/scripts/live-poll.mjs +0 -430
  276. package/template/.agents/skills/design/impeccable/scripts/live-resume.mjs +0 -123
  277. package/template/.agents/skills/design/impeccable/scripts/live-server.mjs +0 -1698
  278. package/template/.agents/skills/design/impeccable/scripts/live-status.mjs +0 -71
  279. package/template/.agents/skills/design/impeccable/scripts/live-target.mjs +0 -30
  280. package/template/.agents/skills/design/impeccable/scripts/live-wrap.mjs +0 -927
  281. package/template/.agents/skills/design/impeccable/scripts/live.mjs +0 -334
  282. package/template/.agents/skills/design/impeccable/scripts/modern-screenshot.umd.js +0 -14
  283. package/template/.agents/skills/design/impeccable/scripts/palette.mjs +0 -628
  284. package/template/.agents/skills/design/impeccable/scripts/pin.mjs +0 -224
  285. package/template/.agents/skills/design/impeccable/scripts/serve-question.mjs +0 -1783
  286. package/template/.agents/skills/design/impeccable/scripts/surface-brief.mjs +0 -74
  287. package/template/.agents/skills/design/shadcn/SKILL.md +0 -277
  288. package/template/.agents/skills/design/shadcn/agents/openai.yml +0 -5
  289. package/template/.agents/skills/design/shadcn/assets/shadcn-small.png +0 -0
  290. package/template/.agents/skills/design/shadcn/assets/shadcn.png +0 -0
  291. package/template/.agents/skills/design/shadcn/cli.md +0 -290
  292. package/template/.agents/skills/design/shadcn/customization.md +0 -209
  293. package/template/.agents/skills/design/shadcn/evals/evals.json +0 -77
  294. package/template/.agents/skills/design/shadcn/mcp.md +0 -105
  295. package/template/.agents/skills/design/shadcn/registry.md +0 -277
  296. package/template/.agents/skills/design/shadcn/rules/base-vs-radix.md +0 -306
  297. package/template/.agents/skills/design/shadcn/rules/chat.md +0 -250
  298. package/template/.agents/skills/design/shadcn/rules/composition.md +0 -213
  299. package/template/.agents/skills/design/shadcn/rules/forms.md +0 -192
  300. package/template/.agents/skills/design/shadcn/rules/icons.md +0 -101
  301. package/template/.agents/skills/design/shadcn/rules/styling.md +0 -185
  302. package/template/.agents/skills/find-skills/SKILL.md +0 -141
  303. package/template/.agents/skills/hono/SKILL.md +0 -593
  304. package/template/.agents/skills/integrations/langfuse/SKILL.md +0 -150
  305. package/template/.agents/skills/integrations/langfuse/references/ci-cd.md +0 -41
  306. package/template/.agents/skills/integrations/langfuse/references/cli.md +0 -60
  307. package/template/.agents/skills/integrations/langfuse/references/create-dataset.md +0 -35
  308. package/template/.agents/skills/integrations/langfuse/references/error-analysis.md +0 -87
  309. package/template/.agents/skills/integrations/langfuse/references/instrumentation.md +0 -121
  310. package/template/.agents/skills/integrations/langfuse/references/judge-calibration.md +0 -293
  311. package/template/.agents/skills/integrations/langfuse/references/prompt-engineering.md +0 -35
  312. package/template/.agents/skills/integrations/langfuse/references/prompt-migration.md +0 -79
  313. package/template/.agents/skills/integrations/langfuse/references/sdk-upgrade.md +0 -34
  314. package/template/.agents/skills/integrations/langfuse/references/setting-up-evals.md +0 -65
  315. package/template/.agents/skills/integrations/langfuse/references/skill-feedback.md +0 -35
  316. package/template/.agents/skills/integrations/langfuse/references/trace-evaluator-upgrade.md +0 -76
  317. package/template/.agents/skills/integrations/langfuse/references/user-feedback.md +0 -66
  318. package/template/.agents/skills/integrations/langfuse/references/v4-project-migration.md +0 -75
  319. package/template/.agents/skills/integrations/posthog/SKILL.md +0 -102
  320. package/template/.agents/skills/integrations/posthog/references/error-tracking-alerts.md +0 -63
  321. package/template/.agents/skills/integrations/posthog/references/error-tracking-assigning-issues.md +0 -77
  322. package/template/.agents/skills/integrations/posthog/references/error-tracking-fingerprints.md +0 -57
  323. package/template/.agents/skills/integrations/posthog/references/error-tracking-monitoring.md +0 -140
  324. package/template/.agents/skills/integrations/posthog/references/error-tracking-nextjs.md +0 -490
  325. package/template/.agents/skills/integrations/posthog/references/error-tracking-source-maps.md +0 -45
  326. package/template/.agents/skills/integrations/posthog/references/feature-flags-best-practices.md +0 -139
  327. package/template/.agents/skills/integrations/posthog/references/feature-flags-react.md +0 -302
  328. package/template/.agents/skills/integrations/posthog/references/identify-users.md +0 -202
  329. package/template/.agents/skills/integrations/posthog/references/integration-example.md +0 -706
  330. package/template/.agents/skills/integrations/posthog/references/integration-nextjs.md +0 -385
  331. package/template/.agents/skills/integrations/posthog/references/integration-step-1-begin.md +0 -43
  332. package/template/.agents/skills/integrations/posthog/references/integration-step-2-edit.md +0 -37
  333. package/template/.agents/skills/integrations/posthog/references/integration-step-3-revise.md +0 -22
  334. package/template/.agents/skills/integrations/posthog/references/integration-step-4-conclude.md +0 -38
  335. package/template/.agents/skills/integrations/posthog/references/llm-analytics-anthropic.md +0 -200
  336. package/template/.agents/skills/integrations/posthog/references/llm-analytics-basics.md +0 -62
  337. package/template/.agents/skills/integrations/posthog/references/llm-analytics-costs.md +0 -197
  338. package/template/.agents/skills/integrations/posthog/references/llm-analytics-manual-capture.md +0 -397
  339. package/template/.agents/skills/integrations/posthog/references/llm-analytics-traces.md +0 -98
  340. package/template/.agents/skills/integrations/posthog/references/llm-analytics-vercel-ai.md +0 -120
  341. package/template/.agents/skills/repo/repo-ci/SKILL.md +0 -265
  342. package/template/.agents/skills/repo/repo-init-next-js/SKILL.md +0 -129
  343. package/template/.agents/skills/repo/repo-init-next-js/references/file-contents.md +0 -800
  344. package/template/.agents/skills/repo/repo-init-next-js/scripts/setup.sh +0 -47
  345. package/template/.agents/skills/repo/repo-init-node/SKILL.md +0 -196
  346. package/template/.agents/skills/skill-creator/LICENSE.txt +0 -202
  347. package/template/.agents/skills/skill-creator/SKILL.md +0 -485
  348. package/template/.agents/skills/skill-creator/agents/analyzer.md +0 -274
  349. package/template/.agents/skills/skill-creator/agents/comparator.md +0 -202
  350. package/template/.agents/skills/skill-creator/agents/grader.md +0 -223
  351. package/template/.agents/skills/skill-creator/assets/eval_review.html +0 -146
  352. package/template/.agents/skills/skill-creator/eval-viewer/generate_review.py +0 -471
  353. package/template/.agents/skills/skill-creator/eval-viewer/viewer.html +0 -1325
  354. package/template/.agents/skills/skill-creator/references/schemas.md +0 -430
  355. package/template/.agents/skills/skill-creator/scripts/__init__.py +0 -0
  356. package/template/.agents/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
  357. package/template/.agents/skills/skill-creator/scripts/generate_report.py +0 -326
  358. package/template/.agents/skills/skill-creator/scripts/improve_description.py +0 -247
  359. package/template/.agents/skills/skill-creator/scripts/package_skill.py +0 -136
  360. package/template/.agents/skills/skill-creator/scripts/quick_validate.py +0 -103
  361. package/template/.agents/skills/skill-creator/scripts/run_eval.py +0 -310
  362. package/template/.agents/skills/skill-creator/scripts/run_loop.py +0 -328
  363. package/template/.agents/skills/skill-creator/scripts/utils.py +0 -47
  364. package/template/.agents/skills/supabase/CHANGELOG.md +0 -78
  365. package/template/.agents/skills/supabase/SKILL.md +0 -149
  366. package/template/.agents/skills/supabase/assets/feedback-issue-template.md +0 -17
  367. package/template/.agents/skills/supabase/references/skill-feedback.md +0 -17
  368. package/template/.agents/skills/supabase-postgres-best-practices/CHANGELOG.md +0 -73
  369. package/template/.agents/skills/supabase-postgres-best-practices/SKILL.md +0 -64
  370. package/template/.agents/skills/supabase-postgres-best-practices/references/_contributing.md +0 -170
  371. package/template/.agents/skills/supabase-postgres-best-practices/references/_sections.md +0 -39
  372. package/template/.agents/skills/supabase-postgres-best-practices/references/_template.md +0 -34
  373. package/template/.agents/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +0 -55
  374. package/template/.agents/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +0 -49
  375. package/template/.agents/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +0 -46
  376. package/template/.agents/skills/supabase-postgres-best-practices/references/conn-limits.md +0 -44
  377. package/template/.agents/skills/supabase-postgres-best-practices/references/conn-pooling.md +0 -41
  378. package/template/.agents/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +0 -46
  379. package/template/.agents/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +0 -54
  380. package/template/.agents/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +0 -53
  381. package/template/.agents/skills/supabase-postgres-best-practices/references/data-pagination.md +0 -50
  382. package/template/.agents/skills/supabase-postgres-best-practices/references/data-upsert.md +0 -50
  383. package/template/.agents/skills/supabase-postgres-best-practices/references/lock-advisory.md +0 -56
  384. package/template/.agents/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +0 -68
  385. package/template/.agents/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +0 -50
  386. package/template/.agents/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +0 -54
  387. package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +0 -45
  388. package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +0 -55
  389. package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +0 -55
  390. package/template/.agents/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +0 -44
  391. package/template/.agents/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +0 -40
  392. package/template/.agents/skills/supabase-postgres-best-practices/references/query-index-types.md +0 -48
  393. package/template/.agents/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +0 -43
  394. package/template/.agents/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +0 -45
  395. package/template/.agents/skills/supabase-postgres-best-practices/references/schema-constraints.md +0 -80
  396. package/template/.agents/skills/supabase-postgres-best-practices/references/schema-data-types.md +0 -46
  397. package/template/.agents/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +0 -59
  398. package/template/.agents/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +0 -55
  399. package/template/.agents/skills/supabase-postgres-best-practices/references/schema-partitioning.md +0 -55
  400. package/template/.agents/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +0 -61
  401. package/template/.agents/skills/supabase-postgres-best-practices/references/security-privileges.md +0 -54
  402. package/template/.agents/skills/supabase-postgres-best-practices/references/security-rls-basics.md +0 -50
  403. package/template/.agents/skills/supabase-postgres-best-practices/references/security-rls-performance.md +0 -63
  404. package/template/.agents/skills/writing/humanizer/LICENSE +0 -21
  405. package/template/.agents/skills/writing/humanizer/README.md +0 -209
  406. package/template/.agents/skills/writing/humanizer/SKILL.md +0 -456
  407. package/template/.agents/upstreams.json +0 -115
@@ -1,447 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * API image generation fallback: renders a mock or world board with the
4
- * user's own OpenAI key when the harness has no native image generation.
5
- *
6
- * context.mjs reports availability (it checks OPENAI_API_KEY); harness-native
7
- * generation always wins when present. This uses gpt-image-2 and spends the
8
- * user's API credit (roughly $0.05-0.25 per image at default quality), so the
9
- * skill states that before the first call in a session.
10
- *
11
- * node generate-image.mjs --prompt "..." --out mock.png [--size 1536x1024] [--quality medium]
12
- * node generate-image.mjs --prompt-file prompt.txt --out mock.png
13
- * node generate-image.mjs --prompt "..." --out mock.png --ref screenshot.png [--ref more.png]
14
- *
15
- * --ref anchors generation on input image(s) via the edits endpoint: pass a
16
- * captured screenshot of a representative existing page when comping a new
17
- * surface for an established world, so the identity comes from the real UI.
18
- *
19
- * node generate-image.mjs --plate <region-id> [--spec .impeccable/build/spec.json] [--quality high]
20
- *
21
- * --plate produces a shipping raster for one raster region of the measured
22
- * comp spec (comp-spec.mjs): it crops the region from the approved comp,
23
- * sends the crop as the reference with the spec's plate prompt (plus any
24
- * --prompt you add), picks the closest supported output size to the region's
25
- * aspect, writes the result to the region's `plate` path, embeds the prompt,
26
- * and scores the plate against the comp crop with comp-diff so a plate that
27
- * does not read as the region is reported (and, with --min, refused) here,
28
- * before it lands on the page. In IMPECCABLE_IMAGE_GEN_FAKE mode the plate is
29
- * the crop itself at 2x, so offline pipelines can walk the plate gate.
30
- */
31
- import fs from 'node:fs';
32
- import path from 'node:path';
33
- import { fileURLToPath } from 'node:url';
34
- import zlib from 'node:zlib';
35
-
36
- function arg(name, fallback = null) {
37
- const i = process.argv.indexOf(`--${name}`);
38
- if (i === -1) return fallback;
39
- const v = process.argv[i + 1];
40
- return v && !v.startsWith('--') ? v : fallback;
41
- }
42
-
43
- // ---------------------------------------------------------------------------
44
- // Fake mode (IMPECCABLE_IMAGE_GEN_FAKE=1)
45
- //
46
- // Deterministic offline stand-in for the OpenAI call: same prompt -> identical
47
- // bytes, no network, no key, cost line reads $0.00. Used by the new-work smoke
48
- // suite so the concept/serve-question/image chain can run without spend. The
49
- // output renders the prompt over a 2-3 color palette hashed from the prompt,
50
- // plus a "SYNTHETIC COMP" corner label. SVG carries the readable text; the
51
- // raster (.png/.webp/.jpg) fallback carries palette stripes and stows the
52
- // prompt + marker in a PNG tEXt chunk so downstream stays a valid image.
53
- // ---------------------------------------------------------------------------
54
-
55
- // FNV-1a 32-bit: tiny, dependency-free, stable across runs and platforms.
56
- function hash32(str) {
57
- let h = 0x811c9dc5;
58
- for (let i = 0; i < str.length; i++) {
59
- h ^= str.charCodeAt(i);
60
- h = Math.imul(h, 0x01000193);
61
- }
62
- return h >>> 0;
63
- }
64
-
65
- function hslToRgb(hDeg, s, l) {
66
- const h = ((hDeg % 360) + 360) % 360 / 360;
67
- const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
68
- const p = 2 * l - q;
69
- const hue = (t) => {
70
- let tt = t;
71
- if (tt < 0) tt += 1;
72
- if (tt > 1) tt -= 1;
73
- if (tt < 1 / 6) return p + (q - p) * 6 * tt;
74
- if (tt < 1 / 2) return q;
75
- if (tt < 2 / 3) return p + (q - p) * (2 / 3 - tt) * 6;
76
- return p;
77
- };
78
- return [hue(h + 1 / 3), hue(h), hue(h - 1 / 3)].map((c) => Math.round(c * 255));
79
- }
80
-
81
- const toHex = ([r, g, b]) =>
82
- '#' + [r, g, b].map((c) => c.toString(16).padStart(2, '0')).join('');
83
-
84
- // Two or three deterministic swatches derived from the prompt hash. The band
85
- // count itself is prompt-derived, so different prompts differ in palette.
86
- function palette(prompt) {
87
- const h = hash32(prompt);
88
- const base = h % 360;
89
- const bands = 2 + (h >>> 9) % 2; // 2 or 3
90
- const spread = 40 + (h >>> 3) % 120;
91
- const out = [];
92
- for (let i = 0; i < bands; i++) {
93
- const hue = base + i * spread;
94
- const light = 0.32 + ((h >>> (i * 5)) % 40) / 100; // 0.32 - 0.71
95
- out.push(hslToRgb(hue, 0.55, light));
96
- }
97
- return out;
98
- }
99
-
100
- function svgFake(prompt, [w, h]) {
101
- const colors = palette(prompt).map(toHex);
102
- const stops = colors
103
- .map((c, i) => `<stop offset="${Math.round((i / (colors.length - 1)) * 100)}%" stop-color="${c}"/>`)
104
- .join('');
105
- // Greedy word wrap tuned to the canvas width so the prompt stays legible.
106
- const perLine = Math.max(12, Math.floor(w / 26));
107
- const words = String(prompt).replace(/\s+/g, ' ').trim().split(' ');
108
- const lines = [];
109
- let cur = '';
110
- for (const word of words) {
111
- if ((cur + ' ' + word).trim().length > perLine) {
112
- if (cur) lines.push(cur);
113
- cur = word;
114
- } else {
115
- cur = (cur + ' ' + word).trim();
116
- }
117
- if (lines.length >= 10) break;
118
- }
119
- if (cur && lines.length < 11) lines.push(cur);
120
- const escape = (s) => String(s).replace(/[&<>]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' }[c]));
121
- const fontSize = Math.round(w / 24);
122
- const startY = h / 2 - ((lines.length - 1) * fontSize * 1.3) / 2;
123
- const text = lines
124
- .map((line, i) => `<text x="${w / 2}" y="${Math.round(startY + i * fontSize * 1.3)}" font-family="Helvetica, Arial, sans-serif" font-size="${fontSize}" fill="#ffffff" text-anchor="middle" dominant-baseline="middle">${escape(line)}</text>`)
125
- .join('');
126
- return `<?xml version="1.0" encoding="UTF-8"?>
127
- <svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${h}" viewBox="0 0 ${w} ${h}">
128
- <defs><linearGradient id="g" x1="0" y1="0" x2="1" y2="1">${stops}</linearGradient></defs>
129
- <rect width="${w}" height="${h}" fill="url(#g)"/>
130
- <rect x="0" y="0" width="${w}" height="${h}" fill="#000000" fill-opacity="0.22"/>
131
- ${text}
132
- <rect x="${w - Math.round(w / 4.2)}" y="${h - Math.round(h / 16)}" width="${Math.round(w / 4.2)}" height="${Math.round(h / 16)}" fill="#000000" fill-opacity="0.55"/>
133
- <text x="${w - Math.round(w / 8.4)}" y="${h - Math.round(h / 32)}" font-family="Helvetica, Arial, sans-serif" font-size="${Math.round(w / 60)}" letter-spacing="2" fill="#ffffff" text-anchor="middle" dominant-baseline="middle">SYNTHETIC COMP</text>
134
- </svg>
135
- `;
136
- }
137
-
138
- // Minimal valid PNG: palette stripes plus a tEXt chunk carrying the marker and
139
- // prompt, so a .png/.webp fake stays a decodable image and still contains the
140
- // "SYNTHETIC" bytes downstream tools look for.
141
- function crc32(buf) {
142
- let c = 0xffffffff;
143
- for (let i = 0; i < buf.length; i++) {
144
- c ^= buf[i];
145
- for (let k = 0; k < 8; k++) c = (c & 1) ? (0xedb88320 ^ (c >>> 1)) : (c >>> 1);
146
- }
147
- return (c ^ 0xffffffff) >>> 0;
148
- }
149
-
150
- function pngChunk(type, data) {
151
- const typeBuf = Buffer.from(type, 'latin1');
152
- const body = Buffer.concat([typeBuf, data]);
153
- const len = Buffer.alloc(4);
154
- len.writeUInt32BE(data.length, 0);
155
- const crc = Buffer.alloc(4);
156
- crc.writeUInt32BE(crc32(body), 0);
157
- return Buffer.concat([len, body, crc]);
158
- }
159
-
160
- function pngFake(prompt, [w, h]) {
161
- const colors = palette(prompt); // [[r,g,b], ...]
162
- const bandH = Math.ceil(h / colors.length);
163
- // Raw image: each scanline prefixed with a 0 filter byte, RGB pixels.
164
- const stride = w * 3;
165
- const raw = Buffer.alloc(h * (stride + 1));
166
- for (let y = 0; y < h; y++) {
167
- const rowStart = y * (stride + 1);
168
- raw[rowStart] = 0;
169
- const [r, g, b] = colors[Math.min(colors.length - 1, Math.floor(y / bandH))];
170
- for (let x = 0; x < w; x++) {
171
- const p = rowStart + 1 + x * 3;
172
- raw[p] = r;
173
- raw[p + 1] = g;
174
- raw[p + 2] = b;
175
- }
176
- }
177
- const ihdr = Buffer.alloc(13);
178
- ihdr.writeUInt32BE(w, 0);
179
- ihdr.writeUInt32BE(h, 4);
180
- ihdr[8] = 8; // bit depth
181
- ihdr[9] = 2; // color type: truecolor RGB
182
- const idat = zlib.deflateSync(raw, { level: 9 });
183
- const textData = Buffer.concat([
184
- Buffer.from('Comment', 'latin1'),
185
- Buffer.from([0]),
186
- Buffer.from(`SYNTHETIC COMP: ${String(prompt).replace(/\s+/g, ' ').trim()}`, 'latin1'),
187
- ]);
188
- return Buffer.concat([
189
- Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
190
- pngChunk('IHDR', ihdr),
191
- pngChunk('tEXt', textData),
192
- pngChunk('IDAT', idat),
193
- pngChunk('IEND', Buffer.alloc(0)),
194
- ]);
195
- }
196
-
197
- function parseSize(sizeStr) {
198
- const m = String(sizeStr).match(/^(\d+)x(\d+)$/);
199
- if (!m) return [1536, 1024];
200
- return [Number(m[1]), Number(m[2])];
201
- }
202
-
203
- // ---------------------------------------------------------------------------
204
- // Plate mode: one raster region of the measured spec -> a shipping plate.
205
- // ---------------------------------------------------------------------------
206
- const plateId = arg('plate');
207
- let plateCtx = null;
208
- if (plateId) {
209
- const { loadSpec, platePrompt, plateReference, SPEC_PATH } = await import('./comp-spec.mjs');
210
- const { decodePng, encodePng, loadRaster } = await import('./lib/png.mjs');
211
- const { crop, resize } = await import('./lib/raster.mjs');
212
- const specPath = arg('spec', SPEC_PATH);
213
- const spec = loadSpec(specPath);
214
- if (!spec) { console.error(`generate-image: no spec at ${specPath}; run comp-spec.mjs first`); process.exit(1); }
215
- const region = spec.regions.find((r) => r.id === plateId);
216
- if (!region) { console.error(`generate-image: no region ${plateId} in ${specPath}; ids: ${spec.regions.map((r) => r.id).join(', ')}`); process.exit(1); }
217
- if (region.medium !== 'raster') { console.error(`generate-image: region ${plateId} is ${region.medium}, not a plate; set its kind to plate|image|texture in the regions file`); process.exit(1); }
218
- let comp;
219
- try { comp = loadRaster(spec.comp).image; } catch (e) { console.error(`generate-image: cannot read comp ${spec.comp}: ${e.message}`); process.exit(1); }
220
- const ref = plateReference(comp, spec, region);
221
- const refPath = path.join(path.dirname(specPath), 'crops', `${region.id}.png`);
222
- fs.mkdirSync(path.dirname(refPath), { recursive: true });
223
- fs.writeFileSync(refPath, encodePng(ref, { text: { 'impeccable:crop-of': `${spec.comp}#${region.id}` } }));
224
- const out = arg('out', region.plate);
225
- fs.mkdirSync(path.dirname(out), { recursive: true });
226
- // Closest supported size to the region's aspect; the page crops the rest
227
- // with object-fit. The plates gate demands >= 1.5x the region's width
228
- // (capped at 1536), so a square region wider than 682px cannot ship from
229
- // 1024x1024: take the 1536-wide landscape frame instead and let cover crop.
230
- const aspect = region.px.w / region.px.h;
231
- const needW = Math.min(1536, Math.ceil(region.px.w * 1.5));
232
- let size = arg('size');
233
- if (!size) {
234
- if (aspect > 1.2) size = '1536x1024';
235
- else if (aspect < 0.83) size = needW > 1024 ? '1536x1024' : '1024x1536';
236
- else size = needW > 1024 ? '1536x1024' : '1024x1024';
237
- }
238
- const extra = arg('prompt') || (arg('prompt-file') ? fs.readFileSync(arg('prompt-file'), 'utf8') : '');
239
- // Chroma: an ink-on-ground plate (a line drawing, a figure on flat ground)
240
- // is generated on a flat key color and keyed to alpha, so the page's own
241
- // ground shows through instead of a second, mismatched paper. Default on
242
- // for kind plate when the comp region reads as ink over one flat ground;
243
- // --chroma / --no-chroma force it.
244
- const wantsChroma = process.argv.includes('--chroma') ? true : process.argv.includes('--no-chroma') ? false : (region.kind === 'plate' && inkOnGround(region));
245
- const chromaColor = '#00ff00';
246
- const chromaLine = wantsChroma ? ` Render the artwork on a perfectly flat, uniform bright green background (${chromaColor}) that fills every pixel not covered by the artwork; no paper texture, no vignette, no shadow on the green; the green will be removed and the artwork composited onto the page's own surface.` : '';
247
- const prompt = [platePrompt(spec, region), extra, chromaLine].filter(Boolean).join(' ');
248
- plateCtx = { spec, specPath, region, ref, refPath, out, size, prompt, comp, encodePng, resize, chroma: wantsChroma ? chromaColor : null };
249
- if (process.env.IMPECCABLE_IMAGE_GEN_FAKE) {
250
- const up = resize(ref, ref.width * 2, ref.height * 2);
251
- fs.writeFileSync(out, encodePng(up, { text: { 'impeccable:prompt': prompt, 'impeccable:fake': '1' } }));
252
- fs.writeFileSync(`${out}.json`, JSON.stringify({ prompt, createdAt: new Date().toISOString(), tool: 'generate-image.mjs', model: 'fake', plate: region.id, refs: [refPath] }, null, 2));
253
- console.log(`PLATE: ${out} (${up.width}x${up.height}, fake 2x crop of region ${region.id}, $0.00, no API call)`);
254
- process.exit(0);
255
- }
256
- // fall through to the real call below with the crop as the single --ref
257
- }
258
-
259
- /** A region whose crop is dominated by one ground color with a dark second: ink on ground. */
260
- function inkOnGround(region) {
261
- const pal = region.palette || [];
262
- if (pal.length < 2) return false;
263
- return pal[0].coverage >= 0.55;
264
- }
265
-
266
- function hexRgb(h) { const m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(h); return m ? [parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16)] : [0, 255, 0]; }
267
-
268
- /**
269
- * Key a flat color to alpha with a soft edge: pixels within `hard` of the key
270
- * go fully transparent, within `soft` fade, and green spill on edge pixels is
271
- * pulled toward the ink color. Writes back in place. Returns keyed fraction.
272
- */
273
- async function keyChroma(file, keyHex) {
274
- const { decodePng, encodePng } = await import('./lib/png.mjs');
275
- const img = decodePng(fs.readFileSync(file));
276
- const [kr, kg, kb] = hexRgb(keyHex);
277
- // sample the actual key from the corners: generators shift the green
278
- const corners = [[2, 2], [img.width - 3, 2], [2, img.height - 3], [img.width - 3, img.height - 3]];
279
- let sr = 0, sg = 0, sb = 0;
280
- for (const [x, y] of corners) { const p = (y * img.width + x) * 4; sr += img.data[p]; sg += img.data[p + 1]; sb += img.data[p + 2]; }
281
- const key = [sr / 4, sg / 4, sb / 4];
282
- const isGreenish = key[1] > 120 && key[1] > key[0] * 1.4 && key[1] > key[2] * 1.4;
283
- const K = isGreenish ? key : [kr, kg, kb];
284
- const hard = 60, soft = 120;
285
- let keyed = 0;
286
- for (let i = 0; i < img.data.length; i += 4) {
287
- const r = img.data[i], g = img.data[i + 1], b = img.data[i + 2];
288
- const d = Math.sqrt((r - K[0]) ** 2 + (g - K[1]) ** 2 + (b - K[2]) ** 2);
289
- // also treat "greener than both other channels by a margin" as key, for gradients the generator adds
290
- const greenDom = g > 150 && g - Math.max(r, b) > 60;
291
- if (d < hard || greenDom) { img.data[i + 3] = 0; keyed++; continue; }
292
- if (d < soft) {
293
- const a = (d - hard) / (soft - hard);
294
- img.data[i + 3] = Math.round(img.data[i + 3] * a);
295
- // despill: pull green down to the mean of the others on the fringe
296
- const m = (r + b) / 2; img.data[i + 1] = Math.round(g * a + m * (1 - a));
297
- }
298
- }
299
- // keep the tEXt chunks (the embedded prompt written before keying)
300
- fs.writeFileSync(file, encodePng(img, { text: img.text && Object.keys(img.text).length ? img.text : null }));
301
- return keyed / (img.data.length / 4);
302
- }
303
-
304
- async function scorePlate(ctx, outFile) {
305
- try {
306
- const { compare } = await import('./comp-diff.mjs');
307
- const { decodePng } = await import('./lib/png.mjs');
308
- let plate = decodePng(fs.readFileSync(outFile));
309
- // a keyed plate ships over the page ground: composite it over the region's
310
- // sampled ground before scoring, the way it will show
311
- if (ctx.chroma) {
312
- const { createImage, blit } = await import('./lib/raster.mjs');
313
- const g = (ctx.region.palette && ctx.region.palette[0] && ctx.region.palette[0].hex) || '#ffffff';
314
- const m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(g);
315
- const ground = m ? [parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16), 255] : [255, 255, 255, 255];
316
- const over = createImage(plate.width, plate.height, ground);
317
- blit(over, plate, 0, 0);
318
- plate = over;
319
- }
320
- // a plate ships under object-fit: cover, so score it the way it will show
321
- const res = compare({ comp: ctx.ref, build: plate, align: 'cover', kind: ctx.region.kind });
322
- const s = res.whole;
323
- const min = arg('min') ? parseFloat(arg('min')) : null;
324
- const line = `PLATE-SCORE ${ctx.region.id} ${(s.overall * 100).toFixed(0)}% against the comp region (structure ${(s.structure * 100).toFixed(0)}%, color ${(s.color * 100).toFixed(0)}%, detail ${(s.detail * 100).toFixed(0)}%)`;
325
- console.log(line);
326
- const { plateVerdict } = await import('./build-phase.mjs');
327
- const v = plateVerdict(ctx.region, s);
328
- if (!v.ok) console.log(`PLATE-WARN the plate does not read as region ${ctx.region.id}: ${v.reasons.join('; ')}. Open ${outFile} beside ${ctx.refPath} and regenerate before building on it; the plates gate refuses it as it stands.`);
329
- if (min != null && s.overall < min) { console.log(`PLATE-REJECTED below --min ${(min * 100).toFixed(0)}%`); process.exit(3); }
330
- } catch (e) {
331
- console.log(`PLATE-SCORE unavailable: ${e.message}`);
332
- }
333
- }
334
-
335
- // A comp written into .impeccable/mocks/ while a direction is dealt but the
336
- // build phases never started is a comp round happening outside the state
337
- // file, and every session cut after it resumes with no state to follow. The
338
- // roll writes .impeccable/build/pending.json; build-phase.mjs start clears
339
- // it. Refuse mock output until start has run (or --force-mock).
340
- {
341
- const outArg = arg('out') || (plateCtx && plateCtx.out) || '';
342
- const intoMocks = /(^|[\\/])\.impeccable[\\/]mocks[\\/]/.test(outArg) && !/[\\/]decision[\\/]/.test(outArg);
343
- const pending = fs.existsSync(path.join('.impeccable', 'build', 'pending.json'));
344
- const state = fs.existsSync(path.join('.impeccable', 'build', 'state.json'));
345
- if (intoMocks && pending && !state && !process.argv.includes('--force-mock')) {
346
- console.error(`generate-image: a direction was chosen (concept-seed rolled) but build-phase.mjs start has not run, so this comp would be generated outside the build's state. Run: node ${path.dirname(fileURLToPath(import.meta.url))}/build-phase.mjs start --direction <seed key> --kind <assigned|pick|challenger|canon> first (it opens the comps phase), then generate. --force-mock overrides.`);
347
- process.exit(4);
348
- }
349
- }
350
-
351
- if (process.env.IMPECCABLE_IMAGE_GEN_FAKE) {
352
- const fakePromptFile = arg('prompt-file');
353
- const fakePrompt = fakePromptFile ? fs.readFileSync(fakePromptFile, 'utf8') : arg('prompt');
354
- const fakeOut = arg('out');
355
- if (!fakePrompt || !fakeOut) {
356
- console.error('generate-image: --prompt (or --prompt-file) and --out are required.');
357
- process.exit(1);
358
- }
359
- const dims = parseSize(arg('size', '1536x1024'));
360
- const bytes = fakeOut.endsWith('.svg')
361
- ? Buffer.from(svgFake(fakePrompt, dims), 'utf8')
362
- : pngFake(fakePrompt, dims);
363
- fs.writeFileSync(fakeOut, bytes);
364
- console.log(`IMAGE: ${fakeOut} (${dims[0]}x${dims[1]}, fake synthetic comp, $0.00, no API call)`);
365
- process.exit(0);
366
- }
367
-
368
- const key = process.env.OPENAI_API_KEY;
369
- if (!key) {
370
- console.error('generate-image: OPENAI_API_KEY is not set; use the harness-native image tool instead.');
371
- process.exit(1);
372
- }
373
- const promptFile = arg('prompt-file');
374
- const prompt = plateCtx ? plateCtx.prompt : (promptFile ? fs.readFileSync(promptFile, 'utf8') : arg('prompt'));
375
- const out = plateCtx ? plateCtx.out : arg('out');
376
- if (!prompt || !out) {
377
- console.error('generate-image: --prompt (or --prompt-file) and --out are required.');
378
- process.exit(1);
379
- }
380
- const size = plateCtx ? plateCtx.size : arg('size', '1536x1024');
381
- const quality = arg('quality', plateCtx ? 'high' : 'medium');
382
- // Reference images (--ref, repeatable): route through the edits endpoint,
383
- // which accepts input images. This is how a comp for an established world
384
- // inherits the real UI's identity from a captured screenshot instead of a
385
- // prose paraphrase of it; the prompt then describes the NEW surface and the
386
- // reference carries palette, type, and component character.
387
- const refs = (() => {
388
- const found = plateCtx ? [plateCtx.refPath] : [];
389
- for (let i = 0; i < process.argv.length; i += 1) {
390
- if (process.argv[i] === '--ref' && process.argv[i + 1] && !process.argv[i + 1].startsWith('--')) found.push(process.argv[i + 1]);
391
- }
392
- return found;
393
- })();
394
-
395
- let response;
396
- if (refs.length) {
397
- const form = new FormData();
398
- form.append('model', 'gpt-image-2');
399
- form.append('prompt', prompt);
400
- form.append('size', size);
401
- form.append('quality', quality);
402
- form.append('n', '1');
403
- for (const ref of refs) {
404
- const bytes = fs.readFileSync(ref);
405
- const type = ref.endsWith('.png') ? 'image/png' : ref.endsWith('.webp') ? 'image/webp' : 'image/jpeg';
406
- form.append('image[]', new Blob([bytes], { type }), ref.split('/').pop());
407
- }
408
- response = await fetch('https://api.openai.com/v1/images/edits', {
409
- method: 'POST',
410
- headers: { Authorization: `Bearer ${key}` },
411
- body: form,
412
- });
413
- } else {
414
- response = await fetch('https://api.openai.com/v1/images/generations', {
415
- method: 'POST',
416
- headers: { Authorization: `Bearer ${key}`, 'content-type': 'application/json' },
417
- body: JSON.stringify({ model: 'gpt-image-2', prompt, size, quality, n: 1 }),
418
- });
419
- }
420
- if (!response.ok) {
421
- console.error(`generate-image: API error ${response.status}: ${(await response.text()).slice(0, 300)}`);
422
- process.exit(1);
423
- }
424
- const json = await response.json();
425
- const b64 = json?.data?.[0]?.b64_json;
426
- if (!b64) {
427
- console.error('generate-image: no image in response');
428
- process.exit(1);
429
- }
430
- fs.writeFileSync(out, Buffer.from(b64, 'base64'));
431
- // The prompt travels with the asset: embedded in the file itself (EXIF-class
432
- // metadata via embed-prompt.mjs) so intent survives copies across harnesses,
433
- // plus a sidecar for anything that indexes rather than opens the image.
434
- let embedded = false;
435
- try {
436
- const { spawnSync } = await import('node:child_process');
437
- const result = spawnSync(process.execPath, [fileURLToPath(new URL('./embed-prompt.mjs', import.meta.url)), out, '--prompt', prompt], { stdio: 'ignore' });
438
- embedded = !result.error && result.status === 0;
439
- if (!embedded) console.warn('generate-image: failed to embed prompt in the image');
440
- fs.writeFileSync(`${out}.json`, JSON.stringify({ prompt, createdAt: new Date().toISOString(), tool: 'generate-image.mjs', model: 'gpt-image-2', ...(refs.length ? { refs } : {}) }, null, 2));
441
- } catch { /* embedding is best-effort */ }
442
- console.log(`IMAGE: ${out} (${size}, ${quality}, gpt-image-2, billed to your OpenAI key); ${embedded ? 'prompt embedded + sidecar' : 'sidecar'} at ${out}.json`);
443
- if (plateCtx && plateCtx.chroma) {
444
- const frac = await keyChroma(out, plateCtx.chroma);
445
- console.log(`PLATE-CHROMA keyed ${(frac * 100).toFixed(0)}% of pixels to alpha (${plateCtx.chroma}); place with a plain <img> over the page's own ground, no background on the plate. If the keyed fraction is under 20% the generator ignored the key: regenerate with --no-chroma and use mix-blend-mode: multiply instead.`);
446
- }
447
- if (plateCtx) await scorePlate(plateCtx, out);