@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
@@ -22,6 +22,9 @@
22
22
  * dedupeAgainstCache(findings, cache, sessionId, filePath)
23
23
  * renderTemplate(findings, filePath, config, opts)
24
24
  * renderCleanAck(filePath, opts) / renderPendingAck(filePath, known, opts)
25
+ * appendDesignSystemNote(text, scanOptions) / appendDesignSystemNoteOnce(text, scanOptions, cache, sessionId, config)
26
+ * designNoteReserve(scanOptions, cache, sessionId)
27
+ * footerModeForSession(cache, sessionId) / commitFooterShown(cache, sessionId, text)
25
28
  * shouldEmitAckForFile(filePath, config?)
26
29
  * writeAuditLog(env, entry)
27
30
  * loadDetector() -> Promise<{ detectText, detectHtml }>
@@ -873,6 +876,9 @@ function extractFindingIgnoreValueRaw(finding, rule = normalizeIgnoreRule(findin
873
876
  const primary = text.match(/Primary font:\s*([^()\n;]+)/i);
874
877
  if (primary) return cleanIgnoreValueDisplay(primary[1]);
875
878
 
879
+ const googleLabel = text.match(/Google Fonts:\s*([^()\n;]+)/i);
880
+ if (googleLabel) return cleanIgnoreValueDisplay(googleLabel[1]);
881
+
876
882
  const family = text.match(/font-family\s*:\s*["']?([^'",;\n]+)/i);
877
883
  if (family) return cleanIgnoreValueDisplay(family[1]);
878
884
 
@@ -960,7 +966,13 @@ export function renderTemplate(findings, filePath, config, opts = {}) {
960
966
  if (!Array.isArray(findings) || findings.length === 0) return '';
961
967
  const limits = config?.limits || DEFAULT_CONFIG.limits;
962
968
  const cap = Math.max(1, limits.maxFindings || DEFAULT_CONFIG.limits.maxFindings);
963
- const maxChars = Math.max(500, limits.maxChars || DEFAULT_CONFIG.limits.maxChars);
969
+ // reserveChars holds back room for a note the caller appends after render
970
+ // (the DESIGN.md staleness note), so the final payload stays inside the
971
+ // configured budget. It comes off after the 500-char floor, so at floor
972
+ // configs the note keeps guaranteed delivery room; the clamp budget can
973
+ // therefore sit below 500, which clampLastLine's footer-preserving
974
+ // fallback handles (Bugbot on PR #508).
975
+ const maxChars = Math.max(500, limits.maxChars || DEFAULT_CONFIG.limits.maxChars) - (opts.reserveChars || 0);
964
976
 
965
977
  const cwd = opts.cwd || process.cwd();
966
978
  const display = relativize(filePath, cwd);
@@ -969,11 +981,12 @@ export function renderTemplate(findings, filePath, config, opts = {}) {
969
981
  const remaining = total - shown.length;
970
982
 
971
983
  const header = `${ENVELOPE_PREFIX} Design hook findings requiring review in ${display} (${total} issue(s)):`;
972
- const lines = shown.map((f) => formatFindingLine(f));
984
+ const seenRules = new Set();
985
+ const lines = shown.map((f) => formatDedupedFindingLine(f, seenRules));
973
986
  const more = remaining > 0
974
987
  ? `... and ${remaining} more (see ${IMPECCABLE_COMMAND} audit).`
975
988
  : null;
976
- const footer = directiveFooter(display);
989
+ const footer = directiveFooter({ mode: opts.footer });
977
990
 
978
991
  const blocks = [header, ...lines];
979
992
  if (more) blocks.push(more);
@@ -997,12 +1010,15 @@ function renderGroupedTemplate(groups, config, opts = {}) {
997
1010
 
998
1011
  const limits = config?.limits || DEFAULT_CONFIG.limits;
999
1012
  const cap = Math.max(1, limits.maxFindings || DEFAULT_CONFIG.limits.maxFindings);
1000
- const maxChars = Math.max(500, limits.maxChars || DEFAULT_CONFIG.limits.maxChars);
1013
+ const maxChars = Math.max(500, limits.maxChars || DEFAULT_CONFIG.limits.maxChars) - (opts.reserveChars || 0);
1001
1014
  const cwd = opts.cwd || process.cwd();
1002
1015
  const total = realGroups.reduce((sum, group) => sum + group.findings.length, 0);
1003
1016
  const header = `${ENVELOPE_PREFIX} Design hook findings requiring review across ${realGroups.length} files (${total} issue(s)):`;
1004
1017
  const lines = [];
1005
1018
  let shownCount = 0;
1019
+ // One seen-set across all groups: a rule already described under one file
1020
+ // is not re-described under the next.
1021
+ const seenRules = new Set();
1006
1022
 
1007
1023
  for (const group of realGroups) {
1008
1024
  const display = relativize(group.filePath, cwd);
@@ -1010,7 +1026,7 @@ function renderGroupedTemplate(groups, config, opts = {}) {
1010
1026
  const remainingCap = Math.max(0, cap - shownCount);
1011
1027
  const shown = group.findings.slice(0, remainingCap);
1012
1028
  for (const finding of shown) {
1013
- lines.push(formatFindingLine(finding));
1029
+ lines.push(formatDedupedFindingLine(finding, seenRules));
1014
1030
  }
1015
1031
  shownCount += shown.length;
1016
1032
  const hidden = group.findings.length - shown.length;
@@ -1019,7 +1035,7 @@ function renderGroupedTemplate(groups, config, opts = {}) {
1019
1035
  }
1020
1036
  }
1021
1037
 
1022
- const footer = directiveFooter('the affected files', { grouped: true });
1038
+ const footer = directiveFooter({ mode: opts.footer });
1023
1039
  let text = [header, ...lines, '', footer].join('\n');
1024
1040
  if (text.length > maxChars) {
1025
1041
  text = clampGroupedToBudget(header, lines, footer, maxChars);
@@ -1027,82 +1043,149 @@ function renderGroupedTemplate(groups, config, opts = {}) {
1027
1043
  return text;
1028
1044
  }
1029
1045
 
1046
+ // The clamp contract, shared by both budget functions: the footer is policy,
1047
+ // not detail, so it survives every clamp. Try the requested footer first;
1048
+ // when it cannot fit even after dropping finding lines, retry with the short
1049
+ // policy rather than sacrifice findings that fit beside it. A result that
1050
+ // dropped every finding line (a grouped render can fit a bare file header)
1051
+ // does not count as a fit: findings are why the emission exists.
1052
+ const isFindingLine = (line) => line.startsWith('- ');
1053
+
1054
+ function footerFallbacks(footer) {
1055
+ const short = directiveFooter({ mode: 'short' });
1056
+ return footer === short ? [footer] : [footer, short];
1057
+ }
1058
+
1030
1059
  function clampGroupedToBudget(header, lines, footer, maxChars) {
1031
- const assemble = (linesArr, omitted) => [
1060
+ const assemble = (linesArr, omitted, footerText) => [
1032
1061
  header,
1033
1062
  ...linesArr,
1034
1063
  ...(omitted ? [`... and more (see ${IMPECCABLE_COMMAND} audit).`] : []),
1035
1064
  '',
1036
- footer,
1065
+ footerText,
1037
1066
  ].join('\n');
1038
1067
 
1039
- let working = lines.slice();
1040
- let omitted = false;
1041
- let assembled = assemble(working, omitted);
1042
- while (assembled.length > maxChars && working.length > 1) {
1043
- working.pop();
1044
- omitted = true;
1045
- assembled = assemble(working, omitted);
1046
- }
1047
- if (assembled.length > maxChars) {
1048
- assembled = `${assembled.slice(0, maxChars - 1)}…`;
1068
+ for (const footerText of footerFallbacks(footer)) {
1069
+ let working = lines.slice();
1070
+ let omitted = false;
1071
+ let assembled = assemble(working, omitted, footerText);
1072
+ while (assembled.length > maxChars && working.length > 1) {
1073
+ working.pop();
1074
+ omitted = true;
1075
+ assembled = assemble(working, omitted, footerText);
1076
+ }
1077
+ if (assembled.length <= maxChars && working.some(isFindingLine)) return assembled;
1049
1078
  }
1050
- return assembled;
1079
+ return clampLastLine((linesArr, footerText) => assemble(linesArr, true, footerText),
1080
+ lines.find(isFindingLine) || lines[0], maxChars);
1051
1081
  }
1052
1082
 
1053
1083
  function clampToBudget(header, lines, more, footer, maxChars) {
1054
- const assemble = (linesArr, moreText) => {
1084
+ const assemble = (linesArr, moreText, footerText) => {
1055
1085
  const blocks = [header, ...linesArr];
1056
1086
  if (moreText) blocks.push(moreText);
1057
1087
  blocks.push('');
1058
- blocks.push(footer);
1088
+ blocks.push(footerText);
1059
1089
  return blocks.join('\n');
1060
1090
  };
1061
1091
 
1062
- let working = lines.slice();
1063
- let moreText = more;
1064
- let assembled = assemble(working, moreText);
1065
- while (assembled.length > maxChars && working.length > 1) {
1066
- working.pop();
1067
- moreText = `... and more (see ${IMPECCABLE_COMMAND} audit).`;
1068
- assembled = assemble(working, moreText);
1069
- }
1070
- if (assembled.length > maxChars) {
1071
- assembled = `${assembled.slice(0, maxChars - 1)}…`;
1072
- }
1073
- return assembled;
1074
- }
1075
-
1076
- function formatFindingLine(f) {
1092
+ let lastMore = more;
1093
+ for (const footerText of footerFallbacks(footer)) {
1094
+ let working = lines.slice();
1095
+ let moreText = more;
1096
+ let assembled = assemble(working, moreText, footerText);
1097
+ while (assembled.length > maxChars && working.length > 1) {
1098
+ working.pop();
1099
+ moreText = `... and more (see ${IMPECCABLE_COMMAND} audit).`;
1100
+ assembled = assemble(working, moreText, footerText);
1101
+ }
1102
+ lastMore = moreText;
1103
+ if (assembled.length <= maxChars) return assembled;
1104
+ }
1105
+ return clampLastLine((linesArr, footerText) => assemble(linesArr, lastMore, footerText),
1106
+ lines.find(isFindingLine) || lines[0], maxChars);
1107
+ }
1108
+
1109
+ // Last resort with one finding line left: the short policy gets the budget
1110
+ // first, the line is clipped to what remains. The pre-fix tail-slice cut
1111
+ // whatever happened to be last, which was always the footer.
1112
+ function clampLastLine(build, line, maxChars) {
1113
+ const footerText = directiveFooter({ mode: 'short' });
1114
+ const bare = build([], footerText);
1115
+ // +1 for the newline the line itself brings when it joins the blocks.
1116
+ const room = maxChars - bare.length - 1;
1117
+ if (room >= 24) {
1118
+ const clipped = line.length > room ? `${line.slice(0, room - 1)}…` : line;
1119
+ return build([clipped], footerText);
1120
+ }
1121
+ // No room for even a clipped finding line: the note reservation can pull
1122
+ // the budget below the 500-char floor, and a deep file path can push the
1123
+ // header past what remains beside the short policy (Bugbot on PR #508).
1124
+ // Drop the line, and if the bare header + policy still overflow, clip the
1125
+ // head. Never tail-slice: the footer sits at the end, so a tail slice is
1126
+ // exactly the footer cut this renderer exists to prevent.
1127
+ if (bare.length <= maxChars) return bare;
1128
+ const head = bare.slice(0, Math.max(0, maxChars - footerText.length - 4));
1129
+ return `${head}…\n\n${footerText}`;
1130
+ }
1131
+
1132
+ // `compact` drops the registry description: within one emission the first
1133
+ // occurrence of a rule carries the full description and repeats keep only the
1134
+ // rule id, name, and their own ignore hint (values differ per line, so the
1135
+ // hint must survive the dedupe).
1136
+ function formatFindingLine(f, opts = {}) {
1077
1137
  const prefix = f.line && f.line > 0 ? `- L${f.line}` : '-';
1078
- const desc = (f.description || '').trim();
1138
+ const desc = opts.compact ? '' : (f.description || '').trim();
1079
1139
  const name = (f.name || '').trim();
1080
1140
  // Description from the registry already ends in punctuation; join with a
1081
1141
  // single space. `name` may have a trailing period already, keep it clean.
1082
1142
  const nameSegment = name ? `${name.replace(/\.+\s*$/, '')}.` : '';
1083
- const ignoreCommand = formatFindingIgnoreCommand(f);
1084
- const ignoreSegment = ignoreCommand
1085
- ? ` If the user explicitly confirms this value is intentional: \`${ignoreCommand}\`.`
1086
- : '';
1143
+ const ignoreHint = formatFindingIgnoreHint(f);
1144
+ const ignoreSegment = ignoreHint ? ` If intentional: \`${ignoreHint}\`.` : '';
1087
1145
  return `${prefix} [${f.antipattern}] ${nameSegment} ${desc}${ignoreSegment}`.replace(/\s+/g, ' ').trim();
1088
1146
  }
1089
1147
 
1090
- function formatFindingIgnoreCommand(finding) {
1148
+ // Dedupe applied in shown-line order, so the first rendered occurrence of a
1149
+ // rule always carries the description. The budget clamps pop lines from the
1150
+ // end, which can never orphan a compact repeat before its described first
1151
+ // occurrence.
1152
+ function formatDedupedFindingLine(finding, seenRules) {
1153
+ const rule = normalizeIgnoreRule(finding?.antipattern);
1154
+ const compact = rule ? seenRules.has(rule) : false;
1155
+ if (rule) seenRules.add(rule);
1156
+ return formatFindingLine(finding, { compact });
1157
+ }
1158
+
1159
+ // The rule/value pair the footer's `hook-admin.mjs ignore-value` command
1160
+ // takes. Deliberately just the args: the executable prefix, the --reason
1161
+ // contract, and the disclosure rule live in the directive footer, stated once
1162
+ // instead of per line.
1163
+ function formatFindingIgnoreHint(finding) {
1091
1164
  if (!finding || typeof finding !== 'object') return '';
1092
1165
  const rule = normalizeIgnoreRule(finding.antipattern);
1093
1166
  if (!rule) return '';
1094
1167
  const normalizedValue = extractFindingIgnoreValue(finding);
1095
1168
  if (!normalizedValue) return '';
1096
- const value = extractFindingIgnoreValueRaw(finding);
1097
- const valueArg = quoteCommandArg(value);
1098
- const reason = quoteCommandArg(`User confirmed ${value} is intentional`);
1099
- return `${IMPECCABLE_COMMAND} hooks ignore-value ${rule} ${valueArg} --shared --reason ${reason}`;
1169
+ const valueArg = quoteCommandArg(extractFindingIgnoreValueRaw(finding));
1170
+ return `ignore-value ${rule} ${valueArg}`;
1100
1171
  }
1101
1172
 
1102
1173
  function quoteCommandArg(value) {
1103
1174
  const text = String(value || '').trim();
1104
1175
  if (/^[A-Za-z0-9._:-]+$/.test(text)) return text;
1105
- return `"${text.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
1176
+ // The suggestion is meant to be run on this same machine, so quote for its
1177
+ // shell. POSIX /bin/sh still expands $(...), backticks, and ${} inside
1178
+ // double quotes, and these values come from scanned file content (a
1179
+ // font-family name) or a file path, so untrusted input must be
1180
+ // single-quoted (issue #476). Windows cmd.exe performs no such command
1181
+ // substitution, but it treats a single quote as a literal character rather
1182
+ // than a grouping delimiter, so a value or path containing spaces has to
1183
+ // stay double-quoted there (Greptile #533). Keep the pre-existing
1184
+ // double-quote escaping on Windows so that path's behavior is unchanged.
1185
+ if (process.platform === 'win32') {
1186
+ return `"${text.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
1187
+ }
1188
+ return `'${text.replace(/'/g, `'\\''`)}'`;
1106
1189
  }
1107
1190
 
1108
1191
  function relativize(filePath, cwd) {
@@ -1297,6 +1380,51 @@ function isInsideProject(filePath, projectCwd) {
1297
1380
  }
1298
1381
  }
1299
1382
 
1383
+ // Resolve a path to its canonical (symlink-free) form. When the path does
1384
+ // not exist yet — the before-edit hook gates proposed Writes — canonicalize
1385
+ // the nearest existing ancestor and re-append the remainder, so a new file
1386
+ // under a symlinked root still compares equal to its canonical project.
1387
+ // Memoized: the hook runs as a fresh process per tool event, so the cache
1388
+ // amounts to once-per-event work — the scan loops re-check the same project
1389
+ // root for every target file. The cap only matters to long-lived importers
1390
+ // like the test runner.
1391
+ const canonicalPathCache = new Map();
1392
+ const CANONICAL_PATH_CACHE_MAX = 1024;
1393
+
1394
+ function canonicalPath(p) {
1395
+ const resolved = path.resolve(p);
1396
+ if (canonicalPathCache.has(resolved)) return canonicalPathCache.get(resolved);
1397
+ let canonical = resolved;
1398
+ let dir = resolved;
1399
+ const tail = [];
1400
+ while (true) {
1401
+ try {
1402
+ canonical = tail.length ? path.join(fs.realpathSync(dir), ...tail) : fs.realpathSync(dir);
1403
+ break;
1404
+ } catch { /* keep climbing */ }
1405
+ const parent = path.dirname(dir);
1406
+ if (parent === dir) break;
1407
+ tail.unshift(path.basename(dir));
1408
+ dir = parent;
1409
+ }
1410
+ if (canonicalPathCache.size >= CANONICAL_PATH_CACHE_MAX) canonicalPathCache.clear();
1411
+ canonicalPathCache.set(resolved, canonical);
1412
+ return canonical;
1413
+ }
1414
+
1415
+ // Containment gate shared by the before-edit hook and both scan passes. A
1416
+ // session routinely touches files that belong to no project or to a
1417
+ // different one — harness scratchpad dirs under the system temp root,
1418
+ // sibling checkouts, one-off throwaway HTML — and findings against those are
1419
+ // judged with THIS project's config and DESIGN.md palette, which is never
1420
+ // right. Skip them (audit reason: outside-project). Paths are canonicalized
1421
+ // first so a symlinked root (macOS /tmp -> /private/tmp) doesn't split the
1422
+ // comparison.
1423
+ export function isScanTargetInsideProject(filePath, projectCwd) {
1424
+ if (!filePath || !projectCwd) return false;
1425
+ return isInsideProject(canonicalPath(filePath), canonicalPath(projectCwd));
1426
+ }
1427
+
1300
1428
  export function parseStaticStyleImports(content, fromFile, projectCwd) {
1301
1429
  if (!content || typeof content !== 'string') return [];
1302
1430
  const dir = path.dirname(fromFile);
@@ -1511,36 +1639,105 @@ export function designSystemOptions(config, detector, projectCwd) {
1511
1639
  }
1512
1640
  }
1513
1641
 
1642
+ const DESIGN_STALE_NOTE = `${ENVELOPE_PREFIX} DESIGN.md is newer than .impeccable/design.json. Run ${IMPECCABLE_COMMAND} document to refresh the design-system sidecar.`;
1643
+
1514
1644
  export function appendDesignSystemNote(text, scanOptions) {
1515
1645
  if (!text || !scanOptions?.designSystem?.mdNewerThanJson) return text;
1516
- return `${text}\n\n${ENVELOPE_PREFIX} DESIGN.md is newer than .impeccable/design.json. Run ${IMPECCABLE_COMMAND} document to refresh the design-system sidecar.`;
1646
+ return `${text}\n\n${DESIGN_STALE_NOTE}`;
1517
1647
  }
1518
1648
 
1649
+ // Session-scoped once-only gate for repeat-prone message parts. Returns true
1650
+ // the first time a flag is consumed in a session and false after, mirroring
1651
+ // the `cleanAcked` mechanic: the mtime skew (and the policy footer) do not
1652
+ // change between edits, so re-stating them on every emission spends context
1653
+ // to say nothing new. Callers must persist the cache for the flag to stick.
1654
+ function consumeSessionNoticeFlag(cache, sessionId, flag) {
1655
+ const session = ensureSession(cache, sessionId);
1656
+ if (session[flag]) return false;
1657
+ session[flag] = true;
1658
+ session.updatedAt = Date.now();
1659
+ return true;
1660
+ }
1661
+
1662
+ // Once-per-session variant of appendDesignSystemNote for the emission paths
1663
+ // that have cache access. The staleness note names standing project state,
1664
+ // not new information, so one mention per session is enough. The note is
1665
+ // appended after the renderer has clamped to the configured budget: render
1666
+ // paths reserve room for it via designNoteReserve, and the size check here
1667
+ // is the safety net for the ack paths, deferring (without consuming the
1668
+ // flag) to a later emission rather than busting maxChars.
1669
+ export function appendDesignSystemNoteOnce(text, scanOptions, cache, sessionId, config) {
1670
+ if (!text || !scanOptions?.designSystem?.mdNewerThanJson) return text;
1671
+ const maxChars = Math.max(500, config?.limits?.maxChars || DEFAULT_CONFIG.limits.maxChars);
1672
+ if (text.length + DESIGN_STALE_NOTE.length + 2 > maxChars) return text;
1673
+ if (!consumeSessionNoticeFlag(cache, sessionId, 'designNoteShown')) return text;
1674
+ return appendDesignSystemNote(text, scanOptions);
1675
+ }
1676
+
1677
+ // Render-time reservation for the note above: how many characters the
1678
+ // renderer must hold back so a pending staleness note still fits inside the
1679
+ // configured budget. Zero once the session has seen the note. Without the
1680
+ // reservation, a session whose every emission fills the budget would defer
1681
+ // the note forever.
1682
+ export function designNoteReserve(scanOptions, cache, sessionId) {
1683
+ if (!scanOptions?.designSystem?.mdNewerThanJson) return 0;
1684
+ if (ensureSession(cache, sessionId).designNoteShown) return 0;
1685
+ return DESIGN_STALE_NOTE.length + 2;
1686
+ }
1687
+
1688
+ // Full directive footer once per session, the short reminder after. Fresh
1689
+ // emissions and denials share the session flag (`footerShown`), so a session
1690
+ // pays the full policy exactly once however it first fires. The mode
1691
+ // is a peek: the clamp can downgrade a requested full footer under a tight
1692
+ // budget, so the flag commits only when the complete full policy actually
1693
+ // reached the output. Matching the whole footer text (not a sentinel) keeps
1694
+ // the flag honest against any truncation that spares the opening words.
1695
+ export function footerModeForSession(cache, sessionId) {
1696
+ return ensureSession(cache, sessionId).footerShown ? 'short' : 'full';
1697
+ }
1698
+
1699
+ export function commitFooterShown(cache, sessionId, text) {
1700
+ if (!text || !text.includes(directiveFooter())) return;
1701
+ const session = ensureSession(cache, sessionId);
1702
+ if (session.footerShown) return;
1703
+ session.footerShown = true;
1704
+ session.updatedAt = Date.now();
1705
+ }
1706
+
1707
+ const HOOK_ADMIN_COMMAND = `node ${quoteCommandArg(path.join(__dirname, 'hook-admin.mjs'))}`;
1708
+
1519
1709
  // The directive footer is the part of the hook output that steers model
1520
- // behavior. Three intentional moves:
1521
- // 1. **Imperative, not advisory.** "Handle these..." beats "Consider
1522
- // revising..." which the model treats as a soft suggestion it can
1523
- // override when the user asked for any kind of throwaway / demo UI.
1524
- // 2. **Explicit judgment clause.** Without it, the model will try to
1525
- // "fix" intentional motion, bad fixtures, anti-pattern examples in
1526
- // docs, or test cases. Naming the judgment inline beats hoping the
1527
- // model infers it from context.
1528
- // 3. **Acknowledgement instruction.** Hook output is injected as
1529
- // developer-role context, not a chat turn, so the user never sees the
1530
- // raw envelope. Asking the model to surface the resolution in its
1531
- // reply is the cheapest way to make the feedback loop visible.
1532
- function directiveFooter(display, opts = {}) {
1533
- // Offer the rule-scoped-to-file form first. `ignore-file` silences every rule
1534
- // for the path forever, which is far more than one noisy rule on a real UI
1535
- // surface justifies, and it was previously the only option named here.
1536
- const target = opts.grouped ? '<path>' : quoteCommandArg(display);
1537
- const fileIgnoreGuidance = `run \`${IMPECCABLE_COMMAND} hooks ignore-value <id> "*" --file ${target}\` to scope just that rule to the file, or \`${IMPECCABLE_COMMAND} hooks ignore-file ${target}\` only when the whole file is out of scope for design review (a fixture, a generated artifact, a deliberate demo)`;
1710
+ // behavior. Intentional moves, in order:
1711
+ // 1. **Imperative, not advisory.** "Triage each finding..." beats
1712
+ // "Consider revising...", which the model treats as a soft suggestion.
1713
+ // 2. **Positive triage branches.** Fix / suppress-and-disclose / ask. The
1714
+ // suppress branch names the calibration examples (demo, fixture,
1715
+ // documented bad design, user-confirmed choice) because the agent now
1716
+ // acts on its own confidence and needs the bar stated.
1717
+ // 3. **Executable ignore path.** The old footer named only the slash
1718
+ // command, which an agent reacting to hook output cannot run; the
1719
+ // hook-admin.mjs invocation is runnable as-is and keeps agents out of
1720
+ // hand-editing config.json.
1721
+ // 4. **Honest provenance.** The --reason is the audit trail; "user
1722
+ // confirmed" appears only when the user actually did.
1723
+ // 5. **Acknowledgement instruction.** Hook output is injected as
1724
+ // developer-role context, so the reply is where the user sees the
1725
+ // resolution, including any ignore the agent persisted.
1726
+ // 6. **Once per session.** The full policy emits on the session's first
1727
+ // fire; later emissions carry the one-line short form (mode 'short').
1728
+ function directiveFooter(opts = {}) {
1729
+ if (opts.mode === 'short') {
1730
+ // No command path here: the session's first emission already gave the
1731
+ // runnable hook-admin.mjs invocation, and restating ~70 chars of absolute
1732
+ // path on every repeat is the duplication this mode exists to cut.
1733
+ return 'Triage per the session policy: fix real problems; persist confident false-positive or sanctioned-exception ignores via `hook-admin.mjs ignore-value` and disclose them in your reply; unsure, ask in one line.';
1734
+ }
1538
1735
  return [
1539
- 'Handle these before finalizing: fix findings that are real design problems, or explicitly classify contextually intentional findings as false positives. Acknowledge what you changed or why you are leaving a finding unchanged.',
1540
- '',
1541
- 'Use context judgment before editing. A finding is not automatically a defect; literal or domain-appropriate motion, intentional demos or fixtures, documentation of bad design, and user-confirmed choices can be valid as-is.',
1542
- '',
1543
- `Do not change intentional design just to satisfy the hook, and do not silence a real finding with an inline ignore comment to skip fixing it. Suppress a finding only after the user explicitly confirms it is intentional. Prefer a config ignore (one reviewable place, the commands below); reach for an inline \`impeccable-disable <rule>\` comment only when the waiver must travel with a file that leaves the repo, such as an exported or standalone document. Prefer the narrowest persisted exception: run the exact \`${IMPECCABLE_COMMAND} hooks ignore-value ... --shared\` command shown next to a value-specific finding. For \`overused-font\`, use \`ignore-value\` for a specific font and use \`${IMPECCABLE_COMMAND} hooks ignore-rule overused-font --all-values\` only when the user asks to ignore overused fonts generally. For a finding whose line shows no exact ignore-value command, such as \`side-tab\`, ${fileIgnoreGuidance}; use \`${IMPECCABLE_COMMAND} hooks ignore-rule <id>\` only when the user asks to suppress the whole non-value-specific rule. Run ${IMPECCABLE_COMMAND} audit for the full pass.`,
1736
+ 'Triage each finding, then state in your reply what you fixed, what you suppressed, and what you left standing:',
1737
+ '- Real design problem: fix it. Keep intentional design as designed.',
1738
+ `- Confident false positive or sanctioned exception (an intentional demo or fixture, documentation of bad design, literal or domain-appropriate motion, a choice the user confirmed): persist the narrowest ignore yourself and disclose it. Run \`${HOOK_ADMIN_COMMAND} ignore-value <rule> "<value>" --reason "<who decided: evidence>"\` with the pair shown on the finding line, or value "*" plus \`--file <path>\` when the line shows none. Write "user confirmed" in a reason only when the user did.`,
1739
+ '- Unsure: leave it as is and ask the user in one line.',
1740
+ `Self-serve ends at ignore-value: \`ignore-file\` and \`ignore-rule\` need the user's explicit approval, and never add an ignore to push a blocked write through. Full suppression ladder: ${IMPECCABLE_COMMAND} hooks.`,
1544
1741
  ].join('\n');
1545
1742
  }
1546
1743
 
@@ -1655,6 +1852,10 @@ export async function runHook({ stdinJson, env = {}, cwd = process.cwd(), now =
1655
1852
  lastSkip = 'file-missing';
1656
1853
  continue;
1657
1854
  }
1855
+ if (!isScanTargetInsideProject(filePath, projectCwd)) {
1856
+ lastSkip = 'outside-project';
1857
+ continue;
1858
+ }
1658
1859
 
1659
1860
  const maxFileBytes = config.limits?.maxFileBytes ?? DEFAULT_CONFIG.limits.maxFileBytes;
1660
1861
  if (maxFileBytes > 0) {
@@ -1758,20 +1959,23 @@ export async function runHook({ stdinJson, env = {}, cwd = process.cwd(), now =
1758
1959
  }
1759
1960
  }
1760
1961
 
1761
- // Persist only when the write is earned: fresh findings justify creating
1762
- // `.impeccable/` (dedup and suppression need it), deferred findings do
1763
- // too (the Stop deep pass needs the touched-file list to surface them),
1764
- // and an already-present `.impeccable/` dir marks a project that opted
1765
- // in. A non-UI edit, or a clean UI edit in a project with no Impeccable
1766
- // footprint, must be a no-op on disk (issues #344, #305).
1767
- if (freshGroups.length > 0 || deferredTotal > 0
1768
- || (cacheDirty && fs.existsSync(path.join(projectCwd, '.impeccable')))) {
1769
- persistCache(projectCwd, cache);
1770
- }
1771
-
1962
+ // The session notice flags mutate the cache, so they must settle before
1963
+ // the persist that makes them stick across events.
1772
1964
  if (freshGroups.length > 0) {
1773
1965
  const firstGroup = freshGroups[0];
1774
- const text = appendDesignSystemNote(renderGroupedTemplate(freshGroups, config, { cwd: projectCwd }), scanOptions);
1966
+ const footerMode = footerModeForSession(cache, sessionId);
1967
+ const text = appendDesignSystemNoteOnce(
1968
+ renderGroupedTemplate(freshGroups, config, {
1969
+ cwd: projectCwd,
1970
+ footer: footerMode,
1971
+ reserveChars: designNoteReserve(scanOptions, cache, sessionId),
1972
+ }),
1973
+ scanOptions, cache, sessionId, config,
1974
+ );
1975
+ commitFooterShown(cache, sessionId, text);
1976
+ // Fresh findings always earn the cache write, including creating
1977
+ // `.impeccable/`: dedup, suppression, and the notice flags need it.
1978
+ persistCache(projectCwd, cache);
1775
1979
  const allFindings = freshGroups.flatMap((group) => group.findings);
1776
1980
  return {
1777
1981
  exitCode: 0,
@@ -1794,6 +1998,33 @@ export async function runHook({ stdinJson, env = {}, cwd = process.cwd(), now =
1794
1998
  };
1795
1999
  }
1796
2000
 
2001
+ // Resolve the ack emission before the persist below: appendDesignSystem-
2002
+ // NoteOnce consumes a session flag, and the flag only sticks when the
2003
+ // write happens after it. Quiet mode emits nothing, so it consumes
2004
+ // nothing. The clean arm mirrors the branch order further down: pending
2005
+ // outranks suppression, suppression outranks clean.
2006
+ let ack = null;
2007
+ if (!quietMode && pendingWinner && shouldEmitAckForFile(pendingWinner.filePath, config)) {
2008
+ ack = {
2009
+ kind: 'pending',
2010
+ text: appendDesignSystemNoteOnce(renderPendingAck(pendingWinner.filePath, pendingWinner.known, { cwd: projectCwd }), scanOptions, cache, sessionId, config),
2011
+ };
2012
+ } else if (!quietMode && !suppressionWinner && cleanWinner && !cleanAckDeduped && shouldEmitAckForFile(cleanWinner.filePath, config)) {
2013
+ ack = {
2014
+ kind: 'clean',
2015
+ text: appendDesignSystemNoteOnce(renderCleanAck(cleanWinner.filePath, { cwd: projectCwd }), scanOptions, cache, sessionId, config),
2016
+ };
2017
+ }
2018
+
2019
+ // Persist only when the write is earned: deferred findings need the
2020
+ // touched-file list for the Stop deep pass, and an already-present
2021
+ // `.impeccable/` dir marks a project that opted in. A non-UI edit, or a
2022
+ // clean UI edit in a project with no Impeccable footprint, must be a
2023
+ // no-op on disk (issues #344, #305).
2024
+ if (deferredTotal > 0 || (cacheDirty && fs.existsSync(path.join(projectCwd, '.impeccable')))) {
2025
+ persistCache(projectCwd, cache);
2026
+ }
2027
+
1797
2028
  if (detectorThrewAny && !pendingWinner && !cleanWinner) {
1798
2029
  return result({ emitted: false, error: 'detector-threw', durationMs: Date.now() - started });
1799
2030
  }
@@ -1802,8 +2033,8 @@ export async function runHook({ stdinJson, env = {}, cwd = process.cwd(), now =
1802
2033
  return result({ emitted: false, quiet: true, durationMs: Date.now() - started });
1803
2034
  }
1804
2035
 
1805
- if (pendingWinner && shouldEmitAckForFile(pendingWinner.filePath, config)) {
1806
- const text = appendDesignSystemNote(renderPendingAck(pendingWinner.filePath, pendingWinner.known, { cwd: projectCwd }), scanOptions);
2036
+ if (ack?.kind === 'pending') {
2037
+ const text = ack.text;
1807
2038
  return {
1808
2039
  exitCode: 0,
1809
2040
  stdout: payload(text, 'PostToolUse', harness),
@@ -1836,8 +2067,8 @@ export async function runHook({ stdinJson, env = {}, cwd = process.cwd(), now =
1836
2067
  };
1837
2068
  }
1838
2069
 
1839
- if (cleanWinner && !cleanAckDeduped && shouldEmitAckForFile(cleanWinner.filePath, config)) {
1840
- const text = appendDesignSystemNote(renderCleanAck(cleanWinner.filePath, { cwd: projectCwd }), scanOptions);
2070
+ if (ack?.kind === 'clean') {
2071
+ const text = ack.text;
1841
2072
  return {
1842
2073
  exitCode: 0,
1843
2074
  stdout: payload(text, 'PostToolUse', harness),
@@ -1985,6 +2216,10 @@ export async function runStopHook({ stdinJson, env = {}, cwd = process.cwd(), no
1985
2216
  const relForMatch = relativize(filePath, projectCwd);
1986
2217
  if (matchesAnyGlob(relForMatch, config.ignoreFiles) || matchesAnyGlob(filePath, config.ignoreFiles)) continue;
1987
2218
  if (!fs.existsSync(filePath)) continue;
2219
+ // Caches written before this gate existed can still hold out-of-project
2220
+ // paths, so the Stop pass re-checks containment rather than trusting
2221
+ // the per-edit pass to have filtered them.
2222
+ if (!isScanTargetInsideProject(filePath, projectCwd)) continue;
1988
2223
 
1989
2224
  scanned += 1;
1990
2225
  let content = '';
@@ -2017,11 +2252,22 @@ export async function runStopHook({ stdinJson, env = {}, cwd = process.cwd(), no
2017
2252
  return result({ emitted: false, skipped: 'stop-clean', durationMs: Date.now() - started });
2018
2253
  }
2019
2254
 
2255
+ // A per-edit fire earlier in this session already consumed the footer
2256
+ // flag, so the Stop wall of text carries the one-line short footer.
2257
+ const footerMode = footerModeForSession(cache, sessionId);
2258
+ const text = appendDesignSystemNoteOnce(
2259
+ renderGroupedTemplate(freshGroups, config, {
2260
+ cwd: projectCwd,
2261
+ footer: footerMode,
2262
+ reserveChars: designNoteReserve(scanOptions, cache, sessionId),
2263
+ }),
2264
+ scanOptions, cache, sessionId, config,
2265
+ );
2266
+ commitFooterShown(cache, sessionId, text);
2267
+
2020
2268
  // Fresh findings earn the cache write so the next Stop fire is silent
2021
- // unless new issues appear.
2269
+ // unless new issues appear; the notice flags ride along.
2022
2270
  persistCache(projectCwd, cache);
2023
-
2024
- const text = appendDesignSystemNote(renderGroupedTemplate(freshGroups, config, { cwd: projectCwd }), scanOptions);
2025
2271
  return {
2026
2272
  exitCode: 0,
2027
2273
  stdout: payload(text, 'Stop', harness),