@bastani/atomic 0.9.13 → 0.9.14-alpha.2

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 (762) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +3 -3
  3. package/dist/builtin/intercom/package.json +2 -2
  4. package/dist/builtin/mcp/package.json +3 -3
  5. package/dist/builtin/subagents/CHANGELOG.md +14 -0
  6. package/dist/builtin/subagents/README.md +6 -4
  7. package/dist/builtin/subagents/agents/code-simplifier.md +1 -1
  8. package/dist/builtin/subagents/agents/codebase-analyzer.md +1 -1
  9. package/dist/builtin/subagents/agents/codebase-locator.md +1 -1
  10. package/dist/builtin/subagents/agents/codebase-online-researcher.md +1 -1
  11. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +1 -1
  12. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +1 -1
  13. package/dist/builtin/subagents/agents/codebase-research-locator.md +1 -1
  14. package/dist/builtin/subagents/agents/debugger.md +1 -1
  15. package/dist/builtin/subagents/agents/worker.md +1 -1
  16. package/dist/builtin/subagents/package.json +6 -5
  17. package/dist/builtin/subagents/src/agents/agent-discovery.ts +17 -11
  18. package/dist/builtin/subagents/src/agents/agent-loaders.ts +115 -43
  19. package/dist/builtin/subagents/src/agents/agent-management-helpers.ts +10 -8
  20. package/dist/builtin/subagents/src/agents/agent-management.ts +8 -7
  21. package/dist/builtin/subagents/src/agents/agent-overrides.ts +2 -2
  22. package/dist/builtin/subagents/src/agents/agent-scope.ts +1 -1
  23. package/dist/builtin/subagents/src/agents/agent-selection.ts +1 -1
  24. package/dist/builtin/subagents/src/agents/agent-serializer.ts +24 -3
  25. package/dist/builtin/subagents/src/agents/agent-types.ts +3 -1
  26. package/dist/builtin/subagents/src/agents/agents.ts +7 -5
  27. package/dist/builtin/subagents/src/agents/frontmatter.ts +67 -22
  28. package/dist/builtin/subagents/src/agents/identity.ts +1 -1
  29. package/dist/builtin/subagents/src/agents/skills-paths.ts +1 -1
  30. package/dist/builtin/subagents/src/agents/skills.ts +64 -6
  31. package/dist/builtin/subagents/src/extension/config.ts +1 -1
  32. package/dist/builtin/subagents/src/extension/control-notices.ts +2 -2
  33. package/dist/builtin/subagents/src/extension/doctor.ts +15 -5
  34. package/dist/builtin/subagents/src/extension/fanout-child.ts +12 -12
  35. package/dist/builtin/subagents/src/extension/index.ts +23 -23
  36. package/dist/builtin/subagents/src/extension/notification-content.ts +1 -1
  37. package/dist/builtin/subagents/src/extension/schemas.ts +1 -1
  38. package/dist/builtin/subagents/src/extension/startup-maintenance.ts +3 -3
  39. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +3 -3
  40. package/dist/builtin/subagents/src/intercom/result-intercom.ts +1 -1
  41. package/dist/builtin/subagents/src/intercom/supervisor-authorization.ts +1 -1
  42. package/dist/builtin/subagents/src/runs/foreground/completion-notification.ts +2 -2
  43. package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +1 -1
  44. package/dist/builtin/subagents/src/runs/foreground/execution-intercom-detach.ts +3 -3
  45. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +1 -1
  46. package/dist/builtin/subagents/src/runs/foreground/execution-updates.ts +2 -2
  47. package/dist/builtin/subagents/src/runs/foreground/execution-utils.ts +1 -1
  48. package/dist/builtin/subagents/src/runs/foreground/execution.ts +2 -2
  49. package/dist/builtin/subagents/src/runs/foreground/inprocess-run-sync.ts +27 -11
  50. package/dist/builtin/subagents/src/runs/foreground/notify.ts +3 -3
  51. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +11 -11
  52. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +3 -3
  53. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +15 -14
  54. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +19 -19
  55. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-runtime.ts +2 -2
  56. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +14 -13
  57. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +9 -9
  58. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +7 -7
  59. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-worktree.ts +6 -6
  60. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +24 -23
  61. package/dist/builtin/subagents/src/runs/inprocess/control-registry.ts +1 -1
  62. package/dist/builtin/subagents/src/runs/inprocess/control-status.ts +3 -3
  63. package/dist/builtin/subagents/src/runs/inprocess/index.ts +3 -3
  64. package/dist/builtin/subagents/src/runs/inprocess/prompt-behavior.ts +17 -8
  65. package/dist/builtin/subagents/src/runs/inprocess/runner.ts +60 -12
  66. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-api.ts +8 -8
  67. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-control.ts +3 -3
  68. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-core.ts +4 -4
  69. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-projection.ts +4 -4
  70. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-registry.ts +5 -5
  71. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-rendering.ts +3 -3
  72. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-sanitize.ts +3 -3
  73. package/dist/builtin/subagents/src/runs/inprocess.ts +1 -1
  74. package/dist/builtin/subagents/src/runs/shared/long-running-guard.ts +1 -1
  75. package/dist/builtin/subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +1 -1
  76. package/dist/builtin/subagents/src/runs/shared/model-candidate-filter.ts +3 -3
  77. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +2 -2
  78. package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +1 -1
  79. package/dist/builtin/subagents/src/runs/shared/single-output.ts +1 -1
  80. package/dist/builtin/subagents/src/runs/shared/subagent-control.ts +1 -1
  81. package/dist/builtin/subagents/src/shared/artifacts.ts +2 -2
  82. package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +1 -1
  83. package/dist/builtin/subagents/src/shared/fast-mode.ts +1 -1
  84. package/dist/builtin/subagents/src/shared/formatters.ts +2 -2
  85. package/dist/builtin/subagents/src/shared/jsonl-writer.ts +1 -1
  86. package/dist/builtin/subagents/src/shared/model-resolution.ts +1 -1
  87. package/dist/builtin/subagents/src/shared/session-tokens.ts +1 -1
  88. package/dist/builtin/subagents/src/shared/settings.ts +4 -4
  89. package/dist/builtin/subagents/src/shared/status-format.ts +1 -1
  90. package/dist/builtin/subagents/src/shared/types-config.ts +16 -4
  91. package/dist/builtin/subagents/src/shared/types-depth.ts +1 -1
  92. package/dist/builtin/subagents/src/shared/types-nested.ts +1 -1
  93. package/dist/builtin/subagents/src/shared/types-output.ts +1 -1
  94. package/dist/builtin/subagents/src/shared/types-results.ts +1 -1
  95. package/dist/builtin/subagents/src/shared/types-runtime.ts +1 -1
  96. package/dist/builtin/subagents/src/shared/types.ts +6 -6
  97. package/dist/builtin/subagents/src/shared/utils.ts +3 -3
  98. package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +1 -1
  99. package/dist/builtin/subagents/src/slash/slash-bridge.ts +3 -3
  100. package/dist/builtin/subagents/src/slash/slash-commands.ts +6 -6
  101. package/dist/builtin/subagents/src/slash/slash-live-state.ts +3 -3
  102. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -2
  103. package/dist/builtin/subagents/src/tui/render-layout.ts +1 -1
  104. package/dist/builtin/subagents/src/tui/render-progress.ts +2 -2
  105. package/dist/builtin/subagents/src/tui/render-result-compact.ts +7 -7
  106. package/dist/builtin/subagents/src/tui/render-result.ts +10 -10
  107. package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -1
  108. package/dist/builtin/subagents/src/tui/render-status-progress.ts +5 -5
  109. package/dist/builtin/subagents/src/tui/render.ts +4 -4
  110. package/dist/builtin/web-access/package.json +2 -2
  111. package/dist/builtin/workflows/CHANGELOG.md +57 -0
  112. package/dist/builtin/workflows/README.md +39 -8
  113. package/dist/builtin/workflows/builtin/adversarial-verification-runner.ts +16 -5
  114. package/dist/builtin/workflows/builtin/adversarial-verification.ts +4 -0
  115. package/dist/builtin/workflows/builtin/classify-and-act.ts +4 -0
  116. package/dist/builtin/workflows/builtin/fan-out-and-synthesize.ts +4 -0
  117. package/dist/builtin/workflows/builtin/generate-and-filter-runner.ts +12 -4
  118. package/dist/builtin/workflows/builtin/generate-and-filter.ts +4 -0
  119. package/dist/builtin/workflows/builtin/goal-models.ts +8 -10
  120. package/dist/builtin/workflows/builtin/goal.ts +4 -0
  121. package/dist/builtin/workflows/builtin/index.d.ts +0 -4
  122. package/dist/builtin/workflows/builtin/loop-until-done-runner.ts +4 -2
  123. package/dist/builtin/workflows/builtin/loop-until-done.ts +4 -0
  124. package/dist/builtin/workflows/builtin/open-claude-design-live-protocol.ts +305 -0
  125. package/dist/builtin/workflows/builtin/open-claude-design-phases.ts +115 -171
  126. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +9 -25
  127. package/dist/builtin/workflows/builtin/open-claude-design-setup.ts +19 -86
  128. package/dist/builtin/workflows/builtin/open-claude-design-utils.ts +0 -6
  129. package/dist/builtin/workflows/builtin/open-claude-design.d.ts +0 -5
  130. package/dist/builtin/workflows/builtin/open-claude-design.ts +11 -15
  131. package/dist/builtin/workflows/builtin/ralph-models.ts +24 -29
  132. package/dist/builtin/workflows/builtin/ralph.ts +4 -0
  133. package/dist/builtin/workflows/builtin/tournament-runner.ts +6 -3
  134. package/dist/builtin/workflows/builtin/tournament.ts +4 -0
  135. package/dist/builtin/workflows/package.json +2 -2
  136. package/dist/builtin/workflows/skills/impeccable/SKILL.md +3 -3
  137. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_asset_producer.toml +25 -31
  138. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_documenter.toml +1 -0
  139. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_finish_reviewer.toml +16 -10
  140. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_manual_edit_applier.toml +2 -2
  141. package/dist/builtin/workflows/skills/impeccable/reference/android.md +6 -0
  142. package/dist/builtin/workflows/skills/impeccable/reference/animate.md +3 -0
  143. package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +3 -1
  144. package/dist/builtin/workflows/skills/impeccable/reference/craft-floor.md +6 -1
  145. package/dist/builtin/workflows/skills/impeccable/reference/critique.md +18 -2
  146. package/dist/builtin/workflows/skills/impeccable/reference/degraded/asset-producer.md +24 -30
  147. package/dist/builtin/workflows/skills/impeccable/reference/degraded/documenter.md +1 -0
  148. package/dist/builtin/workflows/skills/impeccable/reference/degraded/finish-reviewer.md +16 -10
  149. package/dist/builtin/workflows/skills/impeccable/reference/degraded/manual-edit-applier.md +2 -2
  150. package/dist/builtin/workflows/skills/impeccable/reference/distill.md +1 -1
  151. package/dist/builtin/workflows/skills/impeccable/reference/doctor.md +1 -0
  152. package/dist/builtin/workflows/skills/impeccable/reference/document.md +1 -1
  153. package/dist/builtin/workflows/skills/impeccable/reference/extract.md +1 -1
  154. package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +12 -6
  155. package/dist/builtin/workflows/skills/impeccable/reference/init.md +12 -3
  156. package/dist/builtin/workflows/skills/impeccable/reference/ios.md +6 -0
  157. package/dist/builtin/workflows/skills/impeccable/reference/live-setup.md +102 -0
  158. package/dist/builtin/workflows/skills/impeccable/reference/live.md +113 -521
  159. package/dist/builtin/workflows/skills/impeccable/reference/new-work.md +39 -26
  160. package/dist/builtin/workflows/skills/impeccable/reference/overdrive.md +1 -1
  161. package/dist/builtin/workflows/skills/impeccable/reference/polish.md +3 -3
  162. package/dist/builtin/workflows/skills/impeccable/reference/quieter.md +1 -1
  163. package/dist/builtin/workflows/skills/impeccable/reference/visualize.md +25 -11
  164. package/dist/builtin/workflows/skills/impeccable/scripts/concept-seed.mjs +332 -221
  165. package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +10 -19
  166. package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +91 -38
  167. package/dist/builtin/workflows/skills/impeccable/scripts/critique-storage.mjs +19 -10
  168. package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +56 -6
  169. package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +10 -16
  170. package/dist/builtin/workflows/skills/impeccable/scripts/detector/design-system.mjs +140 -2
  171. package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +1174 -694
  172. package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns.mjs +1 -0
  173. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs +5 -1
  174. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +431 -45
  175. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +10 -1
  176. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs +47 -6
  177. package/dist/builtin/workflows/skills/impeccable/scripts/detector/node/file-system.mjs +23 -22
  178. package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +0 -10
  179. package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +384 -384
  180. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/color.mjs +466 -2
  181. package/dist/builtin/workflows/skills/impeccable/scripts/doctor.mjs +2 -0
  182. package/dist/builtin/workflows/skills/impeccable/scripts/embed-prompt.mjs +270 -0
  183. package/dist/builtin/workflows/skills/impeccable/scripts/generate-image.mjs +51 -6
  184. package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +70 -10
  185. package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +336 -90
  186. package/dist/builtin/workflows/skills/impeccable/scripts/lib/composition-catalog.mjs +38 -3
  187. package/dist/builtin/workflows/skills/impeccable/scripts/lib/concept-catalog.mjs +77 -11
  188. package/dist/builtin/workflows/skills/impeccable/scripts/lib/design-parser.mjs +102 -19
  189. package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-config.mjs +44 -59
  190. package/dist/builtin/workflows/skills/impeccable/scripts/lib/is-generated.mjs +3 -0
  191. package/dist/builtin/workflows/skills/impeccable/scripts/lib/open-system-browser.mjs +57 -0
  192. package/dist/builtin/workflows/skills/impeccable/scripts/lib/roll-selection.mjs +369 -0
  193. package/dist/builtin/workflows/skills/impeccable/scripts/lib/staleness-deep.mjs +31 -3
  194. package/dist/builtin/workflows/skills/impeccable/scripts/lib/staleness.mjs +73 -2
  195. package/dist/builtin/workflows/skills/impeccable/scripts/live/accept-css.mjs +617 -0
  196. package/dist/builtin/workflows/skills/impeccable/scripts/live/accept-verify.mjs +71 -0
  197. package/dist/builtin/workflows/skills/impeccable/scripts/live/browser-script-parts.mjs +29 -2
  198. package/dist/builtin/workflows/skills/impeccable/scripts/live/event-validation.mjs +54 -7
  199. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/astro.mjs +47 -0
  200. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/detect-utils.mjs +157 -0
  201. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/index.mjs +143 -0
  202. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/journal.mjs +205 -0
  203. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/nextjs.mjs +49 -0
  204. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/nuxt.mjs +170 -0
  205. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/script-src.mjs +26 -0
  206. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/static-html.mjs +26 -0
  207. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/sveltekit.mjs +71 -0
  208. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/tag-strategy.mjs +247 -0
  209. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/tanstack-start.mjs +70 -0
  210. package/dist/builtin/workflows/skills/impeccable/scripts/live/frameworks/vite-generic.mjs +42 -0
  211. package/dist/builtin/workflows/skills/impeccable/scripts/live/instructions.mjs +169 -0
  212. package/dist/builtin/workflows/skills/impeccable/scripts/live/roots.mjs +670 -0
  213. package/dist/builtin/workflows/skills/impeccable/scripts/live/session-store.mjs +232 -35
  214. package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-ast.mjs +969 -0
  215. package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-component.mjs +621 -74
  216. package/dist/builtin/workflows/skills/impeccable/scripts/live/sveltekit-adapter.mjs +66 -28
  217. package/dist/builtin/workflows/skills/impeccable/scripts/live/tanstack-adapter.mjs +12 -12
  218. package/dist/builtin/workflows/skills/impeccable/scripts/live/ui-surfaces.mjs +75 -0
  219. package/dist/builtin/workflows/skills/impeccable/scripts/live/vocabulary.mjs +135 -0
  220. package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +23 -37
  221. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +945 -115
  222. package/dist/builtin/workflows/skills/impeccable/scripts/live-complete.mjs +33 -1
  223. package/dist/builtin/workflows/skills/impeccable/scripts/live-copy-edit-agent.mjs +132 -15
  224. package/dist/builtin/workflows/skills/impeccable/scripts/live-inject.mjs +173 -425
  225. package/dist/builtin/workflows/skills/impeccable/scripts/live-insert.mjs +2 -0
  226. package/dist/builtin/workflows/skills/impeccable/scripts/live-poll.mjs +16 -3
  227. package/dist/builtin/workflows/skills/impeccable/scripts/live-resume.mjs +39 -10
  228. package/dist/builtin/workflows/skills/impeccable/scripts/live-server.mjs +194 -27
  229. package/dist/builtin/workflows/skills/impeccable/scripts/live-status.mjs +10 -4
  230. package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +50 -31
  231. package/dist/builtin/workflows/skills/impeccable/scripts/live.mjs +91 -28
  232. package/dist/builtin/workflows/skills/impeccable/scripts/pin.mjs +8 -5
  233. package/dist/builtin/workflows/skills/impeccable/scripts/serve-question.mjs +759 -109
  234. package/dist/builtin/workflows/src/authoring/workflow.ts +9 -0
  235. package/dist/builtin/workflows/src/authoring.d.ts +3 -0
  236. package/dist/builtin/workflows/src/durable/completed-catalog.ts +23 -2
  237. package/dist/builtin/workflows/src/durable/dbos-backend.ts +30 -17
  238. package/dist/builtin/workflows/src/durable/dbos-envelope.ts +14 -0
  239. package/dist/builtin/workflows/src/durable/dbos-lifecycle.ts +60 -57
  240. package/dist/builtin/workflows/src/durable/dbos-process-owner.ts +87 -0
  241. package/dist/builtin/workflows/src/durable/dbos-registration-diagnostics.ts +113 -0
  242. package/dist/builtin/workflows/src/durable/factory.ts +11 -8
  243. package/dist/builtin/workflows/src/durable/tool-failure-checkpoint.ts +5 -0
  244. package/dist/builtin/workflows/src/durable/tool-primitive.ts +186 -20
  245. package/dist/builtin/workflows/src/durable/types.ts +4 -0
  246. package/dist/builtin/workflows/src/durable/workflow-heartbeat-anchor.ts +153 -0
  247. package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +28 -0
  248. package/dist/builtin/workflows/src/engine/run-tool-control-registry.ts +9 -1
  249. package/dist/builtin/workflows/src/engine/run.ts +1 -0
  250. package/dist/builtin/workflows/src/extension/adopt-session-run-state.ts +20 -0
  251. package/dist/builtin/workflows/src/extension/background-ui-adapter.ts +9 -30
  252. package/dist/builtin/workflows/src/extension/extension-factory.ts +3 -0
  253. package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +28 -10
  254. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +138 -0
  255. package/dist/builtin/workflows/src/extension/index.bundle.mjs +3365 -1341
  256. package/dist/builtin/workflows/src/extension/workflow-heartbeat-delivery.ts +197 -0
  257. package/dist/builtin/workflows/src/extension/workflow-heartbeat-notice.ts +115 -0
  258. package/dist/builtin/workflows/src/extension/workflow-heartbeat-scheduler.ts +962 -0
  259. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +4 -1
  260. package/dist/builtin/workflows/src/extension/workflow-schema.ts +29 -5
  261. package/dist/builtin/workflows/src/extension/workflow-tool-send.ts +32 -1
  262. package/dist/builtin/workflows/src/runs/background/cancellation-registry.ts +10 -1
  263. package/dist/builtin/workflows/src/runs/background/job-tracker.ts +10 -1
  264. package/dist/builtin/workflows/src/runs/foreground/executor-prompt-nodes.ts +16 -11
  265. package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +31 -1
  266. package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +41 -10
  267. package/dist/builtin/workflows/src/runs/foreground/stage-runner-messages.ts +48 -0
  268. package/dist/builtin/workflows/src/runs/foreground/stage-runner-output.ts +4 -1
  269. package/dist/builtin/workflows/src/runs/foreground/stage-runner-structured-output.ts +45 -12
  270. package/dist/builtin/workflows/src/sdk-surface.ts +9 -0
  271. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +10 -0
  272. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +10 -0
  273. package/dist/builtin/workflows/src/shared/graph-store-snapshot.ts +14 -2
  274. package/dist/builtin/workflows/src/shared/persistence-restore.ts +12 -0
  275. package/dist/builtin/workflows/src/shared/prompt-answer.ts +130 -0
  276. package/dist/builtin/workflows/src/shared/session-scoped-singleton.ts +98 -0
  277. package/dist/builtin/workflows/src/shared/stage-ui-broker.ts +9 -1
  278. package/dist/builtin/workflows/src/shared/store-factory.ts +9 -1
  279. package/dist/builtin/workflows/src/shared/store-public-types.ts +2 -1
  280. package/dist/builtin/workflows/src/shared/store-tool-node-methods.ts +7 -0
  281. package/dist/builtin/workflows/src/shared/store-types.ts +18 -1
  282. package/dist/builtin/workflows/src/shared/tool-payload-bounds.ts +576 -0
  283. package/dist/builtin/workflows/src/shared/workflow-authoring-types.d.ts +1 -0
  284. package/dist/builtin/workflows/src/shared/workflow-authoring-types.ts +1 -0
  285. package/dist/builtin/workflows/src/shared/workflow-heartbeat-contract.d.ts +21 -0
  286. package/dist/builtin/workflows/src/shared/workflow-heartbeat-contract.ts +25 -0
  287. package/dist/builtin/workflows/src/tui/graph-theme.ts +8 -1
  288. package/dist/builtin/workflows/src/tui/graph-view-constants.ts +11 -0
  289. package/dist/builtin/workflows/src/tui/graph-view-input.ts +100 -5
  290. package/dist/builtin/workflows/src/tui/graph-view-layout.ts +42 -11
  291. package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +55 -6
  292. package/dist/builtin/workflows/src/tui/graph-view-render.ts +71 -6
  293. package/dist/builtin/workflows/src/tui/graph-view-state.ts +43 -0
  294. package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +2 -0
  295. package/dist/builtin/workflows/src/tui/node-card.ts +5 -1
  296. package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +11 -2
  297. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +36 -10
  298. package/dist/builtin/workflows/src/tui/switcher.ts +11 -4
  299. package/dist/builtin/workflows/src/tui/tool-detail.ts +348 -0
  300. package/dist/builtin/workflows/src/tui/workflow-status.ts +5 -2
  301. package/dist/cli/args.d.ts +1 -0
  302. package/dist/cli/args.d.ts.map +1 -1
  303. package/dist/cli/args.js +11 -0
  304. package/dist/cli/args.js.map +1 -1
  305. package/dist/cli/auth-check.d.ts +1 -1
  306. package/dist/cli/auth-check.js.map +1 -1
  307. package/dist/cli/credential-print.d.ts +1 -1
  308. package/dist/cli/credential-print.js.map +1 -1
  309. package/dist/cli/list-models.d.ts +1 -1
  310. package/dist/cli/list-models.js.map +1 -1
  311. package/dist/cli/startup-ui.d.ts +9 -0
  312. package/dist/cli/startup-ui.d.ts.map +1 -1
  313. package/dist/cli/startup-ui.js +7 -1
  314. package/dist/cli/startup-ui.js.map +1 -1
  315. package/dist/core/agent-session-custom-message-commit.js +2 -2
  316. package/dist/core/agent-session-custom-message-commit.js.map +1 -1
  317. package/dist/core/agent-session-export.d.ts +6 -1
  318. package/dist/core/agent-session-export.d.ts.map +1 -1
  319. package/dist/core/agent-session-export.js +6 -3
  320. package/dist/core/agent-session-export.js.map +1 -1
  321. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  322. package/dist/core/agent-session-extension-bindings.js +6 -4
  323. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  324. package/dist/core/agent-session-methods.d.ts +5 -2
  325. package/dist/core/agent-session-methods.d.ts.map +1 -1
  326. package/dist/core/agent-session-methods.js.map +1 -1
  327. package/dist/core/agent-session-prompt.d.ts +12 -1
  328. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  329. package/dist/core/agent-session-prompt.js +31 -10
  330. package/dist/core/agent-session-prompt.js.map +1 -1
  331. package/dist/core/agent-session-runtime-auth.js.map +1 -1
  332. package/dist/core/agent-session-services.d.ts +1 -1
  333. package/dist/core/agent-session-services.js.map +1 -1
  334. package/dist/core/agent-session-skill-block.d.ts +1 -0
  335. package/dist/core/agent-session-skill-block.d.ts.map +1 -1
  336. package/dist/core/agent-session-skill-block.js +18 -2
  337. package/dist/core/agent-session-skill-block.js.map +1 -1
  338. package/dist/core/agent-session-state.d.ts.map +1 -1
  339. package/dist/core/agent-session-state.js +2 -1
  340. package/dist/core/agent-session-state.js.map +1 -1
  341. package/dist/core/agent-session-types.d.ts +2 -1
  342. package/dist/core/agent-session-types.d.ts.map +1 -1
  343. package/dist/core/agent-session-types.js.map +1 -1
  344. package/dist/core/agent-session.d.ts +1 -1
  345. package/dist/core/agent-session.js.map +1 -1
  346. package/dist/core/atomic-guide-command.js +2 -2
  347. package/dist/core/atomic-guide-command.js.map +1 -1
  348. package/dist/core/builtin-packages.d.ts.map +1 -1
  349. package/dist/core/builtin-packages.js +0 -6
  350. package/dist/core/builtin-packages.js.map +1 -1
  351. package/dist/core/cloudflare-gateway-binding.d.ts +11 -0
  352. package/dist/core/cloudflare-gateway-binding.d.ts.map +1 -0
  353. package/dist/core/cloudflare-gateway-binding.js +11 -0
  354. package/dist/core/cloudflare-gateway-binding.js.map +1 -0
  355. package/dist/core/codex-fast-mode-transport.d.ts +12 -0
  356. package/dist/core/codex-fast-mode-transport.d.ts.map +1 -0
  357. package/dist/core/codex-fast-mode-transport.js +130 -0
  358. package/dist/core/codex-fast-mode-transport.js.map +1 -0
  359. package/dist/core/codex-fast-mode.d.ts +20 -6
  360. package/dist/core/codex-fast-mode.d.ts.map +1 -1
  361. package/dist/core/codex-fast-mode.js +111 -3
  362. package/dist/core/codex-fast-mode.js.map +1 -1
  363. package/dist/core/diagnostics.d.ts +4 -0
  364. package/dist/core/diagnostics.d.ts.map +1 -1
  365. package/dist/core/diagnostics.js.map +1 -1
  366. package/dist/core/event-bus.d.ts +12 -0
  367. package/dist/core/event-bus.d.ts.map +1 -1
  368. package/dist/core/event-bus.js +22 -0
  369. package/dist/core/event-bus.js.map +1 -1
  370. package/dist/core/experimental.d.ts +25 -0
  371. package/dist/core/experimental.d.ts.map +1 -1
  372. package/dist/core/experimental.js +24 -0
  373. package/dist/core/experimental.js.map +1 -1
  374. package/dist/core/export-html/template-js/tree-filter-render.js +4 -3
  375. package/dist/core/export-html/template.js +4 -3
  376. package/dist/core/extension-session-state.d.ts +28 -0
  377. package/dist/core/extension-session-state.d.ts.map +1 -0
  378. package/dist/core/extension-session-state.js +55 -0
  379. package/dist/core/extension-session-state.js.map +1 -0
  380. package/dist/core/extensions/api-types.d.ts +6 -0
  381. package/dist/core/extensions/api-types.d.ts.map +1 -1
  382. package/dist/core/extensions/api-types.js.map +1 -1
  383. package/dist/core/extensions/context-types.d.ts +4 -0
  384. package/dist/core/extensions/context-types.d.ts.map +1 -1
  385. package/dist/core/extensions/context-types.js.map +1 -1
  386. package/dist/core/extensions/index.d.ts +1 -0
  387. package/dist/core/extensions/index.d.ts.map +1 -1
  388. package/dist/core/extensions/index.js +1 -0
  389. package/dist/core/extensions/index.js.map +1 -1
  390. package/dist/core/extensions/loader-api.d.ts +1 -1
  391. package/dist/core/extensions/loader-api.d.ts.map +1 -1
  392. package/dist/core/extensions/loader-api.js +16 -10
  393. package/dist/core/extensions/loader-api.js.map +1 -1
  394. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  395. package/dist/core/extensions/loader-virtual-modules.js +12 -1
  396. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  397. package/dist/core/extensions/runner-context.d.ts +2 -0
  398. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  399. package/dist/core/extensions/runner-context.js +8 -0
  400. package/dist/core/extensions/runner-context.js.map +1 -1
  401. package/dist/core/extensions/runner.d.ts +1 -0
  402. package/dist/core/extensions/runner.d.ts.map +1 -1
  403. package/dist/core/extensions/runner.js +3 -0
  404. package/dist/core/extensions/runner.js.map +1 -1
  405. package/dist/core/extensions/runtime-types.d.ts +3 -0
  406. package/dist/core/extensions/runtime-types.d.ts.map +1 -1
  407. package/dist/core/extensions/runtime-types.js.map +1 -1
  408. package/dist/core/extensions/ui-types.d.ts +26 -0
  409. package/dist/core/extensions/ui-types.d.ts.map +1 -1
  410. package/dist/core/extensions/ui-types.js +17 -1
  411. package/dist/core/extensions/ui-types.js.map +1 -1
  412. package/dist/core/http-dispatcher.d.ts.map +1 -1
  413. package/dist/core/http-dispatcher.js +5 -0
  414. package/dist/core/http-dispatcher.js.map +1 -1
  415. package/dist/core/keybindings.d.ts +24 -0
  416. package/dist/core/keybindings.d.ts.map +1 -1
  417. package/dist/core/keybindings.js +6 -0
  418. package/dist/core/keybindings.js.map +1 -1
  419. package/dist/core/model-config.d.ts +5 -0
  420. package/dist/core/model-config.d.ts.map +1 -1
  421. package/dist/core/model-config.js +1 -0
  422. package/dist/core/model-config.js.map +1 -1
  423. package/dist/core/model-registry.d.ts +1 -1
  424. package/dist/core/model-registry.js.map +1 -1
  425. package/dist/core/model-resolver-cli.d.ts +1 -1
  426. package/dist/core/model-resolver-cli.js.map +1 -1
  427. package/dist/core/model-resolver-defaults.js +3 -3
  428. package/dist/core/model-resolver-defaults.js.map +1 -1
  429. package/dist/core/model-resolver-initial.d.ts +1 -1
  430. package/dist/core/model-resolver-initial.js.map +1 -1
  431. package/dist/core/model-resolver-scope.d.ts +1 -1
  432. package/dist/core/model-resolver-scope.js.map +1 -1
  433. package/dist/core/model-runtime.d.ts +54 -0
  434. package/dist/core/model-runtime.d.ts.map +1 -1
  435. package/dist/core/model-runtime.js +96 -13
  436. package/dist/core/model-runtime.js.map +1 -1
  437. package/dist/core/oauth-login.js.map +1 -1
  438. package/dist/core/project-trust.d.ts +10 -0
  439. package/dist/core/project-trust.d.ts.map +1 -1
  440. package/dist/core/project-trust.js +12 -0
  441. package/dist/core/project-trust.js.map +1 -1
  442. package/dist/core/resource-loader-assets.d.ts.map +1 -1
  443. package/dist/core/resource-loader-assets.js +14 -5
  444. package/dist/core/resource-loader-assets.js.map +1 -1
  445. package/dist/core/resource-loader-core.d.ts +3 -0
  446. package/dist/core/resource-loader-core.d.ts.map +1 -1
  447. package/dist/core/resource-loader-core.js +5 -0
  448. package/dist/core/resource-loader-core.js.map +1 -1
  449. package/dist/core/resource-loader-internals.d.ts +2 -0
  450. package/dist/core/resource-loader-internals.d.ts.map +1 -1
  451. package/dist/core/resource-loader-internals.js.map +1 -1
  452. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  453. package/dist/core/resource-loader-reload.js +2 -0
  454. package/dist/core/resource-loader-reload.js.map +1 -1
  455. package/dist/core/resource-loader-types.d.ts +2 -0
  456. package/dist/core/resource-loader-types.d.ts.map +1 -1
  457. package/dist/core/resource-loader-types.js.map +1 -1
  458. package/dist/core/resource-loader.d.ts +2 -0
  459. package/dist/core/resource-loader.d.ts.map +1 -1
  460. package/dist/core/resource-loader.js +1 -0
  461. package/dist/core/resource-loader.js.map +1 -1
  462. package/dist/core/sdk-types.d.ts +7 -6
  463. package/dist/core/sdk-types.d.ts.map +1 -1
  464. package/dist/core/sdk-types.js.map +1 -1
  465. package/dist/core/sdk.d.ts.map +1 -1
  466. package/dist/core/sdk.js +17 -6
  467. package/dist/core/sdk.js.map +1 -1
  468. package/dist/core/session-manager-core.d.ts +7 -1
  469. package/dist/core/session-manager-core.d.ts.map +1 -1
  470. package/dist/core/session-manager-core.js +11 -2
  471. package/dist/core/session-manager-core.js.map +1 -1
  472. package/dist/core/session-manager-entries.d.ts +2 -2
  473. package/dist/core/session-manager-entries.d.ts.map +1 -1
  474. package/dist/core/session-manager-entries.js +6 -4
  475. package/dist/core/session-manager-entries.js.map +1 -1
  476. package/dist/core/session-manager-list.d.ts.map +1 -1
  477. package/dist/core/session-manager-list.js +5 -1
  478. package/dist/core/session-manager-list.js.map +1 -1
  479. package/dist/core/session-manager-types.d.ts +25 -2
  480. package/dist/core/session-manager-types.d.ts.map +1 -1
  481. package/dist/core/session-manager-types.js.map +1 -1
  482. package/dist/core/session-manager.d.ts +1 -1
  483. package/dist/core/session-manager.d.ts.map +1 -1
  484. package/dist/core/session-manager.js.map +1 -1
  485. package/dist/core/settings-manager-basic-accessors.d.ts +1 -0
  486. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  487. package/dist/core/settings-manager-basic-accessors.js +8 -0
  488. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  489. package/dist/core/settings-manager-ui-accessors.d.ts +3 -1
  490. package/dist/core/settings-manager-ui-accessors.d.ts.map +1 -1
  491. package/dist/core/settings-manager-ui-accessors.js +9 -0
  492. package/dist/core/settings-manager-ui-accessors.js.map +1 -1
  493. package/dist/core/settings-manager.d.ts +1 -1
  494. package/dist/core/settings-manager.d.ts.map +1 -1
  495. package/dist/core/settings-manager.js.map +1 -1
  496. package/dist/core/settings-types.d.ts +4 -0
  497. package/dist/core/settings-types.d.ts.map +1 -1
  498. package/dist/core/settings-types.js.map +1 -1
  499. package/dist/core/skill-catalog.d.ts +35 -0
  500. package/dist/core/skill-catalog.d.ts.map +1 -0
  501. package/dist/core/skill-catalog.js +264 -0
  502. package/dist/core/skill-catalog.js.map +1 -0
  503. package/dist/core/skills-async.d.ts.map +1 -1
  504. package/dist/core/skills-async.js +12 -6
  505. package/dist/core/skills-async.js.map +1 -1
  506. package/dist/core/skills.d.ts +2 -0
  507. package/dist/core/skills.d.ts.map +1 -1
  508. package/dist/core/skills.js +8 -5
  509. package/dist/core/skills.js.map +1 -1
  510. package/dist/core/slash-commands.d.ts.map +1 -1
  511. package/dist/core/slash-commands.js +1 -5
  512. package/dist/core/slash-commands.js.map +1 -1
  513. package/dist/core/system-prompt.js +2 -2
  514. package/dist/core/system-prompt.js.map +1 -1
  515. package/dist/core/tools/ask-user-question/ask-user-question.d.ts +25 -2
  516. package/dist/core/tools/ask-user-question/ask-user-question.d.ts.map +1 -1
  517. package/dist/core/tools/ask-user-question/ask-user-question.js +47 -18
  518. package/dist/core/tools/ask-user-question/ask-user-question.js.map +1 -1
  519. package/dist/core/tools/ask-user-question/view/components/multi-select-view.d.ts.map +1 -1
  520. package/dist/core/tools/ask-user-question/view/components/multi-select-view.js +5 -2
  521. package/dist/core/tools/ask-user-question/view/components/multi-select-view.js.map +1 -1
  522. package/dist/core/tools/ask-user-question/view/components/submit-picker.d.ts.map +1 -1
  523. package/dist/core/tools/ask-user-question/view/components/submit-picker.js +3 -1
  524. package/dist/core/tools/ask-user-question/view/components/submit-picker.js.map +1 -1
  525. package/dist/core/tools/ask-user-question/view/components/wrapping-select.d.ts.map +1 -1
  526. package/dist/core/tools/ask-user-question/view/components/wrapping-select.js +8 -1
  527. package/dist/core/tools/ask-user-question/view/components/wrapping-select.js.map +1 -1
  528. package/dist/core/tools/bash.d.ts.map +1 -1
  529. package/dist/core/tools/bash.js +2 -0
  530. package/dist/core/tools/bash.js.map +1 -1
  531. package/dist/core/tools/edit.d.ts.map +1 -1
  532. package/dist/core/tools/edit.js +2 -0
  533. package/dist/core/tools/edit.js.map +1 -1
  534. package/dist/core/tools/find.d.ts.map +1 -1
  535. package/dist/core/tools/find.js +3 -1
  536. package/dist/core/tools/find.js.map +1 -1
  537. package/dist/core/tools/grep.js +1 -1
  538. package/dist/core/tools/grep.js.map +1 -1
  539. package/dist/core/tools/hashline-engine/format.d.ts +2 -0
  540. package/dist/core/tools/hashline-engine/format.d.ts.map +1 -1
  541. package/dist/core/tools/hashline-engine/format.js +4 -2
  542. package/dist/core/tools/hashline-engine/format.js.map +1 -1
  543. package/dist/core/tools/hashline-engine/messages.d.ts +2 -0
  544. package/dist/core/tools/hashline-engine/messages.d.ts.map +1 -1
  545. package/dist/core/tools/hashline-engine/messages.js +4 -2
  546. package/dist/core/tools/hashline-engine/messages.js.map +1 -1
  547. package/dist/core/tools/hashline-engine/parser.d.ts.map +1 -1
  548. package/dist/core/tools/hashline-engine/parser.js +16 -4
  549. package/dist/core/tools/hashline-engine/parser.js.map +1 -1
  550. package/dist/core/tools/hashline-engine/tokenizer.d.ts.map +1 -1
  551. package/dist/core/tools/hashline-engine/tokenizer.js +37 -27
  552. package/dist/core/tools/hashline-engine/tokenizer.js.map +1 -1
  553. package/dist/core/tools/hashline.d.ts.map +1 -1
  554. package/dist/core/tools/hashline.js +8 -2
  555. package/dist/core/tools/hashline.js.map +1 -1
  556. package/dist/core/tools/ls.d.ts.map +1 -1
  557. package/dist/core/tools/ls.js +2 -0
  558. package/dist/core/tools/ls.js.map +1 -1
  559. package/dist/core/tools/read.d.ts.map +1 -1
  560. package/dist/core/tools/read.js +8 -1
  561. package/dist/core/tools/read.js.map +1 -1
  562. package/dist/core/tools/search.d.ts.map +1 -1
  563. package/dist/core/tools/search.js +2 -0
  564. package/dist/core/tools/search.js.map +1 -1
  565. package/dist/core/tools/todos.d.ts +3 -12
  566. package/dist/core/tools/todos.d.ts.map +1 -1
  567. package/dist/core/tools/todos.js +19 -4
  568. package/dist/core/tools/todos.js.map +1 -1
  569. package/dist/core/tools/write.d.ts.map +1 -1
  570. package/dist/core/tools/write.js +2 -0
  571. package/dist/core/tools/write.js.map +1 -1
  572. package/dist/index-extensions.d.ts +1 -1
  573. package/dist/index-extensions.d.ts.map +1 -1
  574. package/dist/index-extensions.js +1 -1
  575. package/dist/index-extensions.js.map +1 -1
  576. package/dist/index.d.ts +8 -5
  577. package/dist/index.d.ts.map +1 -1
  578. package/dist/index.js +6 -2
  579. package/dist/index.js.map +1 -1
  580. package/dist/main-runtime-api-key.d.ts +1 -1
  581. package/dist/main-runtime-api-key.js.map +1 -1
  582. package/dist/main-session-options.d.ts +1 -1
  583. package/dist/main-session-options.js.map +1 -1
  584. package/dist/main.d.ts.map +1 -1
  585. package/dist/main.js +10 -2
  586. package/dist/main.js.map +1 -1
  587. package/dist/modes/interactive/components/chat-session-host-rendering.js +1 -1
  588. package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
  589. package/dist/modes/interactive/components/chat-session-host-state.d.ts +8 -0
  590. package/dist/modes/interactive/components/chat-session-host-state.d.ts.map +1 -1
  591. package/dist/modes/interactive/components/chat-session-host-state.js +8 -0
  592. package/dist/modes/interactive/components/chat-session-host-state.js.map +1 -1
  593. package/dist/modes/interactive/components/chat-session-host.d.ts +26 -0
  594. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  595. package/dist/modes/interactive/components/chat-session-host.js +38 -0
  596. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  597. package/dist/modes/interactive/components/chat-transcript.d.ts +37 -0
  598. package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -1
  599. package/dist/modes/interactive/components/chat-transcript.js +54 -1
  600. package/dist/modes/interactive/components/chat-transcript.js.map +1 -1
  601. package/dist/modes/interactive/components/fast-mode-selector.js +1 -1
  602. package/dist/modes/interactive/components/fast-mode-selector.js.map +1 -1
  603. package/dist/modes/interactive/components/model-selector.d.ts +1 -1
  604. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  605. package/dist/modes/interactive/components/model-selector.js +2 -1
  606. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  607. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
  608. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  609. package/dist/modes/interactive/components/reserved-bottom-overlay.d.ts +95 -0
  610. package/dist/modes/interactive/components/reserved-bottom-overlay.d.ts.map +1 -0
  611. package/dist/modes/interactive/components/reserved-bottom-overlay.js +234 -0
  612. package/dist/modes/interactive/components/reserved-bottom-overlay.js.map +1 -0
  613. package/dist/modes/interactive/components/session-selector-search.d.ts +4 -0
  614. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  615. package/dist/modes/interactive/components/session-selector-search.js +4 -0
  616. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  617. package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
  618. package/dist/modes/interactive/components/settings-selector-handlers.js +3 -0
  619. package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
  620. package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
  621. package/dist/modes/interactive/components/settings-selector-items.js +7 -0
  622. package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
  623. package/dist/modes/interactive/components/settings-selector-types.d.ts +3 -1
  624. package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
  625. package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
  626. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  627. package/dist/modes/interactive/components/tool-execution.js +12 -1
  628. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  629. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  630. package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
  631. package/dist/modes/interactive/interactive-autocomplete.js +5 -4
  632. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  633. package/dist/modes/interactive/interactive-bash-compact.d.ts.map +1 -1
  634. package/dist/modes/interactive/interactive-bash-compact.js +2 -2
  635. package/dist/modes/interactive/interactive-bash-compact.js.map +1 -1
  636. package/dist/modes/interactive/interactive-extension-custom-ui.js +94 -6
  637. package/dist/modes/interactive/interactive-extension-custom-ui.js.map +1 -1
  638. package/dist/modes/interactive/interactive-mode-base.d.ts +41 -3
  639. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  640. package/dist/modes/interactive/interactive-mode-base.js +80 -11
  641. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  642. package/dist/modes/interactive/interactive-mode-surface.d.ts +9 -1
  643. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  644. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  645. package/dist/modes/interactive/interactive-mode-types.d.ts +2 -0
  646. package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
  647. package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
  648. package/dist/modes/interactive/interactive-model-catalog-startup.d.ts +8 -1
  649. package/dist/modes/interactive/interactive-model-catalog-startup.d.ts.map +1 -1
  650. package/dist/modes/interactive/interactive-model-catalog-startup.js +13 -3
  651. package/dist/modes/interactive/interactive-model-catalog-startup.js.map +1 -1
  652. package/dist/modes/interactive/interactive-model-routing.js +3 -4
  653. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  654. package/dist/modes/interactive/interactive-render-chat.js +6 -0
  655. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  656. package/dist/modes/interactive/interactive-resource-disclosure.js +2 -2
  657. package/dist/modes/interactive/interactive-resource-disclosure.js.map +1 -1
  658. package/dist/modes/interactive/interactive-selectors.js +7 -3
  659. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  660. package/dist/modes/interactive/interactive-session-runtime.js +7 -1
  661. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  662. package/dist/modes/interactive/interactive-slash-commands.js +2 -2
  663. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  664. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  665. package/dist/modes/interactive/interactive-startup.js +34 -9
  666. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  667. package/dist/modes/interactive/interactive-tui.d.ts +21 -1
  668. package/dist/modes/interactive/interactive-tui.d.ts.map +1 -1
  669. package/dist/modes/interactive/interactive-tui.js +140 -38
  670. package/dist/modes/interactive/interactive-tui.js.map +1 -1
  671. package/dist/modes/interactive/model-catalog-refresh.d.ts +17 -0
  672. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
  673. package/dist/modes/interactive/model-catalog-refresh.js +84 -0
  674. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
  675. package/dist/modes/interactive/theme/dark.json +2 -0
  676. package/dist/modes/interactive/theme/light.json +2 -0
  677. package/dist/modes/interactive/theme/theme-class.d.ts +12 -3
  678. package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
  679. package/dist/modes/interactive/theme/theme-class.js +6 -1
  680. package/dist/modes/interactive/theme/theme-class.js.map +1 -1
  681. package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
  682. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  683. package/dist/modes/interactive/theme/theme-controller.js +23 -10
  684. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  685. package/dist/modes/interactive/theme/theme-loading.d.ts.map +1 -1
  686. package/dist/modes/interactive/theme/theme-loading.js +1 -0
  687. package/dist/modes/interactive/theme/theme-loading.js.map +1 -1
  688. package/dist/modes/interactive/theme/theme-schema.d.ts +8 -0
  689. package/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  690. package/dist/modes/interactive/theme/theme-schema.js +3 -1
  691. package/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  692. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  693. package/dist/modes/interactive-engine/engine-custom-ui.d.ts +2 -0
  694. package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
  695. package/dist/modes/interactive-engine/engine-custom-ui.js +1 -0
  696. package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
  697. package/dist/modes/interactive-engine/protocol.d.ts +1 -0
  698. package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
  699. package/dist/modes/interactive-engine/protocol.js +1 -0
  700. package/dist/modes/interactive-engine/protocol.js.map +1 -1
  701. package/dist/modes/interactive-engine/remote-component.d.ts +3 -1
  702. package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
  703. package/dist/modes/interactive-engine/remote-component.js +3 -2
  704. package/dist/modes/interactive-engine/remote-component.js.map +1 -1
  705. package/dist/modes/json-event.d.ts +6 -1
  706. package/dist/modes/json-event.d.ts.map +1 -1
  707. package/dist/modes/json-event.js +17 -2
  708. package/dist/modes/json-event.js.map +1 -1
  709. package/dist/modes/rpc/rpc-client.js.map +1 -1
  710. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  711. package/dist/modes/rpc/rpc-command-handler.js +5 -4
  712. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  713. package/dist/modes/rpc/rpc-provider-auth.js.map +1 -1
  714. package/dist/modes/rpc/rpc-responses.js.map +1 -1
  715. package/dist/modes/rpc/rpc-types.d.ts +1 -1
  716. package/dist/modes/rpc/rpc-types.js.map +1 -1
  717. package/dist/package-manager-cli.js.map +1 -1
  718. package/dist/server/create-harness.d.ts.map +1 -1
  719. package/dist/server/create-harness.js +11 -0
  720. package/dist/server/create-harness.js.map +1 -1
  721. package/dist/utils/abort.d.ts +9 -0
  722. package/dist/utils/abort.d.ts.map +1 -0
  723. package/dist/utils/abort.js +19 -0
  724. package/dist/utils/abort.js.map +1 -0
  725. package/dist/utils/tools-manager.d.ts +16 -1
  726. package/dist/utils/tools-manager.d.ts.map +1 -1
  727. package/dist/utils/tools-manager.js +19 -19
  728. package/dist/utils/tools-manager.js.map +1 -1
  729. package/docs/custom-provider.md +9 -8
  730. package/docs/development.md +0 -1
  731. package/docs/docs.json +0 -1
  732. package/docs/environment-variables.md +3 -0
  733. package/docs/extensions.md +100 -2
  734. package/docs/json.md +3 -1
  735. package/docs/keybindings.md +8 -3
  736. package/docs/models/artificial-analysis-index.md +2 -2
  737. package/docs/models/model-selection.md +32 -23
  738. package/docs/models/pareto-efficiency.md +25 -24
  739. package/docs/providers.md +95 -2
  740. package/docs/quickstart.md +4 -2
  741. package/docs/rpc.md +21 -7
  742. package/docs/sdk.md +26 -1
  743. package/docs/session-format.md +5 -2
  744. package/docs/settings.md +34 -3
  745. package/docs/skills.md +16 -1
  746. package/docs/terminal-setup.md +15 -2
  747. package/docs/themes.md +22 -4
  748. package/docs/tools.md +3 -1
  749. package/docs/tui.md +2 -0
  750. package/docs/usage.md +5 -4
  751. package/docs/workflows.md +96 -19
  752. package/npm-shrinkwrap.json +211 -232
  753. package/package.json +8 -8
  754. package/dist/builtin/i-have-adhd/CHANGELOG.md +0 -30
  755. package/dist/builtin/i-have-adhd/LICENSE +0 -21
  756. package/dist/builtin/i-have-adhd/README.md +0 -18
  757. package/dist/builtin/i-have-adhd/index.ts +0 -238
  758. package/dist/builtin/i-have-adhd/package.json +0 -56
  759. package/dist/builtin/i-have-adhd/skills/i-have-adhd/SKILL.md +0 -140
  760. package/dist/builtin/workflows/builtin/open-claude-design-feedback.ts +0 -359
  761. package/dist/builtin/workflows/skills/impeccable/scripts/live/ui-core.mjs +0 -180
  762. package/docs/i-have-adhd.md +0 -36
@@ -29,8 +29,18 @@
29
29
  * win over thin categories, which is the intended shape.
30
30
  * - RE-ROLL (--reroll <n>): round n of the same base key. The script
31
31
  * recomputes what rounds 0..n-1 drew, excludes all of it, and rolls a
32
- * fresh assigned index, challengers, and staging. One base key therefore
32
+ * fresh assigned index, challengers, and compositions. One base key therefore
33
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.
34
44
  * - RATINGS: the reviewer's approval ratings weight the challenger draw
35
45
  * (3-star doubles the odds, 1-star sits out); the approved pool itself
36
46
  * is unchanged.
@@ -38,25 +48,44 @@
38
48
  * Usage:
39
49
  * node scripts/concept-seed.mjs --scope direction --mode persuade
40
50
  * node scripts/concept-seed.mjs --scope surface --mode operate --from <key>
51
+ * node scripts/concept-seed.mjs --scope surface --mode operate --grain flow
41
52
  * node scripts/concept-seed.mjs --scope direction --candidate-count 6
42
53
  * node scripts/concept-seed.mjs --scope direction --mode persuade --from <key> --reroll 1
43
- * node scripts/concept-seed.mjs --chosen <challenger-id> --from <key> --scope direction
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.
44
69
  *
45
70
  * --mode names the requested surface's mode (persuade, operate, read,
46
- * experience) so the appended staging matches its register of work; omitted,
47
- * the staging rolls from the full approved pool.
71
+ * experience) so the appended compositions match its register of work; omitted,
72
+ * they roll from the full approved pool.
48
73
  *
49
74
  * Challenger data resolves in order: a local catalog directory (the private
50
75
  * service repo, evals, and tests set IMPECCABLE_CATALOG_DIR), then the roll
51
76
  * API at impeccable.style, then a degraded assignment-only seed when both are
52
- * unavailable. --chosen sends the anonymous choice ping for API-dealt rolls;
53
- * DO_NOT_TRACK or IMPECCABLE_NO_TELEMETRY disables it.
77
+ * unavailable.
78
+ *
79
+ * Atomic ships no choice ping. Upstream 4.1.1 posts one per resolved attended
80
+ * round; that POST and its DO_NOT_TRACK / IMPECCABLE_NO_TELEMETRY opt-outs are
81
+ * removed here. The only outbound request this script can make is the roll GET
82
+ * below, which carries scope, mode, an eight-hex seed key, and a re-roll
83
+ * counter, and no project files, prompts, code, or conversation context.
54
84
  *
55
85
  * Env vars:
56
86
  * IMPECCABLE_CONCEPT_SEED — same as --from; for reproducible eval runs.
57
87
  * IMPECCABLE_CATALOG_DIR — directory holding the four catalog JSON files.
58
88
  * IMPECCABLE_API_URL — roll API base (default https://impeccable.style/api).
59
- * IMPECCABLE_NO_TELEMETRY — disables the choice ping (DO_NOT_TRACK also honored).
60
89
  */
61
90
 
62
91
  import crypto from 'node:crypto';
@@ -64,12 +93,18 @@ import { dirname, join, resolve } from 'node:path';
64
93
  import { fileURLToPath } from 'node:url';
65
94
  import {
66
95
  approvedPoolRevision,
67
- deterministicRank,
68
96
  readConceptCatalog,
69
97
  validateConceptCatalog,
70
98
  WELL_TIERS,
71
99
  } from './lib/concept-catalog.mjs';
72
100
  import { readCompositionCatalog } from './lib/composition-catalog.mjs';
101
+ import {
102
+ COMPOSITION_GRAINS,
103
+ COMPOSITION_PLATFORMS,
104
+ runSyncSelection,
105
+ selectApprovedChallengers as selectApprovedChallengersCore,
106
+ selectApprovedCompositions as selectApprovedCompositionsCore,
107
+ } from './lib/roll-selection.mjs';
73
108
 
74
109
  const here = dirname(fileURLToPath(import.meta.url));
75
110
 
@@ -123,9 +158,11 @@ function requireLocalConcepts() {
123
158
  return local;
124
159
  }
125
160
 
126
- async function fetchRoll({ scope, key, mode, reroll }) {
161
+ async function fetchRoll({ scope, key, mode, grain, platform, reroll }) {
127
162
  const params = new URLSearchParams({ scope, key, reroll: String(reroll) });
128
163
  if (mode) params.set('mode', mode);
164
+ if (grain) params.set('grain', grain);
165
+ if (platform) params.set('platform', platform);
129
166
  const controller = new AbortController();
130
167
  const timer = setTimeout(() => controller.abort(), apiBudgetMs());
131
168
  try {
@@ -147,29 +184,18 @@ async function fetchRoll({ scope, key, mode, reroll }) {
147
184
  }
148
185
  }
149
186
 
150
- function telemetryDisabled() {
151
- return Boolean(process.env.IMPECCABLE_NO_TELEMETRY || process.env.DO_NOT_TRACK);
152
- }
153
-
154
- // Anonymous choice ping: records only that a dealt world was selected.
155
- // Fire-and-forget; never fails the caller.
156
- export async function pingChosen({ chosenId, key, scope, mode }) {
157
- if (telemetryDisabled() || !chosenId) return false;
158
- const controller = new AbortController();
159
- const timer = setTimeout(() => controller.abort(), apiBudgetMs());
160
- try {
161
- await fetch(`${API_BASE}/chosen`, {
162
- method: 'POST',
163
- headers: { 'Content-Type': 'application/json' },
164
- body: JSON.stringify({ chosenId, key, scope, mode }),
165
- signal: controller.signal,
166
- });
167
- return true;
168
- } catch {
169
- return false;
170
- } finally {
171
- clearTimeout(timer);
172
- }
187
+ // Atomic divergence: upstream 4.1.1 posts an anonymous "choice ping" to
188
+ // /chosen once per resolved attended round, opt-out only through
189
+ // IMPECCABLE_NO_TELEMETRY or DO_NOT_TRACK. Atomic does not ship outbound
190
+ // telemetry that is on by default in a bundled skill, so the ping and its
191
+ // opt-out switches are removed outright rather than defaulted off: a switch
192
+ // users must find is still collection they did not choose.
193
+ //
194
+ // pingChosen is kept as an explicit no-op so an upstream caller that still
195
+ // invokes it degrades to "skipped" instead of throwing, and so the removal
196
+ // stays visible at the call site on the next sync.
197
+ export async function pingChosen() {
198
+ return false;
173
199
  }
174
200
 
175
201
  const CARD_BASE = process.env.IMPECCABLE_CARD_BASE || 'https://impeccable.style/worlds/cards';
@@ -187,151 +213,44 @@ ${system}
187
213
  QUALITY BAR: board ${board} · hero ${hero}`;
188
214
  }
189
215
 
190
- export function renderStaging(composition, index = null) {
216
+ export function renderComposition(composition, index = null) {
191
217
  const grammar = composition.grammar.map(rule => ` - ${rule}`).join('\n');
192
218
  return ` ${index == null ? '' : `${index + 1}. `}${composition.form}
193
219
  SOURCE ID: ${composition.id}
194
220
  SPARK: ${composition.spark}
195
- STAGING GRAMMAR:
221
+ COMPOSITION GRAMMAR:
196
222
  ${grammar}
197
223
  WEB LEVERAGE: ${composition.webLeverage}`;
198
224
  }
199
225
 
200
- // Three approved, identity-free staging inputs are rolled deterministically.
201
- // One input was too weak a counterweight to a model's habitual page skeleton:
202
- // it became a single optional flourish beside six identity challengers rather
203
- // than a real search over composition. Prefer distinct staging families so a
204
- // roll tests materially different hierarchy, sequence, and interaction laws.
205
- // Cross-mode fallback would make the input misleading, so an absent mode still
206
- // returns no staging. Re-rolls exclude every earlier set until the pool runs out.
207
- export function selectApprovedStagings({ scope, key, reroll = 0, mode = null, sourceCompositions = null, count = 3 }) {
208
- const pool = sourceCompositions ?? requireLocalConcepts().compositions;
209
- // Stagings honour the same breadth gate as worlds: a staging too specific to
210
- // serve an arbitrary build stays approved for direct briefs and leaves the
211
- // challenger pool. Falls back to the full approved set rather than returning
212
- // nothing if every approved staging is marked niche.
213
- let approved = pool.filter(composition => composition.status === 'approved');
214
- const broad = approved.filter(composition => composition.review?.breadth !== 'niche');
215
- if (broad.length > 0) approved = broad;
216
- if (approved.length === 0) return [];
217
- if (mode) {
218
- const matching = approved.filter(composition => composition.surface === mode);
219
- if (matching.length === 0) return [];
220
- approved = matching;
221
- }
222
- const prior = new Set();
223
- let picks = [];
224
- for (let round = 0; round <= reroll; round += 1) {
225
- const available = approved.filter(composition => !prior.has(composition.id));
226
- const ranked = deterministicRank(
227
- available.length >= Math.min(count, approved.length) ? available : approved,
228
- round === 0 ? `${scope}:${key}:staging` : `${scope}:${key}:staging:reroll-${round}`
229
- );
230
- const families = new Set();
231
- picks = [];
232
- for (const composition of ranked) {
233
- const family = composition.familyId ?? composition.id;
234
- if (families.has(family)) continue;
235
- picks.push(composition);
236
- families.add(family);
237
- if (picks.length >= count) break;
238
- }
239
- for (const composition of ranked) {
240
- if (picks.length >= count) break;
241
- if (!picks.some(pick => pick.id === composition.id)) picks.push(composition);
242
- }
243
- if (round < reroll) picks.forEach(composition => prior.add(composition.id));
244
- }
245
- return picks;
226
+ // Selection itself lives in lib/roll-selection.mjs so this script and the roll
227
+ // API run one algorithm rather than two that drifted. These wrappers add only
228
+ // what is local to the skill: resolving the catalog when no pool is passed, and
229
+ // driving the generator with Node's synchronous hash, which keeps a local render
230
+ // synchronous for prepared eval sessions and tests.
231
+ function driveSelection(generator) {
232
+ return runSyncSelection(generator, input => crypto.createHash('sha256').update(input).digest('hex'));
233
+ }
234
+
235
+ export function dealCompositions({ scope, key, reroll = 0, mode = null, grain = null, platform = null, sourceCompositions = null, count = 3 }) {
236
+ const compositions = sourceCompositions ?? requireLocalConcepts().compositions;
237
+ return driveSelection(selectApprovedCompositionsCore({ scope, key, reroll, mode, grain, platform, compositions, count }));
238
+ }
239
+
240
+ // Array-returning form, which is what every caller wanted before the match
241
+ // report existed.
242
+ export function selectApprovedCompositions(options) {
243
+ return dealCompositions(options).picks;
246
244
  }
247
245
 
248
246
  // Compatibility for callers that need a single smoke-test sample.
249
- export function selectApprovedStaging(options) {
250
- return selectApprovedStagings({ ...options, count: 1 })[0] ?? null;
247
+ export function selectApprovedComposition(options) {
248
+ return selectApprovedCompositions({ ...options, count: 1 })[0] ?? null;
251
249
  }
252
250
 
253
- export function selectApprovedChallengers({ scope, key, reroll = 0, sourceConcepts = null }) {
251
+ export function selectApprovedChallengers({ scope, key, reroll = 0, mode = null, sourceConcepts = null }) {
254
252
  const source = sourceConcepts ?? requireLocalConcepts().concepts;
255
- const approved = source.filter(concept => concept.status === 'approved');
256
- // Direction chooses a durable identity, so it draws worlds; surface designs
257
- // one page inside a committed identity, so it draws stagings. Duals serve
258
- // both. A tier with no matching-strength approvals falls back to its full
259
- // approved pool rather than starving the roll.
260
- const wanted = scope === 'direction'
261
- ? new Set(['world', 'dual'])
262
- : new Set(['composition', 'dual']);
263
- const approvedByTier = new Map();
264
- for (const concept of approved) {
265
- const tier = approvedByTier.get(concept.wellTier) || [];
266
- tier.push(concept);
267
- approvedByTier.set(concept.wellTier, tier);
268
- }
269
- if (WELL_TIERS.some(tier => !(approvedByTier.get(tier) || []).length)) {
270
- throw new Error('concept-seed: every challenger tier needs at least one approved concept');
271
- }
272
- for (const [tier, pool] of approvedByTier) {
273
- const matching = pool.filter(concept => wanted.has(concept.strength));
274
- if (matching.length > 0) approvedByTier.set(tier, matching);
275
- }
276
- // Two challengers per tier, so every roll carries near-zero-translation
277
- // graphic systems beside instrument languages and atmosphere worlds, with
278
- // the second pick preferring a different family for diversity. Tier order
279
- // in the rendered list is rolled too, to avoid positional bias.
280
- // Two separate axes, and both can exclude. Rating grades quality: a 3-star
281
- // earns a second ticket, a 1-star marginal keep leaves the pool. Breadth says
282
- // whether a world can serve an arbitrary build at all, so a niche world
283
- // leaves the pool however good it is. Breadth was split out of rating because
284
- // the only way to hold a narrow world back used to be calling it marginal,
285
- // which made "excellent but narrow" unrecordable and corrupted the ratings as
286
- // a calibration signal for the next authoring round.
287
- const ticketsFor = pool => pool.flatMap(concept => {
288
- const rating = concept.review?.rating;
289
- // Two independent exclusions: a marginal world is too weak to challenge,
290
- // a niche world too narrow. Either one keeps its approval for direct
291
- // briefs and leaves the pool.
292
- if (rating === 1 || concept.review?.breadth === 'niche') return [];
293
- return rating === 3
294
- ? [{ concept, ticket: 0 }, { concept, ticket: 1 }]
295
- : [{ concept, ticket: 0 }];
296
- });
297
- const pickRound = (round, excluded) => {
298
- const salt = round === 0 ? '' : `:reroll-${round}`;
299
- const tierOrder = deterministicRank(
300
- WELL_TIERS.map(id => ({ id })),
301
- `${scope}:${key}:tiers${salt}`
302
- ).map(item => item.id);
303
- return tierOrder.flatMap((tier, index) => {
304
- let pool = approvedByTier.get(tier).filter(concept => !excluded.has(concept.id));
305
- // A tier exhausted by prior rounds falls back to reuse over starvation.
306
- if (pool.length === 0) pool = approvedByTier.get(tier);
307
- let tickets = ticketsFor(pool);
308
- if (tickets.length === 0) tickets = pool.map(concept => ({ concept, ticket: 0 }));
309
- const ranked = deterministicRank(
310
- tickets,
311
- `${scope}:${key}:challenger-${index}${salt}`,
312
- entry => `${entry.concept.id}#${entry.ticket}`
313
- );
314
- const order = [];
315
- const seen = new Set();
316
- for (const entry of ranked) {
317
- if (seen.has(entry.concept.id)) continue;
318
- seen.add(entry.concept.id);
319
- order.push(entry.concept);
320
- }
321
- const first = order[0];
322
- const second = order.find(concept => concept.familyId !== first.familyId)
323
- || order.find(concept => concept.id !== first.id);
324
- return second ? [first, second] : [first];
325
- });
326
- };
327
- // Round n of a re-roll chain excludes everything rounds 0..n-1 drew, so the
328
- // same base key reproduces the whole chain.
329
- const excluded = new Set();
330
- let picks = pickRound(0, excluded);
331
- for (let round = 1; round <= reroll; round += 1) {
332
- for (const pick of picks) excluded.add(pick.id);
333
- picks = pickRound(round, excluded);
334
- }
253
+ const { approved, picks } = driveSelection(selectApprovedChallengersCore({ scope, key, reroll, mode, concepts: source }));
335
254
  return {
336
255
  approved,
337
256
  picks,
@@ -346,7 +265,10 @@ export function renderConceptSeed({
346
265
  scope = 'surface',
347
266
  key = process.env.IMPECCABLE_CONCEPT_SEED || crypto.randomBytes(4).toString('hex'),
348
267
  reroll = 0,
268
+ register = null,
349
269
  mode = null,
270
+ grain = null,
271
+ platform = null,
350
272
  candidateCount = 7,
351
273
  catalogDir = CATALOG_DIR,
352
274
  _resolvedData = undefined,
@@ -357,9 +279,26 @@ export function renderConceptSeed({
357
279
  if (!Number.isInteger(reroll) || reroll < 0) {
358
280
  throw new Error('concept-seed: --reroll must be a non-negative integer');
359
281
  }
282
+ if (register !== null && register !== 'safer' && register !== 'bolder') {
283
+ throw new Error('concept-seed: --register must be safer or bolder');
284
+ }
285
+ if (register !== null && reroll < 1) {
286
+ throw new Error('concept-seed: --register steers a re-roll round; pass --reroll <n> with it');
287
+ }
288
+ if (register !== null && scope !== 'direction') {
289
+ throw new Error('concept-seed: --register applies to direction rounds only');
290
+ }
360
291
  if (mode !== null && !SEED_MODES.has(mode)) {
361
292
  throw new Error('concept-seed: --mode must be persuade, operate, read, or experience');
362
293
  }
294
+ // Grain needs no mode: how much of the product is in play is independent of
295
+ // which register of work it is.
296
+ if (grain !== null && !COMPOSITION_GRAINS.includes(grain)) {
297
+ throw new Error(`concept-seed: --grain must be one of ${COMPOSITION_GRAINS.join(', ')}`);
298
+ }
299
+ if (platform !== null && !COMPOSITION_PLATFORMS.includes(platform)) {
300
+ throw new Error(`concept-seed: --platform must be one of ${COMPOSITION_PLATFORMS.join(', ')}`);
301
+ }
363
302
  if (!Number.isInteger(candidateCount) || candidateCount < 5 || candidateCount > 7) {
364
303
  throw new Error('concept-seed: --candidate-count must be an integer from 5 to 7');
365
304
  }
@@ -369,6 +308,20 @@ export function renderConceptSeed({
369
308
  };
370
309
  const indexSalt = reroll === 0 ? 'index' : `index:reroll-${reroll}`;
371
310
  const buildIndex = 3 + Math.floor(unit(indexSalt) * (candidateCount - 2)); // 3..candidateCount
311
+ // Surface scope deals a hand of three grounded structures: one card is not
312
+ // a choice, and the full ranked list would hand selection back to the
313
+ // model's taste. The dice pick all three; the primary index leads. The
314
+ // no-lineup rule stays direction-only, where it was written for worlds.
315
+ const dealtIndices = [buildIndex];
316
+ for (let draw = 0; scope === 'surface' && dealtIndices.length < Math.min(3, candidateCount); draw += 1) {
317
+ const idx = 1 + Math.floor(unit(`${indexSalt}:deal-${draw}`) * candidateCount);
318
+ if (!dealtIndices.includes(idx)) dealtIndices.push(idx);
319
+ if (draw > 64) { // hash repeats cannot stall the deal
320
+ for (let fill = 1; dealtIndices.length < Math.min(3, candidateCount); fill += 1) {
321
+ if (!dealtIndices.includes(fill)) dealtIndices.push(fill);
322
+ }
323
+ }
324
+ }
372
325
 
373
326
  // Local catalog first (private repo, evals, tests), then the roll API,
374
327
  // then a degraded assignment-only seed. The assigned index is pure local
@@ -381,6 +334,7 @@ export function renderConceptSeed({
381
334
  scope,
382
335
  key,
383
336
  reroll,
337
+ mode,
384
338
  sourceConcepts: local.concepts,
385
339
  });
386
340
  data = {
@@ -389,16 +343,22 @@ export function renderConceptSeed({
389
343
  approvedCount: approved.length,
390
344
  catalogCount,
391
345
  challengers: picks,
392
- stagings: selectApprovedStagings({ scope, key, reroll, mode, sourceCompositions: local.compositions }),
346
+ ...(() => {
347
+ const dealt = dealCompositions({ scope, key, reroll, mode, grain, platform, sourceCompositions: local.compositions });
348
+ return { compositions: dealt.picks, compositionMatch: dealt.match };
349
+ })(),
393
350
  };
394
351
  } else {
395
352
  // Keep local renders synchronous for prepared eval sessions and tests;
396
353
  // installed skills without a bundled catalog resolve through the API.
397
- return fetchRoll({ scope, key, mode, reroll }).then(roll => renderConceptSeed({
354
+ return fetchRoll({ scope, key, mode, grain, platform, reroll }).then(roll => renderConceptSeed({
398
355
  scope,
399
356
  key,
400
357
  reroll,
358
+ register,
401
359
  mode,
360
+ grain,
361
+ platform,
402
362
  candidateCount,
403
363
  catalogDir,
404
364
  _resolvedData: roll ? {
@@ -407,7 +367,11 @@ export function renderConceptSeed({
407
367
  approvedCount: roll.approvedCount,
408
368
  catalogCount: roll.catalogCount,
409
369
  challengers: roll.challengers,
410
- stagings: Array.isArray(roll.stagings) ? roll.stagings : roll.staging ? [roll.staging] : [],
370
+ compositions: Array.isArray(roll.compositions)
371
+ ? roll.compositions
372
+ : Array.isArray(roll.stagings)
373
+ ? roll.stagings
374
+ : roll.staging ? [roll.staging] : [],
411
375
  } : null,
412
376
  }));
413
377
  }
@@ -423,16 +387,32 @@ export function renderConceptSeed({
423
387
  survive the current task plus navigation, quiet and dense content,
424
388
  interaction and state, and a substantially different future surface. In an
425
389
  attended run, present the assigned direction fully committed and offer
426
- re-roll; never present a ranked lineup to choose from. Re-roll yourself only
390
+ re-roll. You may add ONE card for your top-ranked grounded candidate when
391
+ it is not the assigned direction, kicker IMPECCABLE’S PICK, with an honest risk line
392
+ naming its familiarity; one pick card, never a ranked lineup, and the pick
393
+ never takes the lead position. When the assignment IS your top candidate,
394
+ there is no pick card. Re-roll yourself only
427
395
  on named factual grounds, when the assignment cannot carry the product's
428
396
  truth or task; taste is never grounds.`
429
397
  : `After ordering the task's grounded structural candidates by resonance,
430
- build candidate ${buildIndex} of your own grounded list; the assignment never
431
- points at a challenger. The assignment is the roll, not a suggestion.
432
- In an attended run, present the assigned structure and offer re-roll; never
433
- present a ranked lineup to choose from. Re-roll yourself only when the
434
- assignment fails audience identification or product clarity on named
435
- factual grounds.`;
398
+ deal candidates ${dealtIndices.join(', ')} of your own grounded list to the
399
+ table; index ${buildIndex} leads, and the deal never points at a challenger.
400
+ The deal is the roll, not a suggestion: the dice decide which structures
401
+ reach the user, so the ranking rut stays broken while the user still gets a
402
+ real choice, and the full ranked list stays yours. In an attended run,
403
+ present the three dealt structures as full cards of equal salience, the
404
+ lead carrying kicker THE ROLL, with steer and re-roll, and let the user
405
+ lock one in; the world is already settled, so this choice is composition.
406
+ Visualize every dealt card: with image generation available and a
407
+ comp-led default (.impeccable/config.json buildPath; the page toggle
408
+ handles the exception), declare a comp per card and generate after
409
+ serving, lead first; otherwise author each card's wireframe field (see
410
+ serve-question --schema) and the page draws the schematic. Carry the
411
+ recorded default in the payload as buildPath with toggle: true. Locking a card
412
+ approves its comp: a surface round that put three visualized structures on
413
+ the table replaces the three-option comp round in visualize.md. Re-roll
414
+ yourself only when every dealt structure fails audience identification or
415
+ product clarity on named factual grounds.`;
436
416
 
437
417
  const challengerInstruction = scope === 'direction'
438
418
  ? `Fuse each challenger before judging it: the challenger supplies the form
@@ -440,7 +420,16 @@ export function renderConceptSeed({
440
420
  conflicts. Weigh the fused result against the assigned direction on exactly
441
421
  two axes, audience identification and product clarity. Losing to strong
442
422
  grounded material is a valid outcome; beating a thin or tool-monoculture
443
- list is the point. A fused challenger that wins both axes becomes the build.`
423
+ list is the point. A fused challenger that wins both axes becomes the build.
424
+ Close the weighing with a verdict per challenger, decided before any
425
+ borrowing is considered: wins (beats the assigned direction on both axes),
426
+ competitive (holds one axis), or declined (loses both). A declined
427
+ challenger is not spent: name the one discipline of its system the assigned
428
+ direction lacks, and raise the assigned direction to match before
429
+ presenting it. A donation transfers ambition and system discipline, never
430
+ the challenger's clothes; one world owns the page. Write each raise as its
431
+ own named line on the presented direction, and carry every verdict, kept
432
+ line, and raise into the decision page payload.`
444
433
  : `A challenger wins only when its fused result beats the grounded list on
445
434
  audience identification and product clarity. It may change task topology or
446
435
  interaction, but never the committed visual identity.`;
@@ -465,19 +454,55 @@ Ambitious motion, spatial media, or interaction is welcome when it strengthens
465
454
  the product without weakening semantics, performance, or fallback behavior.`;
466
455
 
467
456
  if (!data) {
468
- return `${scope.toUpperCase()} CONCEPT SEED (key: ${key}; mode: ${mode ?? 'unscoped'}; source: degraded; rerun with --scope ${scope}${mode ? ` --mode ${mode}` : ''} --from ${key}${reroll > 0 ? ` --reroll ${reroll}` : ''} --candidate-count ${candidateCount})
469
- ASSIGNED INDEX: ${buildIndex}
457
+ // A degraded roll can still serve the safer register, which needs no
458
+ // catalog at all: the assignment machinery is suppressed entirely, the
459
+ // same as the non-degraded safer round, because emitting both "the user
460
+ // picks" and a mandatory numbered build order hands the model two
461
+ // contradicting instructions and the mandatory one tends to win. The
462
+ // bolder register is exactly the thing degradation took away, so it
463
+ // falls back to a plain grounded round, disclosed.
464
+ 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})`;
465
+ if (register === 'safer') {
466
+ return `${degradedHeader}
467
+ SAFER REGISTER (user-requested): the assigned index is suspended this
468
+ round; the user picks, and no candidate is mandated. Present the familiar
469
+ register: your remaining grounded candidates from the conventional end, at
470
+ most three, as full cards with an honest risk line each, plus the canon
471
+ executed against two or three named competitors. This is the one sanctioned
472
+ lineup of your own ranked candidates; it exists only by this explicit
473
+ request. When the user voices a standing preference for it, record a brand
474
+ commitment in PRODUCT.md.
475
+ ${authorityInstruction}
476
+ A user- or brief-pinned decision beats the roll, always.
477
+ REGISTER (restated for truncated readers): safer, user-requested; the
478
+ assigned index is suspended this round and the user picks; seed key ${key}.
479
+ `;
480
+ }
481
+ const degradedRegister = register === 'bolder'
482
+ ? `BOLDER REGISTER UNAVAILABLE: bolder deals foreign forms, and this roll ran
483
+ degraded with no catalog and no roll service, so there is nothing bold to
484
+ deal. Tell the user, then run this round as a plain grounded re-roll; the
485
+ assignment below applies.
486
+ `
487
+ : '';
488
+ return `${degradedHeader}
489
+ ${degradedRegister}${scope === 'direction' ? `ASSIGNED INDEX: ${buildIndex}` : `DEALT INDICES: ${dealtIndices.join(', ')} (index ${buildIndex} leads)`}
470
490
  ${promotedInstruction}
471
491
  The assignment exists to refuse the model's ranking rut, never to outrank
472
492
  the user or the brief. Never expose assignment metadata in user-facing labels.
473
493
  No challengers this run: the roll service was unreachable and no local
474
- catalog exists. A sandboxed exec tool with no network access causes exactly
475
- this; before accepting degradation, rerun this command once through the
476
- harness's network-enabled command tool. A sandboxed shell without network egress is the most common
477
- cause: if this harness can rerun the command with network access granted,
478
- do that once before proceeding. Otherwise proceed with the grounded
479
- candidates alone; the assignment
480
- above still applies at full strength. Tell the user plainly that this roll
494
+ catalog exists. A sandboxed shell without network egress is the most common
495
+ cause; before accepting degradation, rerun this command once through the
496
+ harness's network-enabled or escalated command tool. When that rerun needs
497
+ an approval, state exactly what the approver must know: this script's only
498
+ network contact is one GET to https://impeccable.style/api/roll whose query
499
+ carries scope, mode, an eight-hex seed key, and a re-roll counter; no
500
+ project files, prompts, code, or conversation context are transmitted, and
501
+ nothing is written. An approval request naming that URL and payload judges
502
+ the real action; a bare "run with network" invites rejection for contacting
503
+ an unspecified domain. If the rerun is still refused, proceed with the
504
+ grounded candidates alone; the assignment above still applies at full
505
+ strength. Tell the user plainly that this roll
481
506
  ran degraded, with no challengers and no quality-bar boards; do not present
482
507
  the outcome as a full roll. A degraded roll changes the cards, not the
483
508
  channel: when a browser can open, present the direction on the decision page
@@ -485,50 +510,124 @@ channel: when a browser can open, present the direction on the decision page
485
510
  the no-browser fallback.
486
511
  ${authorityInstruction}
487
512
  A user- or brief-pinned decision beats the roll, always.
488
- ASSIGNED INDEX (restated for truncated readers): ${buildIndex}. Build candidate
489
- ${buildIndex} of your own grounded list; seed key ${key}.
513
+ ${scope === 'direction'
514
+ ? `ASSIGNED INDEX (restated for truncated readers): ${buildIndex}. Build candidate
515
+ ${buildIndex} of your own grounded list; seed key ${key}.`
516
+ : `DEALT INDICES (restated for truncated readers): ${dealtIndices.join(', ')}; index
517
+ ${buildIndex} leads. Present all three dealt structures; seed key ${key}.`}
490
518
  `;
491
519
  }
492
520
 
493
- const stagings = Array.isArray(data.stagings)
494
- ? data.stagings
495
- : data.staging ? [data.staging] : [];
496
- const stagingBlock = stagings.length > 0
497
- ? `\n${scope === 'direction' ? 'FIRST-SURFACE STAGING INPUTS (identity-free; test them with shortlisted worlds and keep world plus staging one decision):' : 'STAGING CHALLENGERS (identity-free; dress them in the committed visual identity before judging):'}
498
- ${stagings.map((staging, index) => renderStaging(staging, index)).join('\n')}
499
- Stagings organize attention, sequence, and manipulation; they never bring a
500
- palette, typeface, or material. Use them as serious alternatives to the model's
501
- habitual composition, but keep only structures that strengthen this product.\n`
521
+ // Field order is the migration: `compositions` is current, `stagings` is what
522
+ // the API emitted while these were called stagings, and `staging` is the
523
+ // single-pick shape from before it dealt three. Older installs keep working.
524
+ // Compositions are pulled from the deal until the expanded catalog is
525
+ // ready for prime time: the current pool crowds the decision more than it
526
+ // widens it. IMPECCABLE_COMPOSITIONS=1 re-enables rendering for catalog
527
+ // development; the draw machinery, axes, and grain report stay intact.
528
+ const compositionsEnabled = process.env.IMPECCABLE_COMPOSITIONS === '1';
529
+ const compositions = !compositionsEnabled ? []
530
+ : Array.isArray(data.compositions)
531
+ ? data.compositions
532
+ : Array.isArray(data.stagings)
533
+ ? data.stagings
534
+ : data.staging ? [data.staging] : [];
535
+ // The grain report. A top-up keeps the deal at three, which is right, but it
536
+ // must not read as three on-target inputs: a flow request answered entirely by
537
+ // view-grain compositions means the model has to derive the flow's own
538
+ // structure and borrow only their sequence law. Silence here would reproduce
539
+ // the exact failure this axis exists to fix.
540
+ const match = data.compositionMatch ?? null;
541
+ const grainNote = (() => {
542
+ if (!match?.grain) return '';
543
+ if (match.grainAvailable === 0) {
544
+ 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.`;
545
+ }
546
+ if (match.atGrain === 0) {
547
+ 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.`;
548
+ }
549
+ if (match.atGrain < compositions.length) {
550
+ 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.`;
551
+ }
552
+ return '';
553
+ })();
554
+ const compositionBlock = compositions.length > 0
555
+ ? `\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):'}
556
+ ${compositions.map((composition, index) => renderComposition(composition, index)).join('\n')}
557
+ Each one asks the same question of this build: what is the cleverest way to
558
+ present, organize, or make interactive the problem in front of you? They carry
559
+ structure only, never a palette, typeface, or material. Treat them as serious
560
+ rivals to your habitual layout, and keep only what makes this product clearer.${grainNote}\n`
502
561
  : '';
503
562
  const rerollBlock = reroll > 0
504
- ? `RE-ROLL ROUND ${reroll}: every candidate presented in earlier rounds, grounded
505
- and challenger alike, is eliminated and may not return reworded. Derive
563
+ ? `RE-ROLL ROUND ${reroll}${register ? ` (${register.toUpperCase()} REGISTER, user-requested)` : ''}: every candidate presented in earlier rounds, grounded
564
+ and challenger alike, is eliminated and may not return reworded.${register ? '' : ` Derive
506
565
  genuinely new grounded candidates from unexplored angles before judging
507
- these fresh challengers.\n`
508
- : '';
509
- const telemetryBlock = data.source === 'api'
510
- ? `TELEMETRY: if the resolved direction uses one of these challengers, rerun
511
- this script once with --chosen <challenger-id> --from ${key} --scope ${scope}${mode ? ` --mode ${mode}` : ''}
512
- after resolution. The ping is anonymous (chosen id only) and is skipped
513
- automatically when DO_NOT_TRACK or IMPECCABLE_NO_TELEMETRY is set.\n`
566
+ these fresh challengers.`}\n`
514
567
  : '';
515
- 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}` : ''} --candidate-count ${candidateCount} to reproduce this roll against this catalog revision)
516
- ${rerollBlock}ASSIGNED INDEX: ${buildIndex}
568
+ // A register swaps the round's presentation, never its deal: the assigned
569
+ // index and challenger fetch stay identical so the chain reproduces, and
570
+ // only the instructions change.
571
+ const saferBlock = `SAFER REGISTER: the user asked for the familiar end of the spectrum, so this
572
+ round's dealt hand is spent unseen, stays excluded from future rounds, and
573
+ is not printed. The assigned index is suspended this round; the user picks. Present the familiar register: your remaining grounded
574
+ candidates from the conventional end, at most three, as full cards with an
575
+ honest risk line each, plus the canon executed against two or three named
576
+ competitors. This is the one sanctioned lineup of your own ranked
577
+ candidates; it exists only by this explicit request. When the user voices a
578
+ standing preference for it, record a brand commitment in PRODUCT.md.`;
579
+ const bolderBlock = `BOLDER REGISTER: the user asked for foreign forms at full commitment, so no
580
+ grounded direction is presented this round and the assigned index is
581
+ suspended. The hand is every dealt challenger below, each fused with the
582
+ product and presented as a full card; the FIRST dealt challenger leads, an
583
+ assignment by deal order, so the dice still choose. Verdicts and donations
584
+ apply between the challengers, weighed against the leader. The pick card
585
+ sits out; the canon stays, as always.`;
586
+ // Atomic divergence: upstream emits a TELEMETRY block here instructing the
587
+ // agent to rerun this script after the user chooses, so the choice reaches
588
+ // /chosen. With the ping removed the instruction would ask for a rerun that
589
+ // does nothing, so it is not emitted at all.
590
+ const telemetryBlock = '';
591
+ const assignedBlock = register === null
592
+ ? `${scope === 'direction' ? `ASSIGNED INDEX: ${buildIndex}` : `DEALT INDICES: ${dealtIndices.join(', ')} (index ${buildIndex} leads)`}
517
593
  ${promotedInstruction}
518
594
  The assignment exists to refuse the model's ranking rut, never to outrank
519
- the user or the brief. Never expose assignment metadata in user-facing labels.
520
- CHALLENGERS:
595
+ the user or the brief. Never expose assignment metadata in user-facing labels.`
596
+ : register === 'safer' ? saferBlock : bolderBlock;
597
+ // A bolder round has no assigned grounded direction, so the generic
598
+ // weighing instruction (which measures against the assignment) would
599
+ // contradict the register; the bolder variant weighs against the leader.
600
+ const bolderChallengerInstruction = `Fuse each challenger before judging it: the challenger supplies the form
601
+ and its system grammar, the product supplies every fact, and clarity wins
602
+ conflicts. Weigh every fused challenger against the fused LEADER, the first
603
+ dealt, on exactly two axes, audience identification and product clarity;
604
+ verdicts and donations apply between the challengers, and one that beats
605
+ the leader on both axes presents as the hand's strongest alternate.`;
606
+ const roundChallengerInstruction = register === 'bolder' ? bolderChallengerInstruction : challengerInstruction;
607
+ const challengerSection = register === 'safer'
608
+ ? ''
609
+ : `CHALLENGERS:
521
610
  ${data.challengers.map(renderChallenger).join('\n')}
522
- ${stagingBlock}${challengerInstruction}
611
+ ${compositionBlock}${roundChallengerInstruction}
523
612
  When you can view images, open the QUALITY BAR board and hero for any
524
613
  challenger you weigh seriously and for the world you build. They exist as a
525
614
  craft bar, the finish level and commitment the build is expected to reach,
526
615
  never as a mockup to copy; your surface serves this product, not that render.
527
- ${authorityInstruction}
616
+ `;
617
+ const restated = register === null
618
+ ? (scope === 'direction'
619
+ ? `ASSIGNED INDEX (restated for truncated readers): ${buildIndex}. Build candidate
620
+ ${buildIndex} of your own grounded list; seed key ${key}.`
621
+ : `DEALT INDICES (restated for truncated readers): ${dealtIndices.join(', ')}; index
622
+ ${buildIndex} leads. Present all three dealt structures; seed key ${key}.`)
623
+ : `REGISTER (restated for truncated readers): ${register}, user-requested; the
624
+ assigned index is suspended this round; seed key ${key}.`;
625
+ 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)
626
+ ${rerollBlock}${assignedBlock}
627
+ ${challengerSection}${authorityInstruction}
528
628
  ${richnessInstruction}
529
629
  ${telemetryBlock}A user- or brief-pinned decision beats the roll, always.
530
- ASSIGNED INDEX (restated for truncated readers): ${buildIndex}. Build candidate
531
- ${buildIndex} of your own grounded list; seed key ${key}.
630
+ ${restated}
532
631
  `;
533
632
  }
534
633
 
@@ -537,19 +636,21 @@ if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.ur
537
636
  const fromIdx = args.indexOf('--from');
538
637
  const scopeIdx = args.indexOf('--scope');
539
638
  const rerollIdx = args.indexOf('--reroll');
639
+ const registerIdx = args.indexOf('--register');
540
640
  const modeIdx = args.indexOf('--mode');
641
+ const grainIdx = args.indexOf('--grain');
642
+ const platformIdx = args.indexOf('--platform');
541
643
  const candidateCountIdx = args.indexOf('--candidate-count');
542
644
  const chosenIdx = args.indexOf('--chosen');
645
+ const kindIdx = args.indexOf('--kind');
543
646
  try {
544
- if (chosenIdx !== -1) {
545
- // Choice ping: always exits 0, telemetry must never fail a design flow.
546
- const sent = await pingChosen({
547
- chosenId: args[chosenIdx + 1],
548
- key: fromIdx !== -1 ? args[fromIdx + 1] : undefined,
549
- scope: scopeIdx !== -1 ? args[scopeIdx + 1] : undefined,
550
- mode: modeIdx !== -1 ? args[modeIdx + 1] : undefined,
551
- });
552
- process.stdout.write(sent ? 'choice recorded\n' : 'choice ping skipped\n');
647
+ if (chosenIdx !== -1 || kindIdx !== -1) {
648
+ // Atomic divergence: --chosen / --kind used to POST the choice ping.
649
+ // The flags stay accepted and still exit 0 so an agent following an
650
+ // older instruction, or a cached reference doc, cannot fail a design
651
+ // flow; they simply record nothing now.
652
+ await pingChosen();
653
+ process.stdout.write('choice ping skipped: telemetry is not shipped in Atomic\n');
553
654
  } else {
554
655
  // Mechanical init gate: prose alone does not keep a model from dealing
555
656
  // before init, and fresh repos produced exactly that skip (the model
@@ -570,7 +671,10 @@ if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.ur
570
671
  ? args[fromIdx + 1]
571
672
  : (process.env.IMPECCABLE_CONCEPT_SEED || crypto.randomBytes(4).toString('hex')),
572
673
  reroll: rerollIdx !== -1 ? Number(args[rerollIdx + 1]) : 0,
674
+ register: registerIdx !== -1 ? args[registerIdx + 1] : null,
573
675
  mode: modeIdx !== -1 ? args[modeIdx + 1] : null,
676
+ grain: grainIdx !== -1 ? args[grainIdx + 1] : null,
677
+ platform: platformIdx !== -1 ? args[platformIdx + 1] : null,
574
678
  candidateCount: candidateCountIdx !== -1 ? Number(args[candidateCountIdx + 1]) : 7,
575
679
  }));
576
680
  }
@@ -579,6 +683,13 @@ if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.ur
579
683
  process.exitCode = 1;
580
684
  }
581
685
  // A raced-out fetch may still hold a socket; exit explicitly so the CLI
582
- // never lingers on a dead network path after output is written.
686
+ // never lingers on a dead network path after output is written. Destroy
687
+ // fetch's global undici dispatcher first: process.exit() with a live
688
+ // keep-alive socket trips a libuv assertion on Windows and aborts the
689
+ // process after a successful roll (nodejs/node#56645).
690
+ const dispatcher = globalThis[Symbol.for('undici.globalDispatcher.1')];
691
+ if (dispatcher && typeof dispatcher.destroy === 'function') {
692
+ try { await dispatcher.destroy(); } catch { /* exit regardless */ }
693
+ }
583
694
  process.exit(process.exitCode ?? 0);
584
695
  }