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,814 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * External concept seed: the dice half of new-work's complete-direction and
4
- * established-world surface procedures.
5
- *
6
- * Before this script runs, the model retrieves cultural material and derives
7
- * a grounded shortlist of complete candidate directions from it (see
8
- * reference/new-work.md). Left alone, it then always builds its #1 —
9
- * and a single model's resonance ranking is deterministic, so every run
10
- * in a category ships the same one or two concepts. Measured: 30/35
11
- * identical concepts across 16 prompt framings; the model cannot roll
12
- * its own dice.
13
- *
14
- * This script rolls them from outside, the same trick that made the
15
- * palette seed work:
16
- * - ASSIGNED INDEX: which entry of the model's own resonance-ordered
17
- * shortlist gets built. The assignment is the dice: it never chooses an
18
- * ungrounded ingredient, it only refuses the argmax rut. Attended runs
19
- * present the assigned direction and offer re-roll instead of a ranked
20
- * lineup, because a lineup hands selection back to a taste function
21
- * (model or user) and taste functions pick the safest card.
22
- * - CHALLENGERS (6): outside forms from concept-ingredients.json, two from
23
- * each challenger tier (graphic system, instrument language, atmosphere
24
- * world), fused with the product first (challenger supplies form and
25
- * system grammar, product supplies every fact, clarity wins conflicts),
26
- * then weighed against the derived candidates on audience identification
27
- * and product clarity. They win only when they beat the grounded list;
28
- * measured behavior is that they lose to strong cultural material and
29
- * win over thin categories, which is the intended shape.
30
- * - RE-ROLL (--reroll <n>): round n of the same base key. The script
31
- * recomputes what rounds 0..n-1 drew, excludes all of it, and rolls a
32
- * fresh assigned index, challengers, and compositions. One base key therefore
33
- * reproduces the entire chain of rounds.
34
- * - REGISTER (--register safer|bolder): the user's steering on the
35
- * familiar-to-bold axis, applied to a re-roll round. A register changes
36
- * only what this round instructs, never what it dealt: the same key and
37
- * reroll count reproduce the same deal whatever the register, so the
38
- * exclusion chain never forks. bolder presents the dealt foreign forms
39
- * as the whole hand (first-dealt leads, dice-assigned by deal order);
40
- * safer spends the dealt hand unseen and presents the familiar register,
41
- * the model's conventional grounded candidates plus the canon against
42
- * named competitors, the one sanctioned lineup of the model's own list.
43
- * Registers are user-requested, never pre-selected by the model.
44
- * - RATINGS: the reviewer's approval ratings weight the challenger draw
45
- * (3-star doubles the odds, 1-star sits out); the approved pool itself
46
- * is unchanged.
47
- *
48
- * Usage:
49
- * node scripts/concept-seed.mjs --scope direction --mode persuade
50
- * node scripts/concept-seed.mjs --scope surface --mode operate --from <key>
51
- * node scripts/concept-seed.mjs --scope surface --mode operate --grain flow
52
- * node scripts/concept-seed.mjs --scope direction --candidate-count 6
53
- * node scripts/concept-seed.mjs --scope direction --mode persuade --from <key> --reroll 1
54
- * node scripts/concept-seed.mjs --scope direction --mode persuade --from <key> --reroll 1 --register bolder
55
- * node scripts/concept-seed.mjs --chosen <challenger-id> --kind challenger --from <key> --scope direction
56
- * node scripts/concept-seed.mjs --kind assigned --from <key> --scope direction
57
- *
58
- * --grain names how much of the product is in play: product, flow, view, or
59
- * region. A docs site, an onboarding flow, a landing page and a data table are
60
- * four different amounts of product and want different compositions. Grain is a
61
- * preference: it deals matching compositions first and tops up from the rest of
62
- * the register, and the rendered seed says how many actually matched so a
63
- * borrowed structure is never mistaken for a supplied one.
64
- *
65
- * --platform names the delivery target (web, ios, android). Unlike grain this is
66
- * a hard filter: a composition that needs hover or a pointer does not degrade on
67
- * a phone, it stops working. --mode also gates which worlds are eligible, for
68
- * worlds whose reviewer marked them as carrying only some modes.
69
- *
70
- * --mode names the requested surface's mode (persuade, operate, read,
71
- * experience) so the appended compositions match its register of work; omitted,
72
- * they roll from the full approved pool.
73
- *
74
- * Challenger data resolves in order: a local catalog directory (the private
75
- * service repo, evals, and tests set IMPECCABLE_CATALOG_DIR), then the roll
76
- * API at impeccable.style, then a degraded assignment-only seed when both are
77
- * unavailable. The anonymous choice ping fires once per resolved attended
78
- * round on API-dealt rolls: --kind names which card class won (assigned,
79
- * pick, challenger, canon) so share metrics have a denominator, --chosen
80
- * carries the catalog id when a dealt challenger won, and --register rides
81
- * along when the round came from a steered hand. Grounded candidates' names
82
- * never leave the machine. DO_NOT_TRACK or IMPECCABLE_NO_TELEMETRY disables
83
- * the ping entirely.
84
- *
85
- * Env vars:
86
- * IMPECCABLE_CONCEPT_SEED — same as --from; for reproducible eval runs.
87
- * IMPECCABLE_CATALOG_DIR — directory holding the four catalog JSON files.
88
- * IMPECCABLE_API_URL — roll API base (default https://impeccable.style/api).
89
- * IMPECCABLE_NO_TELEMETRY — disables the choice ping (DO_NOT_TRACK also honored).
90
- */
91
-
92
- import crypto from 'node:crypto';
93
- import { dirname, join, relative, resolve } from 'node:path';
94
- import { readFileSync, realpathSync } from 'node:fs';
95
- import { fileURLToPath } from 'node:url';
96
- import {
97
- approvedPoolRevision,
98
- readConceptCatalog,
99
- validateConceptCatalog,
100
- WELL_TIERS,
101
- } from './lib/concept-catalog.mjs';
102
- import { readCompositionCatalog } from './lib/composition-catalog.mjs';
103
- import {
104
- COMPOSITION_GRAINS,
105
- COMPOSITION_PLATFORMS,
106
- runSyncSelection,
107
- selectApprovedChallengers as selectApprovedChallengersCore,
108
- selectApprovedCompositions as selectApprovedCompositionsCore,
109
- } from './lib/roll-selection.mjs';
110
-
111
- const here = dirname(fileURLToPath(import.meta.url));
112
-
113
- // Data resolution order: a local catalog (the private service repo, evals, and
114
- // tests point IMPECCABLE_CATALOG_DIR at one), then the roll API, then a
115
- // degraded assignment-only seed. The full catalog does not ship with the skill.
116
- const CATALOG_DIR = process.env.IMPECCABLE_CATALOG_DIR || here;
117
- const API_BASE = (process.env.IMPECCABLE_API_URL || 'https://impeccable.style/api').replace(/\/$/, '');
118
- const API_TIMEOUT_MS = Number(process.env.IMPECCABLE_API_TIMEOUT || 4000);
119
- // All API calls in one seed run share a single deadline so an unreachable
120
- // network degrades after one timeout total, never one timeout per call.
121
- let apiDeadline = null;
122
- function apiBudgetMs() {
123
- if (apiDeadline === null) apiDeadline = Date.now() + API_TIMEOUT_MS;
124
- return Math.max(0, apiDeadline - Date.now());
125
- }
126
-
127
- const localStates = new Map();
128
- function loadLocal(catalogDir = CATALOG_DIR) {
129
- if (localStates.has(catalogDir)) return localStates.get(catalogDir);
130
- let localState;
131
- try {
132
- const catalogState = readConceptCatalog(
133
- join(catalogDir, 'concept-ingredients.json'),
134
- join(catalogDir, 'concept-reviews.json')
135
- );
136
- const validation = validateConceptCatalog(catalogState.catalog, catalogState.reviewData);
137
- if (validation.errors.length > 0) {
138
- throw new Error(`invalid catalog: ${validation.errors.join('; ')}`);
139
- }
140
- const compositionState = readCompositionCatalog(
141
- join(catalogDir, 'composition-ingredients.json'),
142
- join(catalogDir, 'composition-reviews.json')
143
- );
144
- localState = {
145
- concepts: catalogState.concepts,
146
- compositions: compositionState.compositions,
147
- };
148
- } catch {
149
- localState = null;
150
- }
151
- localStates.set(catalogDir, localState);
152
- return localState;
153
- }
154
-
155
- function requireLocalConcepts() {
156
- const local = loadLocal();
157
- if (!local) {
158
- throw new Error('concept-seed: no local catalog (set IMPECCABLE_CATALOG_DIR or pass sourceConcepts)');
159
- }
160
- return local;
161
- }
162
-
163
- async function fetchRoll({ scope, key, mode, grain, platform, reroll }) {
164
- const params = new URLSearchParams({ scope, key, reroll: String(reroll) });
165
- if (mode) params.set('mode', mode);
166
- if (grain) params.set('grain', grain);
167
- if (platform) params.set('platform', platform);
168
- const controller = new AbortController();
169
- const timer = setTimeout(() => controller.abort(), apiBudgetMs());
170
- try {
171
- // Race the budget explicitly: abort signals do not reliably cancel the
172
- // TCP connect phase, so a blackholed route would otherwise stall ~10s.
173
- const response = await Promise.race([
174
- fetch(`${API_BASE}/roll?${params}`, { signal: controller.signal }),
175
- new Promise(resolveTimeout => setTimeout(() => resolveTimeout(null), apiBudgetMs())),
176
- ]);
177
- if (!response) return null;
178
- if (!response.ok) return null;
179
- const roll = await response.json();
180
- if (!Array.isArray(roll.challengers) || roll.challengers.length === 0) return null;
181
- return roll;
182
- } catch {
183
- return null;
184
- } finally {
185
- clearTimeout(timer);
186
- }
187
- }
188
-
189
- function telemetryDisabled() {
190
- return Boolean(process.env.IMPECCABLE_NO_TELEMETRY || process.env.DO_NOT_TRACK);
191
- }
192
-
193
- // Anonymous choice ping: one per resolved attended direction round. kind
194
- // says which card class won (assigned / pick / challenger / canon), so
195
- // pick-share and canon-share have a denominator; chosenId rides along only
196
- // when a dealt catalog world won, and register only when the round came from
197
- // a steered hand. Grounded candidates' names never leave the machine: they
198
- // are derived from the user's project, so the ping carries the kind alone.
199
- // Fire-and-forget; never fails the caller.
200
- const PING_KINDS = new Set(['assigned', 'pick', 'challenger', 'canon']);
201
- export async function pingChosen({ chosenId, key, scope, mode, kind, register }) {
202
- if (telemetryDisabled()) return false;
203
- if (kind && !PING_KINDS.has(kind)) return false;
204
- if (register && register !== 'safer' && register !== 'bolder') return false;
205
- // Legacy shape: a bare challenger id with no kind stays a valid ping.
206
- if (!chosenId && !kind) return false;
207
- if ((kind === 'challenger' || !kind) && !chosenId) return false;
208
- const controller = new AbortController();
209
- const timer = setTimeout(() => controller.abort(), apiBudgetMs());
210
- try {
211
- await fetch(`${API_BASE}/chosen`, {
212
- method: 'POST',
213
- headers: { 'Content-Type': 'application/json' },
214
- body: JSON.stringify({
215
- ...(chosenId ? { chosenId } : {}),
216
- key,
217
- scope,
218
- mode,
219
- ...(kind ? { kind } : {}),
220
- ...(register ? { register } : {}),
221
- }),
222
- signal: controller.signal,
223
- });
224
- return true;
225
- } catch {
226
- return false;
227
- } finally {
228
- clearTimeout(timer);
229
- }
230
- }
231
-
232
- const CARD_BASE = process.env.IMPECCABLE_CARD_BASE || 'https://impeccable.style/worlds/cards';
233
-
234
- export function renderChallenger(concept, index) {
235
- const system = concept.system.map(rule => ` - ${rule}`).join('\n');
236
- const board = concept.cardBoard || `${CARD_BASE}/${concept.id}.webp`;
237
- const hero = concept.cardHero || `${CARD_BASE}/${concept.id}-hero.webp`;
238
- return ` ${index + 1}. ${concept.form}
239
- SOURCE ID: ${concept.id}
240
- CREATIVE SPARK: ${concept.spark}
241
- SYSTEM GRAMMAR:
242
- ${system}
243
- WEB LEVERAGE: ${concept.webLeverage}
244
- QUALITY BAR: board ${board} · hero ${hero}`;
245
- }
246
-
247
- export function renderComposition(composition, index = null) {
248
- const grammar = composition.grammar.map(rule => ` - ${rule}`).join('\n');
249
- return ` ${index == null ? '' : `${index + 1}. `}${composition.form}
250
- SOURCE ID: ${composition.id}
251
- SPARK: ${composition.spark}
252
- COMPOSITION GRAMMAR:
253
- ${grammar}
254
- WEB LEVERAGE: ${composition.webLeverage}`;
255
- }
256
-
257
- // Selection itself lives in lib/roll-selection.mjs so this script and the roll
258
- // API run one algorithm rather than two that drifted. These wrappers add only
259
- // what is local to the skill: resolving the catalog when no pool is passed, and
260
- // driving the generator with Node's synchronous hash, which keeps a local render
261
- // synchronous for prepared eval sessions and tests.
262
- function driveSelection(generator) {
263
- return runSyncSelection(generator, input => crypto.createHash('sha256').update(input).digest('hex'));
264
- }
265
-
266
- export function dealCompositions({ scope, key, reroll = 0, mode = null, grain = null, platform = null, sourceCompositions = null, count = 3 }) {
267
- const compositions = sourceCompositions ?? requireLocalConcepts().compositions;
268
- return driveSelection(selectApprovedCompositionsCore({ scope, key, reroll, mode, grain, platform, compositions, count }));
269
- }
270
-
271
- // Array-returning form, which is what every caller wanted before the match
272
- // report existed.
273
- export function selectApprovedCompositions(options) {
274
- return dealCompositions(options).picks;
275
- }
276
-
277
- // Compatibility for callers that need a single smoke-test sample.
278
- export function selectApprovedComposition(options) {
279
- return selectApprovedCompositions({ ...options, count: 1 })[0] ?? null;
280
- }
281
-
282
- export function selectApprovedChallengers({ scope, key, reroll = 0, mode = null, sourceConcepts = null }) {
283
- const source = sourceConcepts ?? requireLocalConcepts().concepts;
284
- const { approved, picks } = driveSelection(selectApprovedChallengersCore({ scope, key, reroll, mode, concepts: source }));
285
- return {
286
- approved,
287
- picks,
288
- poolRevision: approvedPoolRevision(source),
289
- catalogCount: source.length,
290
- };
291
- }
292
-
293
- const SEED_MODES = new Set(['persuade', 'operate', 'read', 'experience']);
294
-
295
- export function renderConceptSeed({
296
- scope = 'surface',
297
- key = process.env.IMPECCABLE_CONCEPT_SEED || crypto.randomBytes(4).toString('hex'),
298
- reroll = 0,
299
- register = null,
300
- mode = null,
301
- grain = null,
302
- platform = null,
303
- candidateCount = 7,
304
- catalogDir = CATALOG_DIR,
305
- _resolvedData = undefined,
306
- } = {}) {
307
- if (scope !== 'surface' && scope !== 'direction') {
308
- throw new Error('concept-seed: --scope must be direction or surface');
309
- }
310
- if (!Number.isInteger(reroll) || reroll < 0) {
311
- throw new Error('concept-seed: --reroll must be a non-negative integer');
312
- }
313
- if (register !== null && register !== 'safer' && register !== 'bolder') {
314
- throw new Error('concept-seed: --register must be safer or bolder');
315
- }
316
- if (register !== null && reroll < 1) {
317
- throw new Error('concept-seed: --register steers a re-roll round; pass --reroll <n> with it');
318
- }
319
- if (register !== null && scope !== 'direction') {
320
- throw new Error('concept-seed: --register applies to direction rounds only');
321
- }
322
- if (mode !== null && !SEED_MODES.has(mode)) {
323
- throw new Error('concept-seed: --mode must be persuade, operate, read, or experience');
324
- }
325
- // Grain needs no mode: how much of the product is in play is independent of
326
- // which register of work it is.
327
- if (grain !== null && !COMPOSITION_GRAINS.includes(grain)) {
328
- throw new Error(`concept-seed: --grain must be one of ${COMPOSITION_GRAINS.join(', ')}`);
329
- }
330
- if (platform !== null && !COMPOSITION_PLATFORMS.includes(platform)) {
331
- throw new Error(`concept-seed: --platform must be one of ${COMPOSITION_PLATFORMS.join(', ')}`);
332
- }
333
- if (!Number.isInteger(candidateCount) || candidateCount < 5 || candidateCount > 7) {
334
- throw new Error('concept-seed: --candidate-count must be an integer from 5 to 7');
335
- }
336
- const unit = (salt) => {
337
- const h = crypto.createHash('sha256').update(`${scope}:${salt}:${key}`).digest();
338
- return h.readUInt32BE(0) / 0xffffffff;
339
- };
340
- const indexSalt = reroll === 0 ? 'index' : `index:reroll-${reroll}`;
341
- const buildIndex = 3 + Math.floor(unit(indexSalt) * (candidateCount - 2)); // 3..candidateCount
342
- // Surface scope deals a hand of three grounded structures: one card is not
343
- // a choice, and the full ranked list would hand selection back to the
344
- // model's taste. The dice pick all three; the primary index leads. The
345
- // no-lineup rule stays direction-only, where it was written for worlds.
346
- const dealtIndices = [buildIndex];
347
- for (let draw = 0; scope === 'surface' && dealtIndices.length < Math.min(3, candidateCount); draw += 1) {
348
- const idx = 1 + Math.floor(unit(`${indexSalt}:deal-${draw}`) * candidateCount);
349
- if (!dealtIndices.includes(idx)) dealtIndices.push(idx);
350
- if (draw > 64) { // hash repeats cannot stall the deal
351
- for (let fill = 1; dealtIndices.length < Math.min(3, candidateCount); fill += 1) {
352
- if (!dealtIndices.includes(fill)) dealtIndices.push(fill);
353
- }
354
- }
355
- }
356
-
357
- // Local catalog first (private repo, evals, tests), then the roll API,
358
- // then a degraded assignment-only seed. The assigned index is pure local
359
- // math, so even a fully offline run keeps the anti-argmax mechanism.
360
- let data = _resolvedData ?? null;
361
- if (_resolvedData === undefined) {
362
- const local = loadLocal(catalogDir);
363
- if (local) {
364
- const { approved, picks, poolRevision, catalogCount } = selectApprovedChallengers({
365
- scope,
366
- key,
367
- reroll,
368
- mode,
369
- sourceConcepts: local.concepts,
370
- });
371
- data = {
372
- source: 'local',
373
- poolRevision,
374
- approvedCount: approved.length,
375
- catalogCount,
376
- challengers: picks,
377
- ...(() => {
378
- const dealt = dealCompositions({ scope, key, reroll, mode, grain, platform, sourceCompositions: local.compositions });
379
- return { compositions: dealt.picks, compositionMatch: dealt.match };
380
- })(),
381
- };
382
- } else {
383
- // Keep local renders synchronous for prepared eval sessions and tests;
384
- // installed skills without a bundled catalog resolve through the API.
385
- return fetchRoll({ scope, key, mode, grain, platform, reroll }).then(roll => renderConceptSeed({
386
- scope,
387
- key,
388
- reroll,
389
- register,
390
- mode,
391
- grain,
392
- platform,
393
- candidateCount,
394
- catalogDir,
395
- _resolvedData: roll ? {
396
- source: 'api',
397
- poolRevision: roll.poolRevision,
398
- approvedCount: roll.approvedCount,
399
- catalogCount: roll.catalogCount,
400
- challengers: roll.challengers,
401
- compositions: Array.isArray(roll.compositions)
402
- ? roll.compositions
403
- : Array.isArray(roll.stagings)
404
- ? roll.stagings
405
- : roll.staging ? [roll.staging] : [],
406
- } : null,
407
- }));
408
- }
409
- }
410
-
411
- const promotedInstruction = scope === 'direction'
412
- ? `After ordering the grounded directions by resonance, build candidate
413
- ${buildIndex} of your own grounded list; the assignment never points at a
414
- challenger. The assignment is the roll, not a suggestion: your top-ranked
415
- direction is what every run would ship, so the script decides which grounded
416
- direction gets built. Each direction joins a durable visual system to a
417
- concrete expression for the requested first surface, decided as one. It must
418
- survive the current task plus navigation, quiet and dense content,
419
- interaction and state, and a substantially different future surface. In an
420
- attended run, present the assigned direction fully committed and offer
421
- re-roll. You may add ONE card for your top-ranked grounded candidate when
422
- it is not the assigned direction, kicker IMPECCABLE’S PICK, with an honest risk line
423
- naming its familiarity; one pick card, never a ranked lineup, and the pick
424
- never takes the lead position. When the assignment IS your top candidate,
425
- there is no pick card. Re-roll yourself only
426
- on named factual grounds, when the assignment cannot carry the product's
427
- truth or task; taste is never grounds.`
428
- : `After ordering the task's grounded structural candidates by resonance,
429
- deal candidates ${dealtIndices.join(', ')} of your own grounded list to the
430
- table; index ${buildIndex} leads, and the deal never points at a challenger.
431
- The deal is the roll, not a suggestion: the dice decide which structures
432
- reach the user, so the ranking rut stays broken while the user still gets a
433
- real choice, and the full ranked list stays yours. In an attended run,
434
- present the three dealt structures as full cards of equal salience, the
435
- lead carrying kicker THE ROLL, with steer and re-roll, and let the user
436
- lock one in; the world is already settled, so this choice is composition.
437
- Visualize every dealt card: with image generation available and a
438
- comp-led default (.impeccable/config.json buildPath; the page toggle
439
- handles the exception), declare a comp per card and generate after
440
- serving, lead first; otherwise author each card's wireframe field (see
441
- serve-question --schema) and the page draws the schematic. Carry the
442
- recorded default in the payload as buildPath with toggle: true. Locking a card
443
- approves its comp: a surface round that put three visualized structures on
444
- the table replaces the three-option comp round in visualize.md. Re-roll
445
- yourself only when every dealt structure fails audience identification or
446
- product clarity on named factual grounds.`;
447
-
448
- const challengerInstruction = scope === 'direction'
449
- ? `Fuse each challenger before judging it: the challenger supplies the form
450
- and its system grammar, the product supplies every fact, and clarity wins
451
- conflicts. Weigh the fused result against the assigned direction on exactly
452
- two axes, audience identification and product clarity. Losing to strong
453
- grounded material is a valid outcome; beating a thin or tool-monoculture
454
- list is the point. A fused challenger that wins both axes becomes the build.
455
- Close the weighing with a verdict per challenger, decided before any
456
- borrowing is considered: wins (beats the assigned direction on both axes),
457
- competitive (holds one axis), or declined (loses both). A declined
458
- challenger is not spent: name the one discipline of its system the assigned
459
- direction lacks, and raise the assigned direction to match before
460
- presenting it. A donation transfers ambition and system discipline, never
461
- the challenger's clothes; one world owns the page. Write each raise as its
462
- own named line on the presented direction, and carry every verdict, kept
463
- line, and raise into the decision page payload.`
464
- : `A challenger wins only when its fused result beats the grounded list on
465
- audience identification and product clarity. It may change task topology or
466
- interaction, but never the committed visual identity.`;
467
-
468
- const authorityInstruction = scope === 'direction'
469
- ? `PRODUCT.md and explicit incumbent brand commitments constrain every direction.
470
- The seed never chooses exact colors, fonts, tokens, or a user preference, and
471
- it never permits the world and first surface to be selected independently.`
472
- : `PRODUCT.md and DESIGN.md constrain every surface candidate's identity
473
- vocabulary; they do not cancel task-level composition. The seed never
474
- authorizes a new palette, type system, material world, or unfamiliar control
475
- behavior.`;
476
-
477
- const richnessInstruction = `The CREATIVE SPARK is a complete visual system, not a theme or decorative
478
- reference. Translate every supplied system rule into the product: palette and
479
- material, type and composition, topology, controls and states, and adaptation.
480
- Keep the source's visible character, scale, rhythm, and interaction instead of
481
- reducing vivid grammar to generic nouns. When the source is already a credible
482
- interface language, commit to it across navigation, content, controls, and
483
- states. Otherwise keep a literal carrier only when it becomes functional.
484
- Ambitious motion, spatial media, or interaction is welcome when it strengthens
485
- the product without weakening semantics, performance, or fallback behavior.`;
486
-
487
- if (!data) {
488
- // A degraded roll can still serve the safer register, which needs no
489
- // catalog at all: the assignment machinery is suppressed entirely, the
490
- // same as the non-degraded safer round, because emitting both "the user
491
- // picks" and a mandatory numbered build order hands the model two
492
- // contradicting instructions and the mandatory one tends to win. The
493
- // bolder register is exactly the thing degradation took away, so it
494
- // falls back to a plain grounded round, disclosed.
495
- const degradedHeader = `${scope.toUpperCase()} CONCEPT SEED (key: ${key}; mode: ${mode ?? 'unscoped'}; source: degraded; rerun with --scope ${scope}${mode ? ` --mode ${mode}` : ''} --from ${key}${reroll > 0 ? ` --reroll ${reroll}` : ''}${register ? ` --register ${register}` : ''} --candidate-count ${candidateCount})`;
496
- if (register === 'safer') {
497
- return `${degradedHeader}
498
- SAFER REGISTER (user-requested): the assigned index is suspended this
499
- round; the user picks, and no candidate is mandated. Present the familiar
500
- register: your remaining grounded candidates from the conventional end, at
501
- most three, as full cards with an honest risk line each, plus the canon
502
- executed against two or three named competitors. This is the one sanctioned
503
- lineup of your own ranked candidates; it exists only by this explicit
504
- request. When the user voices a standing preference for it, record a brand
505
- commitment in PRODUCT.md.
506
- ${authorityInstruction}
507
- A user- or brief-pinned decision beats the roll, always.
508
- REGISTER (restated for truncated readers): safer, user-requested; the
509
- assigned index is suspended this round and the user picks; seed key ${key}.
510
- `;
511
- }
512
- const degradedRegister = register === 'bolder'
513
- ? `BOLDER REGISTER UNAVAILABLE: bolder deals foreign forms, and this roll ran
514
- degraded with no catalog and no roll service, so there is nothing bold to
515
- deal. Tell the user, then run this round as a plain grounded re-roll; the
516
- assignment below applies.
517
- `
518
- : '';
519
- return `${degradedHeader}
520
- ${degradedRegister}${scope === 'direction' ? `ASSIGNED INDEX: ${buildIndex}` : `DEALT INDICES: ${dealtIndices.join(', ')} (index ${buildIndex} leads)`}
521
- ${promotedInstruction}
522
- The assignment exists to refuse the model's ranking rut, never to outrank
523
- the user or the brief. Never expose assignment metadata in user-facing labels.
524
- No challengers this run: the roll service was unreachable and no local
525
- catalog exists. A sandboxed shell without network egress is the most common
526
- cause; before accepting degradation, rerun this command once through the
527
- harness's network-enabled or escalated command tool. When that rerun needs
528
- an approval, state exactly what the approver must know: this script's only
529
- network contact is one GET to https://impeccable.style/api/roll whose query
530
- carries scope, mode, an eight-hex seed key, and a re-roll counter; no
531
- project files, prompts, code, or conversation context are transmitted, and
532
- nothing is written. An approval request naming that URL and payload judges
533
- the real action; a bare "run with network" invites rejection for contacting
534
- an unspecified domain. If the rerun is still refused, proceed with the
535
- grounded candidates alone; the assignment above still applies at full
536
- strength. Tell the user plainly that this roll
537
- ran degraded, with no challengers and no quality-bar boards; do not present
538
- the outcome as a full roll. A degraded roll changes the cards, not the
539
- channel: when a browser can open, present the direction on the decision page
540
- (serve-question.mjs, text-only card); the structured question tool remains
541
- the no-browser fallback.
542
- ${authorityInstruction}
543
- A user- or brief-pinned decision beats the roll, always.
544
- ${scope === 'direction'
545
- ? `ASSIGNED INDEX (restated for truncated readers): ${buildIndex}. Build candidate
546
- ${buildIndex} of your own grounded list; seed key ${key}.`
547
- : `DEALT INDICES (restated for truncated readers): ${dealtIndices.join(', ')}; index
548
- ${buildIndex} leads. Present all three dealt structures; seed key ${key}.`}
549
- `;
550
- }
551
-
552
- // Field order is the migration: `compositions` is current, `stagings` is what
553
- // the API emitted while these were called stagings, and `staging` is the
554
- // single-pick shape from before it dealt three. Older installs keep working.
555
- // Compositions are pulled from the deal until the expanded catalog is
556
- // ready for prime time: the current pool crowds the decision more than it
557
- // widens it. IMPECCABLE_COMPOSITIONS=1 re-enables rendering for catalog
558
- // development; the draw machinery, axes, and grain report stay intact.
559
- const compositionsEnabled = process.env.IMPECCABLE_COMPOSITIONS === '1';
560
- const compositions = !compositionsEnabled ? []
561
- : Array.isArray(data.compositions)
562
- ? data.compositions
563
- : Array.isArray(data.stagings)
564
- ? data.stagings
565
- : data.staging ? [data.staging] : [];
566
- // The grain report. A top-up keeps the deal at three, which is right, but it
567
- // must not read as three on-target inputs: a flow request answered entirely by
568
- // view-grain compositions means the model has to derive the flow's own
569
- // structure and borrow only their sequence law. Silence here would reproduce
570
- // the exact failure this axis exists to fix.
571
- const match = data.compositionMatch ?? null;
572
- const grainNote = (() => {
573
- if (!match?.grain) return '';
574
- if (match.grainAvailable === 0) {
575
- return `\nNONE of these sit at the requested ${match.grain} grain, because the catalog holds no ${match.grain}-grain composition yet. Derive that structure yourself and borrow only their sequence and attention laws.`;
576
- }
577
- if (match.atGrain === 0) {
578
- return `\nNONE of these sit at the requested ${match.grain} grain, though ${match.grainAvailable} exist; these were topped up from the rest of the register. Treat their structure as borrowed.`;
579
- }
580
- if (match.atGrain < compositions.length) {
581
- return `\n${match.atGrain} of ${compositions.length} sit at the requested ${match.grain} grain; the rest were topped up from the register and their structure is borrowed.`;
582
- }
583
- return '';
584
- })();
585
- const compositionBlock = compositions.length > 0
586
- ? `\n${scope === 'direction' ? 'FIRST-SURFACE COMPOSITION INPUTS (identity-free; test them with shortlisted worlds and keep world plus composition one decision):' : 'COMPOSITION CHALLENGERS (identity-free; dress them in the committed visual identity before judging):'}
587
- ${compositions.map((composition, index) => renderComposition(composition, index)).join('\n')}
588
- Each one asks the same question of this build: what is the cleverest way to
589
- present, organize, or make interactive the problem in front of you? They carry
590
- structure only, never a palette, typeface, or material. Treat them as serious
591
- rivals to your habitual layout, and keep only what makes this product clearer.${grainNote}\n`
592
- : '';
593
- const rerollBlock = reroll > 0
594
- ? `RE-ROLL ROUND ${reroll}${register ? ` (${register.toUpperCase()} REGISTER, user-requested)` : ''}: every candidate presented in earlier rounds, grounded
595
- and challenger alike, is eliminated and may not return reworded.${register ? '' : ` Derive
596
- genuinely new grounded candidates from unexplored angles before judging
597
- these fresh challengers.`}\n`
598
- : '';
599
- // A register swaps the round's presentation, never its deal: the assigned
600
- // index and challenger fetch stay identical so the chain reproduces, and
601
- // only the instructions change.
602
- const saferBlock = `SAFER REGISTER: the user asked for the familiar end of the spectrum, so this
603
- round's dealt hand is spent unseen, stays excluded from future rounds, and
604
- is not printed. The assigned index is suspended this round; the user picks. Present the familiar register: your remaining grounded
605
- candidates from the conventional end, at most three, as full cards with an
606
- honest risk line each, plus the canon executed against two or three named
607
- competitors. This is the one sanctioned lineup of your own ranked
608
- candidates; it exists only by this explicit request. When the user voices a
609
- standing preference for it, record a brand commitment in PRODUCT.md.`;
610
- const bolderBlock = `BOLDER REGISTER: the user asked for foreign forms at full commitment, so no
611
- grounded direction is presented this round and the assigned index is
612
- suspended. The hand is every dealt challenger below, each fused with the
613
- product and presented as a full card; the FIRST dealt challenger leads, an
614
- assignment by deal order, so the dice still choose. Verdicts and donations
615
- apply between the challengers, weighed against the leader. The pick card
616
- sits out; the canon stays, as always.`;
617
- // The one command that follows a resolved choice. It records the choice
618
- // (anonymous telemetry on API-dealt rolls; skipped under DO_NOT_TRACK /
619
- // IMPECCABLE_NO_TELEMETRY) and opens the build's phase machine, whose
620
- // first gate is the comp round on a comp-led build. Every run that skipped
621
- // the comp round did so by treating a separate "telemetry ping" as
622
- // bookkeeping: suppressed with >/dev/null, run after the page was written,
623
- // or never run. So there is no separate ping; the start command is the
624
- // ping, and it is not optional.
625
- const nextCommand = scope === 'direction'
626
- ? `AFTER THE CHOICE, run exactly one command and follow what it prints (do not suppress its output; do not write page code before it):
627
- node ${relative(process.cwd(), here) || '.'}/build-phase.mjs start --direction ${key} --kind <assigned|pick|challenger|canon>${data.source === 'api' ? ' [--chosen <challenger-id>]' : ''}${register ? ` --register ${register}` : ''}
628
- It records the choice${data.source === 'api' ? ' (anonymous: card kind plus catalog id; skipped under DO_NOT_TRACK / IMPECCABLE_NO_TELEMETRY)' : ''} and opens the build phases: on a comp-led build the comp round is the first gate (three comps, one approved) and no page code is written before it closes; on a code-led build it prints the contract step. A build without this state file is a build the finish reviewer treats as having skipped the round.\n`
629
- : (data.source === 'api'
630
- ? `AFTER THE CHOICE, run once: node ${relative(process.cwd(), here) || '.'}/concept-seed.mjs --kind <assigned|pick|challenger|canon> --from ${key} --scope ${scope}${mode ? ` --mode ${mode}` : ''} (records the choice; the locked card's comp is the approved comp, so then: node ${relative(process.cwd(), here) || '.'}/build-phase.mjs start --comp <that comp>).\n`
631
- : `AFTER THE CHOICE: the locked card's comp is the approved comp; run node ${relative(process.cwd(), here) || '.'}/build-phase.mjs start --comp <that comp> and follow what it prints.\n`);
632
- const telemetryBlock = nextCommand;
633
- const assignedBlock = register === null
634
- ? `${scope === 'direction' ? `ASSIGNED INDEX: ${buildIndex}` : `DEALT INDICES: ${dealtIndices.join(', ')} (index ${buildIndex} leads)`}
635
- ${promotedInstruction}
636
- The assignment exists to refuse the model's ranking rut, never to outrank
637
- the user or the brief. Never expose assignment metadata in user-facing labels.`
638
- : register === 'safer' ? saferBlock : bolderBlock;
639
- // A bolder round has no assigned grounded direction, so the generic
640
- // weighing instruction (which measures against the assignment) would
641
- // contradict the register; the bolder variant weighs against the leader.
642
- const bolderChallengerInstruction = `Fuse each challenger before judging it: the challenger supplies the form
643
- and its system grammar, the product supplies every fact, and clarity wins
644
- conflicts. Weigh every fused challenger against the fused LEADER, the first
645
- dealt, on exactly two axes, audience identification and product clarity;
646
- verdicts and donations apply between the challengers, and one that beats
647
- the leader on both axes presents as the hand's strongest alternate.`;
648
- const roundChallengerInstruction = register === 'bolder' ? bolderChallengerInstruction : challengerInstruction;
649
- const challengerSection = register === 'safer'
650
- ? ''
651
- : `CHALLENGERS:
652
- ${data.challengers.map(renderChallenger).join('\n')}
653
- ${compositionBlock}${roundChallengerInstruction}
654
- When you can view images, open the QUALITY BAR board and hero for any
655
- challenger you weigh seriously and for the world you build. They exist as a
656
- craft bar, the finish level and commitment the build is expected to reach,
657
- never as a mockup to copy; your surface serves this product, not that render.
658
- `;
659
- const restated = register === null
660
- ? (scope === 'direction'
661
- ? `ASSIGNED INDEX (restated for truncated readers): ${buildIndex}. Build candidate
662
- ${buildIndex} of your own grounded list; seed key ${key}.`
663
- : `DEALT INDICES (restated for truncated readers): ${dealtIndices.join(', ')}; index
664
- ${buildIndex} leads. Present all three dealt structures; seed key ${key}.`)
665
- : `REGISTER (restated for truncated readers): ${register}, user-requested; the
666
- assigned index is suspended this round; seed key ${key}.`;
667
- return `${scope.toUpperCase()} CONCEPT SEED (key: ${key}; mode: ${mode ?? 'unscoped'}; source: ${data.source}; approved pool: ${data.poolRevision}; ${data.approvedCount}/${data.catalogCount} human-approved; rerun with --scope ${scope}${mode ? ` --mode ${mode}` : ''} --from ${key}${reroll > 0 ? ` --reroll ${reroll}` : ''}${register ? ` --register ${register}` : ''} --candidate-count ${candidateCount} to reproduce this roll against this catalog revision)
668
- ${rerollBlock}${assignedBlock}
669
- ${challengerSection}${authorityInstruction}
670
- ${richnessInstruction}
671
- ${telemetryBlock}A user- or brief-pinned decision beats the roll, always.
672
- ${restated}
673
- `;
674
- }
675
-
676
- /**
677
- * What the model must do next, once a direction (or surface structure) is
678
- * chosen. Read from the same config the boot directive reads:
679
- * `.impeccable/config.local.json` over `.impeccable/config.json`,
680
- * `buildPath` comp|code; with neither, comp-led whenever image generation
681
- * exists (an OpenAI key here; a harness-native image tool is invisible to
682
- * this script, so the text names it too), code-led otherwise.
683
- */
684
- export function nextStepAfterChoice({ key, scope, cwd = process.cwd(), env = process.env } = {}) {
685
- let buildPath = null;
686
- for (const name of ['config.json', 'config.local.json']) {
687
- try {
688
- const raw = JSON.parse(readFileSync(resolve(cwd, '.impeccable', name), 'utf8'));
689
- if (raw?.buildPath === 'comp' || raw?.buildPath === 'code') buildPath = raw.buildPath;
690
- } catch { /* absent */ }
691
- }
692
- const scriptsDir = dirname(fileURLToPath(import.meta.url));
693
- const scripts = relative(cwd, scriptsDir) || '.';
694
- const imageGen = !!env.OPENAI_API_KEY;
695
- const seed = key ? ` --direction ${key}` : '';
696
- if (buildPath === 'code') {
697
- return `NEXT (code-led, from .impeccable config): write the direction contract, then build; no comp round. Load reference/new-work.md section 5 and 6.\n`;
698
- }
699
- const why = buildPath === 'comp' ? 'from .impeccable config' : imageGen ? 'default: image generation is available' : 'default: comp-led unless no image tool exists; if your harness truly has none and there is no OpenAI key, this is code-led and you say so in one line';
700
- if (scope === 'surface') {
701
- return `NEXT (comp-led, ${why}): the locked card's comp is the approved comp. Run: node ${scripts}/build-phase.mjs start --comp <that comp> and follow its NEXT lines. Do not write page code before build-phase.mjs advance has closed the spec, plates, and hero gates.\n`;
702
- }
703
- return `NEXT (comp-led, ${why}): the world is chosen; the composition is not. Run: node ${scripts}/build-phase.mjs start${seed} and follow its NEXT lines: it opens the comps phase (three comps under .impeccable/mocks/, one approved by the user through the decision page or structured question, sidecar "approved": true), then spec, plates, hero, sections, motion, responsive, review. Do not write page code before those gates close. Reference: reference/visualize.md for the comp round.\n`;
704
- }
705
-
706
- export function sameMainModulePath(left, right, platform = process.platform) {
707
- if (platform !== 'win32') return left === right;
708
- const normalizeDriveLetter = (value) => value.replace(/^([a-z]):/i, (_, drive) => `${drive.toUpperCase()}:`);
709
- return normalizeDriveLetter(left) === normalizeDriveLetter(right);
710
- }
711
-
712
- function isMainModule() {
713
- if (!process.argv[1]) return false;
714
- try {
715
- // Node resolves import.meta.url through symlinks but leaves argv[1] as the
716
- // invoked path. Compare real paths so a linked skill still runs its CLI,
717
- // normalizing the drive-letter casing that Windows junctions can change.
718
- return sameMainModulePath(
719
- realpathSync(process.argv[1]),
720
- realpathSync(fileURLToPath(import.meta.url))
721
- );
722
- } catch {
723
- return false;
724
- }
725
- }
726
-
727
- if (isMainModule()) {
728
- const args = process.argv.slice(2);
729
- const fromIdx = args.indexOf('--from');
730
- const scopeIdx = args.indexOf('--scope');
731
- const rerollIdx = args.indexOf('--reroll');
732
- const registerIdx = args.indexOf('--register');
733
- const modeIdx = args.indexOf('--mode');
734
- const grainIdx = args.indexOf('--grain');
735
- const platformIdx = args.indexOf('--platform');
736
- const candidateCountIdx = args.indexOf('--candidate-count');
737
- const chosenIdx = args.indexOf('--chosen');
738
- const kindIdx = args.indexOf('--kind');
739
- try {
740
- if (chosenIdx !== -1 || kindIdx !== -1) {
741
- // Choice ping: always exits 0, telemetry must never fail a design flow.
742
- // --kind alone pings a non-challenger outcome (assigned/pick/canon);
743
- // --chosen alone stays the legacy challenger-win ping.
744
- const sent = await pingChosen({
745
- chosenId: chosenIdx !== -1 ? args[chosenIdx + 1] : undefined,
746
- key: fromIdx !== -1 ? args[fromIdx + 1] : undefined,
747
- scope: scopeIdx !== -1 ? args[scopeIdx + 1] : undefined,
748
- mode: modeIdx !== -1 ? args[modeIdx + 1] : undefined,
749
- kind: kindIdx !== -1 ? args[kindIdx + 1] : undefined,
750
- register: registerIdx !== -1 ? args[registerIdx + 1] : undefined,
751
- });
752
- process.stdout.write(sent ? 'choice recorded\n' : 'choice ping skipped\n');
753
- // The choice is resolved; this is the last script output the model
754
- // reads before it decides what to do next, and every run that skipped
755
- // the comp round did so right here: prose 20 KB into new-work.md lost
756
- // to "direction locked, building now". So the ping prints the next
757
- // mandatory step from the recorded build path, and the phase machine
758
- // takes it from there.
759
- process.stdout.write(nextStepAfterChoice({
760
- key: fromIdx !== -1 ? args[fromIdx + 1] : undefined,
761
- scope: scopeIdx !== -1 ? args[scopeIdx + 1] : undefined,
762
- }));
763
- } else {
764
- // A dealt roll leaves a marker the build phase clears: context.mjs and
765
- // detect.mjs read it and refuse to treat page work as done while a
766
- // direction is chosen but the build never started (COMP_ROUND_OPEN).
767
- try {
768
- const { mkdirSync, writeFileSync: wf } = await import('node:fs');
769
- if (scopeIdx !== -1 && args[scopeIdx + 1] === 'direction') {
770
- mkdirSync(resolve(process.cwd(), '.impeccable', 'build'), { recursive: true });
771
- wf(resolve(process.cwd(), '.impeccable', 'build', 'pending.json'), JSON.stringify({ scope: 'direction', at: new Date().toISOString() }, null, 2));
772
- }
773
- } catch { /* marker is best-effort */ }
774
- // Mechanical init gate: prose alone does not keep a model from dealing
775
- // before init, and fresh repos produced exactly that skip (the model
776
- // rolled directions with no PRODUCT.md, so nothing grounded the fusion).
777
- // The --chosen branch above stays ungated; telemetry never blocks.
778
- const { loadContext } = await import('./context.mjs');
779
- if (!loadContext(process.cwd()).hasProduct) {
780
- process.stdout.write([
781
- 'NO_PRODUCT_MD: the dice stay in the cup until product truth exists.',
782
- 'Complete the init ask round and write PRODUCT.md first (reference/init.md), then re-run this exact command.',
783
- 'Challengers fuse their form with facts from PRODUCT.md; without it every direction is ungrounded.',
784
- ].join(' ') + '\n');
785
- process.exit(1);
786
- }
787
- process.stdout.write(await renderConceptSeed({
788
- scope: scopeIdx !== -1 ? args[scopeIdx + 1] : 'surface',
789
- key: fromIdx !== -1
790
- ? args[fromIdx + 1]
791
- : (process.env.IMPECCABLE_CONCEPT_SEED || crypto.randomBytes(4).toString('hex')),
792
- reroll: rerollIdx !== -1 ? Number(args[rerollIdx + 1]) : 0,
793
- register: registerIdx !== -1 ? args[registerIdx + 1] : null,
794
- mode: modeIdx !== -1 ? args[modeIdx + 1] : null,
795
- grain: grainIdx !== -1 ? args[grainIdx + 1] : null,
796
- platform: platformIdx !== -1 ? args[platformIdx + 1] : null,
797
- candidateCount: candidateCountIdx !== -1 ? Number(args[candidateCountIdx + 1]) : 7,
798
- }));
799
- }
800
- } catch (error) {
801
- process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
802
- process.exitCode = 1;
803
- }
804
- // A raced-out fetch may still hold a socket; exit explicitly so the CLI
805
- // never lingers on a dead network path after output is written. Destroy
806
- // fetch's global undici dispatcher first: process.exit() with a live
807
- // keep-alive socket trips a libuv assertion on Windows and aborts the
808
- // process after a successful roll (nodejs/node#56645).
809
- const dispatcher = globalThis[Symbol.for('undici.globalDispatcher.1')];
810
- if (dispatcher && typeof dispatcher.destroy === 'function') {
811
- try { await dispatcher.destroy(); } catch { /* exit regardless */ }
812
- }
813
- process.exit(process.exitCode ?? 0);
814
- }