@bastani/atomic 0.9.5-alpha.8 → 0.9.5

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 (530) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/README.md +2 -2
  3. package/dist/builtin/cursor/CHANGELOG.md +12 -0
  4. package/dist/builtin/cursor/package.json +3 -3
  5. package/dist/builtin/cursor/src/model-mapper.ts +6 -3
  6. package/dist/builtin/intercom/CHANGELOG.md +37 -0
  7. package/dist/builtin/intercom/README.md +4 -2
  8. package/dist/builtin/intercom/broker/broker.ts +6 -114
  9. package/dist/builtin/intercom/broker/client.ts +29 -54
  10. package/dist/builtin/intercom/broker/delivered-message-cache.ts +44 -0
  11. package/dist/builtin/intercom/broker/pending-send-registry.ts +142 -0
  12. package/dist/builtin/intercom/broker/send-handler.ts +106 -0
  13. package/dist/builtin/intercom/broker/send-signature.ts +37 -0
  14. package/dist/builtin/intercom/foreground-detach-handoff.ts +136 -0
  15. package/dist/builtin/intercom/index-heavy.ts +49 -53
  16. package/dist/builtin/intercom/index.ts +278 -262
  17. package/dist/builtin/intercom/lazy-heavy-proxy.ts +114 -0
  18. package/dist/builtin/intercom/lazy-subagent-ack.ts +20 -0
  19. package/dist/builtin/intercom/lazy-tool-execution.ts +39 -0
  20. package/dist/builtin/intercom/lifecycle-lease.ts +51 -0
  21. package/dist/builtin/intercom/lifecycle.ts +37 -20
  22. package/dist/builtin/intercom/package.json +3 -6
  23. package/dist/builtin/intercom/reply-routing.ts +17 -0
  24. package/dist/builtin/intercom/subagent-relay.ts +58 -12
  25. package/dist/builtin/intercom/types.ts +3 -3
  26. package/dist/builtin/mcp/CHANGELOG.md +38 -0
  27. package/dist/builtin/mcp/OAUTH.md +1 -0
  28. package/dist/builtin/mcp/README.md +10 -6
  29. package/dist/builtin/mcp/apps-cancellation.ts +32 -0
  30. package/dist/builtin/mcp/call-tool-result.ts +9 -0
  31. package/dist/builtin/mcp/caller-wait.ts +50 -0
  32. package/dist/builtin/mcp/command-registration.ts +82 -0
  33. package/dist/builtin/mcp/direct-tool-executor.ts +279 -0
  34. package/dist/builtin/mcp/direct-tools.ts +40 -255
  35. package/dist/builtin/mcp/host-html-template.ts +4 -2
  36. package/dist/builtin/mcp/index.ts +274 -239
  37. package/dist/builtin/mcp/init.ts +96 -126
  38. package/dist/builtin/mcp/mcp-auth-flow.ts +247 -237
  39. package/dist/builtin/mcp/mcp-callback-server.ts +89 -68
  40. package/dist/builtin/mcp/mcp-oauth-provider.ts +23 -1
  41. package/dist/builtin/mcp/metadata-hydration.ts +52 -0
  42. package/dist/builtin/mcp/package.json +3 -3
  43. package/dist/builtin/mcp/proxy-auth.ts +4 -4
  44. package/dist/builtin/mcp/proxy-call.ts +111 -40
  45. package/dist/builtin/mcp/proxy-connect.ts +35 -15
  46. package/dist/builtin/mcp/proxy-info-modes.ts +106 -23
  47. package/dist/builtin/mcp/proxy-modes.ts +3 -3
  48. package/dist/builtin/mcp/session-cleanup-barrier.ts +43 -0
  49. package/dist/builtin/mcp/startup-warmup.ts +98 -0
  50. package/dist/builtin/mcp/state-lease.ts +12 -0
  51. package/dist/builtin/mcp/tool-result-renderer.ts +3 -3
  52. package/dist/builtin/mcp/ui-server.ts +8 -8
  53. package/dist/builtin/mcp/ui-session.ts +9 -18
  54. package/dist/builtin/subagents/CHANGELOG.md +78 -0
  55. package/dist/builtin/subagents/README.md +30 -29
  56. package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
  57. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
  58. package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
  59. package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
  60. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
  61. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
  62. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
  63. package/dist/builtin/subagents/agents/debugger.md +2 -2
  64. package/dist/builtin/subagents/agents/worker.md +2 -2
  65. package/dist/builtin/subagents/package.json +5 -5
  66. package/dist/builtin/subagents/prompts/review-loop.md +1 -1
  67. package/dist/builtin/subagents/skills/subagent/SKILL.md +37 -36
  68. package/dist/builtin/subagents/src/extension/api-lifecycle.ts +64 -0
  69. package/dist/builtin/subagents/src/extension/fanout-child.ts +44 -51
  70. package/dist/builtin/subagents/src/extension/index.ts +289 -320
  71. package/dist/builtin/subagents/src/extension/prompt-guidance.ts +7 -10
  72. package/dist/builtin/subagents/src/extension/schemas.ts +22 -5
  73. package/dist/builtin/subagents/src/extension/startup-maintenance.ts +89 -0
  74. package/dist/builtin/subagents/src/extension/tool-description.ts +29 -0
  75. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +13 -2
  76. package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -4
  77. package/dist/builtin/subagents/src/runs/background/async-event-journal.ts +106 -0
  78. package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +26 -20
  79. package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +13 -2
  80. package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +3 -0
  81. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -1
  82. package/dist/builtin/subagents/src/runs/background/completion-claims.ts +189 -0
  83. package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +44 -7
  84. package/dist/builtin/subagents/src/runs/background/completion-notification.ts +34 -0
  85. package/dist/builtin/subagents/src/runs/background/notify.ts +72 -22
  86. package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +232 -0
  87. package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +151 -0
  88. package/dist/builtin/subagents/src/runs/background/result-quarantine.ts +72 -0
  89. package/dist/builtin/subagents/src/runs/background/result-retry-scheduler.ts +48 -0
  90. package/dist/builtin/subagents/src/runs/background/result-status.ts +81 -0
  91. package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +59 -0
  92. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +177 -233
  93. package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +3 -2
  94. package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +73 -14
  95. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +29 -15
  96. package/dist/builtin/subagents/src/runs/background/top-level-async.ts +1 -2
  97. package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +1 -0
  98. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +1 -0
  99. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +1 -0
  100. package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +7 -9
  101. package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +3 -13
  102. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +2 -15
  103. package/dist/builtin/subagents/src/runs/foreground/execution-attempt-finalize.ts +2 -2
  104. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +63 -46
  105. package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +48 -0
  106. package/dist/builtin/subagents/src/runs/foreground/execution-detach-route.ts +17 -0
  107. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +39 -26
  108. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +3 -1
  109. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +3 -51
  110. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +6 -11
  111. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +11 -2
  112. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
  113. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +5 -112
  114. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +2 -0
  115. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +68 -118
  116. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +79 -7
  117. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +2 -2
  118. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +3 -0
  119. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -2
  120. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +55 -12
  121. package/dist/builtin/subagents/src/shared/artifacts.ts +22 -11
  122. package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +294 -0
  123. package/dist/builtin/subagents/src/shared/exclusive-file-publication.ts +44 -0
  124. package/dist/builtin/subagents/src/shared/jsonl-writer.ts +1 -0
  125. package/dist/builtin/subagents/src/shared/model-info.ts +2 -2
  126. package/dist/builtin/subagents/src/shared/settings.ts +20 -10
  127. package/dist/builtin/subagents/src/shared/types-async.ts +3 -1
  128. package/dist/builtin/subagents/src/shared/types-config.ts +2 -0
  129. package/dist/builtin/subagents/src/shared/types-runtime.ts +3 -2
  130. package/dist/builtin/subagents/src/slash/slash-commands.ts +9 -12
  131. package/dist/builtin/subagents/src/slash/slash-live-state.ts +63 -32
  132. package/dist/builtin/subagents/src/tui/render-result.ts +7 -0
  133. package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -0
  134. package/dist/builtin/subagents/src/tui/render-widget.ts +157 -89
  135. package/dist/builtin/web-access/CHANGELOG.md +28 -0
  136. package/dist/builtin/web-access/README.md +4 -0
  137. package/dist/builtin/web-access/content-tools.ts +8 -3
  138. package/dist/builtin/web-access/index-heavy.ts +1 -1
  139. package/dist/builtin/web-access/index.ts +190 -46
  140. package/dist/builtin/web-access/lifecycle-lease.ts +38 -0
  141. package/dist/builtin/web-access/package.json +2 -2
  142. package/dist/builtin/web-access/result-renderers.ts +1 -1
  143. package/dist/builtin/web-access/summary-review.ts +1 -1
  144. package/dist/builtin/web-access/web-search-activity.ts +1 -1
  145. package/dist/builtin/web-access/web-search-return.ts +7 -0
  146. package/dist/builtin/web-access/web-search-summary.ts +1 -1
  147. package/dist/builtin/web-access/web-search-tool.ts +4 -2
  148. package/dist/builtin/workflows/CHANGELOG.md +86 -0
  149. package/dist/builtin/workflows/README.md +5 -5
  150. package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +27 -4
  151. package/dist/builtin/workflows/builtin/goal-runner.ts +86 -27
  152. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +10 -0
  153. package/dist/builtin/workflows/builtin/ralph-core.ts +9 -9
  154. package/dist/builtin/workflows/builtin/ralph-models.ts +71 -36
  155. package/dist/builtin/workflows/builtin/ralph-runner.ts +20 -31
  156. package/dist/builtin/workflows/package.json +2 -2
  157. package/dist/builtin/workflows/skills/impeccable/SKILL.md +16 -13
  158. package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +1 -0
  159. package/dist/builtin/workflows/skills/impeccable/reference/adapt.native.md +58 -0
  160. package/dist/builtin/workflows/skills/impeccable/reference/android.md +40 -0
  161. package/dist/builtin/workflows/skills/impeccable/reference/animate.md +2 -0
  162. package/dist/builtin/workflows/skills/impeccable/reference/audit.md +2 -0
  163. package/dist/builtin/workflows/skills/impeccable/reference/audit.native.md +139 -0
  164. package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +69 -62
  165. package/dist/builtin/workflows/skills/impeccable/reference/critique.md +21 -7
  166. package/dist/builtin/workflows/skills/impeccable/reference/document.md +1 -1
  167. package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +92 -0
  168. package/dist/builtin/workflows/skills/impeccable/reference/init.md +29 -7
  169. package/dist/builtin/workflows/skills/impeccable/reference/ios.md +45 -0
  170. package/dist/builtin/workflows/skills/impeccable/reference/layout.md +25 -1
  171. package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +23 -1
  172. package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +2 -1
  173. package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +75 -14
  174. package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +1 -1
  175. package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +31 -0
  176. package/dist/builtin/workflows/skills/impeccable/scripts/detector/design-system.mjs +64 -0
  177. package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +118 -11
  178. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +16 -11
  179. package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +66 -0
  180. package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +42 -10
  181. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/fonts.mjs +30 -0
  182. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/page.mjs +4 -6
  183. package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +660 -0
  184. package/dist/builtin/workflows/skills/impeccable/scripts/hook-before-edit.mjs +516 -0
  185. package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +1764 -0
  186. package/dist/builtin/workflows/skills/impeccable/scripts/hook.mjs +61 -0
  187. package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-config.mjs +4 -2
  188. package/dist/builtin/workflows/skills/impeccable/scripts/lib/is-generated.mjs +2 -2
  189. package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-component.mjs +13 -16
  190. package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +17 -11
  191. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +104 -37
  192. package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +9 -0
  193. package/dist/builtin/workflows/src/durable/backend.ts +12 -0
  194. package/dist/builtin/workflows/src/durable/dbos-backend.ts +17 -1
  195. package/dist/builtin/workflows/src/durable/resume-catalog.ts +12 -0
  196. package/dist/builtin/workflows/src/durable/resume-runtime.ts +5 -2
  197. package/dist/builtin/workflows/src/durable/stage-primitive.ts +2 -1
  198. package/dist/builtin/workflows/src/durable/types.ts +16 -0
  199. package/dist/builtin/workflows/src/engine/primitives/task.ts +3 -1
  200. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +1 -2
  201. package/dist/builtin/workflows/src/engine/run-returned-status.ts +50 -16
  202. package/dist/builtin/workflows/src/engine/run.ts +20 -19
  203. package/dist/builtin/workflows/src/engine/runtime.ts +5 -0
  204. package/dist/builtin/workflows/src/extension/extension-factory.ts +3 -0
  205. package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +9 -2
  206. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +137 -27
  207. package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +22 -6
  208. package/dist/builtin/workflows/src/extension/public-types.ts +1 -1
  209. package/dist/builtin/workflows/src/extension/workflow-command-completions.ts +13 -1
  210. package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +19 -4
  211. package/dist/builtin/workflows/src/extension/workflow-command-surfaces.ts +9 -0
  212. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +17 -22
  213. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +48 -23
  214. package/dist/builtin/workflows/src/extension/workflow-schema.ts +15 -2
  215. package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +20 -8
  216. package/dist/builtin/workflows/src/extension/workflow-tool.ts +24 -8
  217. package/dist/builtin/workflows/src/runs/background/status.ts +4 -3
  218. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +29 -8
  219. package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +1 -1
  220. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +3 -2
  221. package/dist/builtin/workflows/src/runs/shared/model-fallback-candidates.ts +1 -1
  222. package/dist/builtin/workflows/src/runs/shared/worktree-git.ts +155 -20
  223. package/dist/builtin/workflows/src/runs/shared/worktree-types.ts +6 -0
  224. package/dist/builtin/workflows/src/runs/shared/worktree.ts +2 -1
  225. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -2
  226. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +2 -2
  227. package/dist/builtin/workflows/src/shared/resume-continuation.ts +2 -0
  228. package/dist/builtin/workflows/src/shared/returned-run-status.ts +116 -0
  229. package/dist/builtin/workflows/src/shared/workflow-failures-decisions.ts +2 -0
  230. package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +21 -3
  231. package/dist/builtin/workflows/src/tui/graph-view-state.ts +3 -0
  232. package/dist/builtin/workflows/src/tui/graph-view-types.ts +3 -0
  233. package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +1 -23
  234. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +54 -9
  235. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +5 -2
  236. package/dist/builtin/workflows/src/tui/status-list.ts +22 -15
  237. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +4 -4
  238. package/dist/cli/args.d.ts.map +1 -1
  239. package/dist/cli/args.js +2 -2
  240. package/dist/cli/args.js.map +1 -1
  241. package/dist/core/agent-session-auto-compaction.d.ts +23 -3
  242. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  243. package/dist/core/agent-session-auto-compaction.js +129 -17
  244. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  245. package/dist/core/agent-session-events.d.ts.map +1 -1
  246. package/dist/core/agent-session-events.js +9 -1
  247. package/dist/core/agent-session-events.js.map +1 -1
  248. package/dist/core/agent-session-message-queue.d.ts.map +1 -1
  249. package/dist/core/agent-session-message-queue.js +1 -1
  250. package/dist/core/agent-session-message-queue.js.map +1 -1
  251. package/dist/core/agent-session-methods.d.ts +6 -3
  252. package/dist/core/agent-session-methods.d.ts.map +1 -1
  253. package/dist/core/agent-session-methods.js.map +1 -1
  254. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  255. package/dist/core/agent-session-prompt.js +2 -2
  256. package/dist/core/agent-session-prompt.js.map +1 -1
  257. package/dist/core/agent-session-retry.d.ts.map +1 -1
  258. package/dist/core/agent-session-retry.js +1 -1
  259. package/dist/core/agent-session-retry.js.map +1 -1
  260. package/dist/core/agent-session-services.d.ts.map +1 -1
  261. package/dist/core/agent-session-services.js +3 -2
  262. package/dist/core/agent-session-services.js.map +1 -1
  263. package/dist/core/agent-session-types.d.ts.map +1 -1
  264. package/dist/core/agent-session-types.js +1 -1
  265. package/dist/core/agent-session-types.js.map +1 -1
  266. package/dist/core/agent-session.d.ts +4 -2
  267. package/dist/core/agent-session.d.ts.map +1 -1
  268. package/dist/core/agent-session.js +4 -2
  269. package/dist/core/agent-session.js.map +1 -1
  270. package/dist/core/anthropic-thinking-guard.d.ts +5 -5
  271. package/dist/core/anthropic-thinking-guard.d.ts.map +1 -1
  272. package/dist/core/anthropic-thinking-guard.js +42 -32
  273. package/dist/core/anthropic-thinking-guard.js.map +1 -1
  274. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  275. package/dist/core/atomic-guide-command.js +15 -15
  276. package/dist/core/atomic-guide-command.js.map +1 -1
  277. package/dist/core/auth-storage.d.ts.map +1 -1
  278. package/dist/core/auth-storage.js +14 -9
  279. package/dist/core/auth-storage.js.map +1 -1
  280. package/dist/core/compaction/compaction.d.ts +2 -0
  281. package/dist/core/compaction/compaction.d.ts.map +1 -1
  282. package/dist/core/compaction/compaction.js +79 -46
  283. package/dist/core/compaction/compaction.js.map +1 -1
  284. package/dist/core/compaction/context-assistant-turns.d.ts +42 -0
  285. package/dist/core/compaction/context-assistant-turns.d.ts.map +1 -0
  286. package/dist/core/compaction/context-assistant-turns.js +87 -0
  287. package/dist/core/compaction/context-assistant-turns.js.map +1 -0
  288. package/dist/core/compaction/context-compaction-critical.d.ts +1 -1
  289. package/dist/core/compaction/context-compaction-critical.d.ts.map +1 -1
  290. package/dist/core/compaction/context-compaction-critical.js +2 -2
  291. package/dist/core/compaction/context-compaction-critical.js.map +1 -1
  292. package/dist/core/compaction/context-compaction-eviction-alternates.d.ts +18 -0
  293. package/dist/core/compaction/context-compaction-eviction-alternates.d.ts.map +1 -0
  294. package/dist/core/compaction/context-compaction-eviction-alternates.js +186 -0
  295. package/dist/core/compaction/context-compaction-eviction-alternates.js.map +1 -0
  296. package/dist/core/compaction/context-compaction-eviction.d.ts +10 -2
  297. package/dist/core/compaction/context-compaction-eviction.d.ts.map +1 -1
  298. package/dist/core/compaction/context-compaction-eviction.js +196 -146
  299. package/dist/core/compaction/context-compaction-eviction.js.map +1 -1
  300. package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
  301. package/dist/core/compaction/context-compaction-prompt.js +1 -1
  302. package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
  303. package/dist/core/compaction/context-compaction-types.d.ts +2 -0
  304. package/dist/core/compaction/context-compaction-types.d.ts.map +1 -1
  305. package/dist/core/compaction/context-compaction-types.js.map +1 -1
  306. package/dist/core/compaction/context-deletion-application.d.ts +5 -4
  307. package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
  308. package/dist/core/compaction/context-deletion-application.js +17 -15
  309. package/dist/core/compaction/context-deletion-application.js.map +1 -1
  310. package/dist/core/compaction/context-deletion-store.d.ts.map +1 -1
  311. package/dist/core/compaction/context-deletion-store.js +1 -1
  312. package/dist/core/compaction/context-deletion-store.js.map +1 -1
  313. package/dist/core/compaction/context-deletion-targets.d.ts +2 -1
  314. package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
  315. package/dist/core/compaction/context-deletion-targets.js +36 -31
  316. package/dist/core/compaction/context-deletion-targets.js.map +1 -1
  317. package/dist/core/compaction/context-deletion-tool-helpers.d.ts.map +1 -1
  318. package/dist/core/compaction/context-deletion-tool-helpers.js +116 -43
  319. package/dist/core/compaction/context-deletion-tool-helpers.js.map +1 -1
  320. package/dist/core/compaction/context-transcript-analysis.d.ts +1 -2
  321. package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
  322. package/dist/core/compaction/context-transcript-analysis.js +33 -37
  323. package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
  324. package/dist/core/copilot-model-synthesis.d.ts.map +1 -1
  325. package/dist/core/copilot-model-synthesis.js +3 -1
  326. package/dist/core/copilot-model-synthesis.js.map +1 -1
  327. package/dist/core/extensions/loader-virtual-modules.d.ts +8 -1
  328. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  329. package/dist/core/extensions/loader-virtual-modules.js +2 -1
  330. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  331. package/dist/core/extensions/provider-types.d.ts +2 -7
  332. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  333. package/dist/core/extensions/provider-types.js.map +1 -1
  334. package/dist/core/footer-data-provider.d.ts +6 -0
  335. package/dist/core/footer-data-provider.d.ts.map +1 -1
  336. package/dist/core/footer-data-provider.js +72 -29
  337. package/dist/core/footer-data-provider.js.map +1 -1
  338. package/dist/core/messages.d.ts +9 -0
  339. package/dist/core/messages.d.ts.map +1 -1
  340. package/dist/core/messages.js +100 -18
  341. package/dist/core/messages.js.map +1 -1
  342. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  343. package/dist/core/model-registry-builtins.js +5 -0
  344. package/dist/core/model-registry-builtins.js.map +1 -1
  345. package/dist/core/model-registry-custom-loader.d.ts.map +1 -1
  346. package/dist/core/model-registry-custom-loader.js +49 -8
  347. package/dist/core/model-registry-custom-loader.js.map +1 -1
  348. package/dist/core/model-registry-dynamic.d.ts.map +1 -1
  349. package/dist/core/model-registry-dynamic.js +11 -5
  350. package/dist/core/model-registry-dynamic.js.map +1 -1
  351. package/dist/core/model-registry-loader.d.ts.map +1 -1
  352. package/dist/core/model-registry-loader.js +8 -0
  353. package/dist/core/model-registry-loader.js.map +1 -1
  354. package/dist/core/model-registry-schemas.d.ts +93 -8
  355. package/dist/core/model-registry-schemas.d.ts.map +1 -1
  356. package/dist/core/model-registry-schemas.js +24 -12
  357. package/dist/core/model-registry-schemas.js.map +1 -1
  358. package/dist/core/model-registry-types.d.ts +7 -6
  359. package/dist/core/model-registry-types.d.ts.map +1 -1
  360. package/dist/core/model-registry-types.js.map +1 -1
  361. package/dist/core/model-registry.d.ts +5 -0
  362. package/dist/core/model-registry.d.ts.map +1 -1
  363. package/dist/core/model-registry.js +23 -0
  364. package/dist/core/model-registry.js.map +1 -1
  365. package/dist/core/model-resolver-cli.d.ts.map +1 -1
  366. package/dist/core/model-resolver-cli.js +33 -5
  367. package/dist/core/model-resolver-cli.js.map +1 -1
  368. package/dist/core/model-resolver-initial.d.ts +6 -1
  369. package/dist/core/model-resolver-initial.d.ts.map +1 -1
  370. package/dist/core/model-resolver-initial.js +12 -7
  371. package/dist/core/model-resolver-initial.js.map +1 -1
  372. package/dist/core/model-resolver.d.ts +1 -1
  373. package/dist/core/model-resolver.d.ts.map +1 -1
  374. package/dist/core/model-resolver.js +1 -1
  375. package/dist/core/model-resolver.js.map +1 -1
  376. package/dist/core/openai-responses-payload-sanitizer.d.ts +1 -0
  377. package/dist/core/openai-responses-payload-sanitizer.d.ts.map +1 -1
  378. package/dist/core/openai-responses-payload-sanitizer.js +24 -9
  379. package/dist/core/openai-responses-payload-sanitizer.js.map +1 -1
  380. package/dist/core/resource-loader-context-files.d.ts +1 -0
  381. package/dist/core/resource-loader-context-files.d.ts.map +1 -1
  382. package/dist/core/resource-loader-context-files.js +13 -10
  383. package/dist/core/resource-loader-context-files.js.map +1 -1
  384. package/dist/core/sdk.d.ts.map +1 -1
  385. package/dist/core/sdk.js +2 -2
  386. package/dist/core/sdk.js.map +1 -1
  387. package/dist/core/session-entry-normalization.d.ts +7 -0
  388. package/dist/core/session-entry-normalization.d.ts.map +1 -0
  389. package/dist/core/session-entry-normalization.js +14 -0
  390. package/dist/core/session-entry-normalization.js.map +1 -0
  391. package/dist/core/session-manager-core.d.ts.map +1 -1
  392. package/dist/core/session-manager-core.js +1 -0
  393. package/dist/core/session-manager-core.js.map +1 -1
  394. package/dist/core/session-manager-history.d.ts +2 -2
  395. package/dist/core/session-manager-history.d.ts.map +1 -1
  396. package/dist/core/session-manager-history.js +127 -108
  397. package/dist/core/session-manager-history.js.map +1 -1
  398. package/dist/core/settings-manager-basic-accessors.d.ts +2 -2
  399. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  400. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  401. package/dist/core/settings-types.d.ts +1 -1
  402. package/dist/core/settings-types.d.ts.map +1 -1
  403. package/dist/core/settings-types.js.map +1 -1
  404. package/dist/core/slash-commands.d.ts +2 -0
  405. package/dist/core/slash-commands.d.ts.map +1 -1
  406. package/dist/core/slash-commands.js +141 -0
  407. package/dist/core/slash-commands.js.map +1 -1
  408. package/dist/core/tools/bash.d.ts.map +1 -1
  409. package/dist/core/tools/bash.js +11 -8
  410. package/dist/core/tools/bash.js.map +1 -1
  411. package/dist/index.d.ts +1 -0
  412. package/dist/index.d.ts.map +1 -1
  413. package/dist/index.js +1 -0
  414. package/dist/index.js.map +1 -1
  415. package/dist/main-deferred-startup.d.ts.map +1 -1
  416. package/dist/main-deferred-startup.js +2 -2
  417. package/dist/main-deferred-startup.js.map +1 -1
  418. package/dist/main-early-input.d.ts.map +1 -1
  419. package/dist/main-early-input.js +7 -0
  420. package/dist/main-early-input.js.map +1 -1
  421. package/dist/main-session.d.ts.map +1 -1
  422. package/dist/main-session.js +1 -0
  423. package/dist/main-session.js.map +1 -1
  424. package/dist/main.d.ts.map +1 -1
  425. package/dist/main.js +1 -1
  426. package/dist/main.js.map +1 -1
  427. package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
  428. package/dist/modes/interactive/components/chat-session-host-actions.js +0 -1
  429. package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
  430. package/dist/modes/interactive/components/settings-selector-options.d.ts.map +1 -1
  431. package/dist/modes/interactive/components/settings-selector-options.js +3 -1
  432. package/dist/modes/interactive/components/settings-selector-options.js.map +1 -1
  433. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  434. package/dist/modes/interactive/components/thinking-selector.js +2 -1
  435. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  436. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  437. package/dist/modes/interactive/interactive-agent-events.js +3 -1
  438. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  439. package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  440. package/dist/modes/interactive/interactive-autocomplete.js +21 -9
  441. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  442. package/dist/modes/interactive/interactive-child-ordering.d.ts +7 -0
  443. package/dist/modes/interactive/interactive-child-ordering.d.ts.map +1 -0
  444. package/dist/modes/interactive/interactive-child-ordering.js +26 -0
  445. package/dist/modes/interactive/interactive-child-ordering.js.map +1 -0
  446. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  447. package/dist/modes/interactive/interactive-deferred-startup.js +43 -30
  448. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  449. package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
  450. package/dist/modes/interactive/interactive-hotkeys-debug.js +1 -0
  451. package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
  452. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  453. package/dist/modes/interactive/interactive-input-handling.js +41 -6
  454. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  455. package/dist/modes/interactive/interactive-mode-base.d.ts +3 -0
  456. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  457. package/dist/modes/interactive/interactive-mode-base.js +3 -0
  458. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  459. package/dist/modes/interactive/interactive-mode-deps.d.ts +2 -2
  460. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  461. package/dist/modes/interactive/interactive-mode-deps.js +2 -2
  462. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  463. package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -2
  464. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  465. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  466. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  467. package/dist/modes/interactive/interactive-model-routing.js +11 -4
  468. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  469. package/dist/modes/interactive/interactive-process-lifecycle.d.ts.map +1 -1
  470. package/dist/modes/interactive/interactive-process-lifecycle.js +0 -3
  471. package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
  472. package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
  473. package/dist/modes/interactive/interactive-render-chat.js +15 -1
  474. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  475. package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
  476. package/dist/modes/interactive/interactive-session-routing.js +5 -1
  477. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  478. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  479. package/dist/modes/interactive/interactive-startup.js +20 -21
  480. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  481. package/dist/modes/interactive/theme/global-theme.d.ts.map +1 -1
  482. package/dist/modes/interactive/theme/global-theme.js +26 -2
  483. package/dist/modes/interactive/theme/global-theme.js.map +1 -1
  484. package/dist/modes/interactive/theme/theme-class.d.ts +1 -1
  485. package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
  486. package/dist/modes/interactive/theme/theme-class.js +2 -0
  487. package/dist/modes/interactive/theme/theme-class.js.map +1 -1
  488. package/dist/utils/clipboard-image.d.ts.map +1 -1
  489. package/dist/utils/clipboard-image.js +3 -0
  490. package/dist/utils/clipboard-image.js.map +1 -1
  491. package/dist/utils/fs-watch.d.ts +24 -1
  492. package/dist/utils/fs-watch.d.ts.map +1 -1
  493. package/dist/utils/fs-watch.js +60 -5
  494. package/dist/utils/fs-watch.js.map +1 -1
  495. package/docs/changelog.mdx +19 -0
  496. package/docs/compaction.md +60 -49
  497. package/docs/custom-provider.md +18 -5
  498. package/docs/development.md +4 -0
  499. package/docs/extensions.md +11 -2
  500. package/docs/json.md +1 -1
  501. package/docs/models.md +69 -10
  502. package/docs/providers.md +1 -1
  503. package/docs/quickstart.md +12 -8
  504. package/docs/rpc.md +2 -2
  505. package/docs/sdk.md +1 -1
  506. package/docs/settings.md +4 -4
  507. package/docs/subagents.md +40 -5
  508. package/docs/tools.md +1 -1
  509. package/docs/usage.md +4 -2
  510. package/docs/windows.md +4 -0
  511. package/docs/workflows.md +33 -48
  512. package/examples/extensions/preset.ts +2 -2
  513. package/examples/extensions/subagent/README.md +2 -2
  514. package/examples/extensions/subagent/index.ts +1 -2
  515. package/examples/extensions/subagent/schemas.ts +4 -1
  516. package/examples/sdk/12-full-control.ts +1 -1
  517. package/npm-shrinkwrap.json +48 -51
  518. package/package.json +7 -7
  519. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-behavior.ts +0 -75
  520. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-component.ts +0 -202
  521. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-edit.ts +0 -97
  522. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-editor.ts +0 -160
  523. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-frame.ts +0 -72
  524. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-modes.ts +0 -161
  525. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-selectors.ts +0 -203
  526. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-selectors.ts +0 -234
  527. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-state.ts +0 -103
  528. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-types.ts +0 -29
  529. package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +0 -9
  530. package/dist/builtin/subagents/src/runs/foreground/chain-execution-clarify.ts +0 -117
@@ -123,6 +123,7 @@ const ANTIPATTERNS = [
123
123
  {
124
124
  id: 'overused-font',
125
125
  category: 'slop',
126
+ scopes: ['type'],
126
127
  name: 'Overused font',
127
128
  description:
128
129
  'Inter, Roboto, Fraunces, Geist, Plus Jakarta Sans, and Space Grotesk are used on so many sites they no longer feel distinctive. Each new wave of AI-generated UIs converges on the same handful of faces. Choose a face that gives your interface personality.',
@@ -132,6 +133,7 @@ const ANTIPATTERNS = [
132
133
  {
133
134
  id: 'single-font',
134
135
  category: 'slop',
136
+ scopes: ['type'],
135
137
  name: 'Single font for everything',
136
138
  description:
137
139
  'Only one font family is used for the entire page. Pair a distinctive display font with a refined body font to create typographic hierarchy.',
@@ -141,6 +143,7 @@ const ANTIPATTERNS = [
141
143
  {
142
144
  id: 'flat-type-hierarchy',
143
145
  category: 'slop',
146
+ scopes: ['type'],
144
147
  name: 'Flat type hierarchy',
145
148
  description:
146
149
  'Font sizes are too close together — no clear visual hierarchy. Use fewer sizes with more contrast (aim for at least a 1.25 ratio between steps).',
@@ -177,6 +180,7 @@ const ANTIPATTERNS = [
177
180
  {
178
181
  id: 'nested-cards',
179
182
  category: 'slop',
183
+ scopes: ['layout'],
180
184
  name: 'Nested cards',
181
185
  description:
182
186
  'Cards inside cards create visual noise and excessive depth. Flatten the hierarchy — use spacing, typography, and dividers instead of nesting containers.',
@@ -186,6 +190,7 @@ const ANTIPATTERNS = [
186
190
  {
187
191
  id: 'monotonous-spacing',
188
192
  category: 'slop',
193
+ scopes: ['layout'],
189
194
  name: 'Monotonous spacing',
190
195
  description:
191
196
  'The same spacing value used everywhere — no rhythm, no variation. Use tight groupings for related items and generous separations between sections.',
@@ -213,6 +218,7 @@ const ANTIPATTERNS = [
213
218
  {
214
219
  id: 'icon-tile-stack',
215
220
  category: 'slop',
221
+ scopes: ['layout'],
216
222
  name: 'Icon tile stacked above heading',
217
223
  description:
218
224
  'A small rounded-square icon container above a heading is the universal AI feature-card template — every generator outputs this exact shape. Try a side-by-side icon and heading, or let the icon sit in flow without its own container.',
@@ -222,6 +228,7 @@ const ANTIPATTERNS = [
222
228
  {
223
229
  id: 'italic-serif-display',
224
230
  category: 'slop',
231
+ scopes: ['type'],
225
232
  name: 'Italic serif display headline',
226
233
  description:
227
234
  'Oversized italic serif (Fraunces, Recoleta, Playfair, Newsreader-italic) as the primary hero headline reads as taste in isolation but has become the universal AI-startup landing page hero. Set roman, or move to a non-serif display face. Editorial / magazine register may legitimately want this — judge by context.',
@@ -231,6 +238,7 @@ const ANTIPATTERNS = [
231
238
  {
232
239
  id: 'hero-eyebrow-chip',
233
240
  category: 'slop',
241
+ scopes: ['type'],
234
242
  name: 'Hero eyebrow / pill chip',
235
243
  description:
236
244
  'A tiny uppercase letter-spaced label sitting immediately above an oversized hero headline — or the same shape rendered as a pill chip — is now the default AI SaaS hero. Drop the eyebrow, integrate the kicker into the headline, or run it as a navigation breadcrumb instead.',
@@ -240,6 +248,7 @@ const ANTIPATTERNS = [
240
248
  {
241
249
  id: 'repeated-section-kickers',
242
250
  category: 'slop',
251
+ scopes: ['type'],
243
252
  severity: 'advisory',
244
253
  name: 'Repeated section kicker labels',
245
254
  description:
@@ -250,6 +259,7 @@ const ANTIPATTERNS = [
250
259
  {
251
260
  id: 'numbered-section-markers',
252
261
  category: 'slop',
262
+ scopes: ['layout'],
253
263
  severity: 'advisory',
254
264
  name: 'Numbered section markers (01 / 02 / 03)',
255
265
  description:
@@ -287,6 +297,7 @@ const ANTIPATTERNS = [
287
297
  {
288
298
  id: 'oversized-h1',
289
299
  category: 'slop',
300
+ scopes: ['type'],
290
301
  name: 'Oversized hero headline',
291
302
  description:
292
303
  'A full-sentence headline set at display size ends up dominating the viewport, leaving no room for anything else above the fold. A punchy one- or two-word headline at that size is fine — the problem is a long headline blown up too large. Set long headlines smaller, or tighten the copy.',
@@ -296,6 +307,7 @@ const ANTIPATTERNS = [
296
307
  {
297
308
  id: 'extreme-negative-tracking',
298
309
  category: 'slop',
310
+ scopes: ['type'],
299
311
  name: 'Crushed letter spacing',
300
312
  description:
301
313
  'Letter-spacing pulled tighter than the point where characters keep their own shapes costs legibility. Tighten display type optically, not destructively.',
@@ -341,6 +353,7 @@ const ANTIPATTERNS = [
341
353
  {
342
354
  id: 'line-length',
343
355
  category: 'quality',
356
+ scopes: ['type', 'layout'],
344
357
  name: 'Line length too long',
345
358
  description:
346
359
  'Text lines wider than ~80 characters are hard to read. The eye loses its place tracking back to the start of the next line. Add a max-width (65ch to 75ch) to text containers.',
@@ -350,6 +363,7 @@ const ANTIPATTERNS = [
350
363
  {
351
364
  id: 'cramped-padding',
352
365
  category: 'quality',
366
+ scopes: ['layout'],
353
367
  name: 'Cramped padding',
354
368
  description:
355
369
  'Text is too close to the edge of its container. Two shapes: (1) an element with its own text where the padding is too low for the font size, and (2) a wrapper with text-bearing children and near-zero padding against a visible boundary (border, outline, or non-transparent background) — children land flush against the boundary line. Add at least 8px (ideally 12–16px) of padding inside bordered, outlined, or colored containers.',
@@ -359,6 +373,7 @@ const ANTIPATTERNS = [
359
373
  {
360
374
  id: 'body-text-viewport-edge',
361
375
  category: 'quality',
376
+ scopes: ['layout'],
362
377
  name: 'Body text touching viewport edge',
363
378
  description:
364
379
  'Body paragraphs render flush against the left or right viewport edge with no container providing horizontal padding. Wrap content in a container with at least 16px (ideally 24-32px) of horizontal padding, or apply max-width with mx-auto.',
@@ -366,6 +381,7 @@ const ANTIPATTERNS = [
366
381
  {
367
382
  id: 'tight-leading',
368
383
  category: 'quality',
384
+ scopes: ['type'],
369
385
  name: 'Tight line height',
370
386
  description:
371
387
  'Line height below 1.3x the font size makes multi-line text hard to read. Use 1.5 to 1.7 for body text so lines have room to breathe.',
@@ -373,6 +389,7 @@ const ANTIPATTERNS = [
373
389
  {
374
390
  id: 'skipped-heading',
375
391
  category: 'quality',
392
+ scopes: ['type'],
376
393
  name: 'Skipped heading level',
377
394
  description:
378
395
  'Heading levels should not skip (e.g. h1 then h3 with no h2). Screen readers use heading hierarchy for navigation. Skipping levels breaks the document outline.',
@@ -380,6 +397,7 @@ const ANTIPATTERNS = [
380
397
  {
381
398
  id: 'justified-text',
382
399
  category: 'quality',
400
+ scopes: ['type'],
383
401
  name: 'Justified text',
384
402
  description:
385
403
  'Justified text without hyphenation creates uneven word spacing ("rivers of white"). Use text-align: left for body text, or enable hyphens: auto if you must justify.',
@@ -387,6 +405,7 @@ const ANTIPATTERNS = [
387
405
  {
388
406
  id: 'tiny-text',
389
407
  category: 'quality',
408
+ scopes: ['type'],
390
409
  name: 'Tiny body text',
391
410
  description:
392
411
  'Body text below 12px is hard to read, especially on high-DPI screens. Use at least 14px for body content, 16px is ideal.',
@@ -394,6 +413,7 @@ const ANTIPATTERNS = [
394
413
  {
395
414
  id: 'all-caps-body',
396
415
  category: 'quality',
416
+ scopes: ['type'],
397
417
  name: 'All-caps body text',
398
418
  description:
399
419
  'Long passages in uppercase are hard to read. We recognize words by shape (ascenders and descenders), which all-caps removes. Reserve uppercase for short labels and headings.',
@@ -403,6 +423,7 @@ const ANTIPATTERNS = [
403
423
  {
404
424
  id: 'wide-tracking',
405
425
  category: 'quality',
426
+ scopes: ['type'],
406
427
  name: 'Wide letter spacing on body text',
407
428
  description:
408
429
  'Letter spacing above 0.05em on body text disrupts natural character groupings and slows reading. Reserve wide tracking for short uppercase labels only.',
@@ -410,6 +431,7 @@ const ANTIPATTERNS = [
410
431
  {
411
432
  id: 'text-overflow',
412
433
  category: 'quality',
434
+ scopes: ['layout'],
413
435
  name: 'Content overflowing its container',
414
436
  description:
415
437
  'Content renders wider than its container, spilling out or forcing a horizontal scrollbar. Let text wrap, constrain widths, or give the region a deliberate scroll affordance.',
@@ -419,6 +441,7 @@ const ANTIPATTERNS = [
419
441
  {
420
442
  id: 'clipped-overflow-container',
421
443
  category: 'quality',
444
+ scopes: ['layout'],
422
445
  name: 'Positioned child clipped by overflow container',
423
446
  description:
424
447
  'A clipping container (overflow hidden or clip) wrapping an absolutely-positioned child cuts off tooltips, menus, and popovers that need to escape. Let the overflow be visible, or move the positioned layer out of the clip.',
@@ -428,6 +451,7 @@ const ANTIPATTERNS = [
428
451
  {
429
452
  id: 'design-system-font',
430
453
  category: 'quality',
454
+ scopes: ['type'],
431
455
  name: 'Font outside DESIGN.md',
432
456
  description:
433
457
  'A font is used that is not declared in DESIGN.md typography. Use the documented type system or update DESIGN.md if this is an intentional brand addition.',
@@ -454,6 +478,17 @@ const ANTIPATTERNS = [
454
478
  skillSection: 'Visual Details',
455
479
  skillGuideline: 'border radius outside the project design system',
456
480
  },
481
+ {
482
+ id: 'design-system-font-size',
483
+ category: 'quality',
484
+ severity: 'advisory',
485
+ scopes: ['type'],
486
+ name: 'Font size outside DESIGN.md',
487
+ description:
488
+ 'A literal font-size is off the type ramp documented in DESIGN.md typography. Use a documented size step or update the design system if the new step is intentional.',
489
+ skillSection: 'Typography',
490
+ skillGuideline: 'font size outside the project design system',
491
+ },
457
492
 
458
493
  // ── Provider tells: opt-in via --gpt / --gemini (gated off by default) ──
459
494
  {
@@ -478,6 +513,17 @@ const ANTIPATTERNS = [
478
513
  skillSection: 'Visual Details',
479
514
  skillGuideline: 'repeating-gradient decorative stripes',
480
515
  },
516
+ {
517
+ id: 'codex-grid-background',
518
+ category: 'slop',
519
+ severity: 'advisory',
520
+ gated: 'gpt',
521
+ name: 'Decorative grid-line background',
522
+ description:
523
+ 'A two-axis grid drawn with hairline linear-gradient layers ("1px, transparent 1px" on both axes) is a recurring generated-UI signature. Reserve grid overlays for actual canvas, map, blueprint, or measurement surfaces; elsewhere use product structure or a plain surface.',
524
+ skillSection: 'Visual Details',
525
+ skillGuideline: 'two-axis grid-line gradient background',
526
+ },
481
527
  {
482
528
  id: 'theater-slop-phrase',
483
529
  category: 'slop',
@@ -617,6 +663,36 @@ function colorToHex(c) {
617
663
  return '#' + [c.r, c.g, c.b].map(v => v.toString(16).padStart(2, '0')).join('');
618
664
  }
619
665
 
666
+ // --- cli/engine/shared/fonts.mjs ---
667
+ const GOOGLE_FONTS_URL_RE = /fonts\.googleapis\.com\/css2?\?[^"'\s)<>]*/gi;
668
+
669
+ function normalizeGoogleFontFamilyParam(value) {
670
+ return String(value || '')
671
+ .split('|')
672
+ .map(part => part.split(':')[0].trim().toLowerCase())
673
+ .filter(Boolean);
674
+ }
675
+
676
+ function extractGoogleFontFamilies(text) {
677
+ const families = [];
678
+ if (!text) return families;
679
+
680
+ GOOGLE_FONTS_URL_RE.lastIndex = 0;
681
+ let urlMatch;
682
+ while ((urlMatch = GOOGLE_FONTS_URL_RE.exec(text)) !== null) {
683
+ const url = urlMatch[0];
684
+ const queryStart = url.indexOf('?');
685
+ if (queryStart === -1) continue;
686
+
687
+ const params = new URLSearchParams(url.slice(queryStart + 1).replace(/&amp;/g, '&'));
688
+ for (const value of params.getAll('family')) {
689
+ families.push(...normalizeGoogleFontFamilyParam(value));
690
+ }
691
+ }
692
+
693
+ return families;
694
+ }
695
+
620
696
  // --- cli/engine/rules/checks.mjs ---
621
697
  const DETECTOR_IS_BROWSER = typeof window !== 'undefined';
622
698
 
@@ -1172,13 +1248,49 @@ function checkHtmlPatterns(html) {
1172
1248
  findings.push({ id: 'repeating-stripes-gradient', snippet: 'repeating-gradient decorative stripes' });
1173
1249
  }
1174
1250
 
1251
+ // --- Provider tells (gated): two-axis grid-line background (Codex/GPT) ---
1252
+ // The Codex grid tell is two hairline `linear-gradient(... <color> 1px,
1253
+ // transparent 1px)` layers (one per axis) tiled by a repeating
1254
+ // `background-size` cell. Both signals must co-occur in the SAME style block
1255
+ // (a CSS rule body or one inline `style="..."`): two hairline stops WITHOUT a
1256
+ // tiling background-size is a fixed crosshair, not a grid, and a single
1257
+ // hairline is a legitimate ruled line. Scoping to one block also stops
1258
+ // unrelated single-axis rules on separate elements from adding up across the
1259
+ // page. Count hairlines only inside `background`/`background-image` values so
1260
+ // a hairline in an unrelated property (mask-image, border-image) can't stand
1261
+ // in for the second axis. Colors like `oklch(96% 0.012 82 / 0.055)` carry
1262
+ // nested parens, so match the hairline stop directly rather than parsing
1263
+ // whole gradient layers.
1264
+ {
1265
+ const hairlineRe = /\b\d{1,3}px\s*,\s*transparent\s+\d{1,3}px/gi;
1266
+ const gridSizeRe = /background-size\s*:[^;{}"']*\b\d{1,3}px\b/i;
1267
+ const bgDeclRe = /\bbackground(?:-image)?\s*:\s*([^;{}"']*)/gi;
1268
+ const blockRe = /\{([^{}]*)\}|style\s*=\s*"([^"]*)"|style\s*=\s*'([^']*)'/gi;
1269
+ let blk;
1270
+ while ((blk = blockRe.exec(html)) !== null) {
1271
+ const block = blk[1] || blk[2] || blk[3] || '';
1272
+ if (!gridSizeRe.test(block)) continue;
1273
+ let hairlineCount = 0;
1274
+ let bm;
1275
+ bgDeclRe.lastIndex = 0;
1276
+ while ((bm = bgDeclRe.exec(block)) !== null) {
1277
+ const stops = bm[1].match(hairlineRe);
1278
+ if (stops) hairlineCount += stops.length;
1279
+ }
1280
+ if (hairlineCount >= 2) {
1281
+ findings.push({ id: 'codex-grid-background', snippet: 'two-axis grid-line gradient background' });
1282
+ break;
1283
+ }
1284
+ }
1285
+ }
1286
+
1175
1287
  // --- Provider tells (gated): "X theater" framing copy (GPT) ---
1176
1288
  // Lives here (regex-on-HTML) rather than in the text-content analyzers so it
1177
1289
  // runs in the bundled browser path too, not just the CLI/static path.
1178
1290
  {
1179
1291
  const bodyText = html
1180
- .replace(/<script\b[^>]*>[\s\S]*?<\/script[^>]*>/gi, ' ')
1181
- .replace(/<style\b[^>]*>[\s\S]*?<\/style[^>]*>/gi, ' ')
1292
+ .replace(/<script\b[^>]*>[\s\S]*?<\/script\b[^>]*>/gi, ' ')
1293
+ .replace(/<style\b[^>]*>[\s\S]*?<\/style\b[^>]*>/gi, ' ')
1182
1294
  .replace(/<[^>]+>/g, ' ');
1183
1295
  const tm = /\b(\w+)\s+theater\b/i.exec(bodyText);
1184
1296
  if (tm) findings.push({ id: 'theater-slop-phrase', snippet: `"${tm[0].trim()}"` });
@@ -2635,14 +2747,9 @@ function checkPageTypography(doc, win) {
2635
2747
 
2636
2748
  // Check Google Fonts links in HTML
2637
2749
  const html = doc.documentElement?.outerHTML || '';
2638
- const gfRe = /fonts\.googleapis\.com\/css2?\?family=([^&"'\s]+)/gi;
2639
- let m;
2640
- while ((m = gfRe.exec(html)) !== null) {
2641
- const families = m[1].split('|').map(f => f.split(':')[0].replace(/\+/g, ' ').toLowerCase());
2642
- for (const f of families) {
2643
- fonts.add(f);
2644
- if (OVERUSED_FONTS.has(f)) overusedFound.add(f);
2645
- }
2750
+ for (const f of extractGoogleFontFamilies(html)) {
2751
+ fonts.add(f);
2752
+ if (OVERUSED_FONTS.has(f)) overusedFound.add(f);
2646
2753
  }
2647
2754
 
2648
2755
  // Also parse raw HTML/style content for font-family (jsdom may not expose all via CSSOM)
@@ -4475,7 +4582,7 @@ if (IS_BROWSER) {
4475
4582
 
4476
4583
  function browserPrimaryFont(stack) {
4477
4584
  if (!stack || /var\(/i.test(stack)) return '';
4478
- return String(stack)
4585
+ return String(stack || '')
4479
4586
  .split(',')
4480
4587
  .map(normalizeBrowserFontName)
4481
4588
  .find(font => font && !GENERIC_FONTS.has(font)) || '';
@@ -1,5 +1,6 @@
1
- import { GENERIC_FONTS } from '../../shared/constants.mjs';
1
+ import { GENERIC_FONTS, OVERUSED_FONTS } from '../../shared/constants.mjs';
2
2
  import { isNeutralColor } from '../../shared/color.mjs';
3
+ import { extractGoogleFontFamilies } from '../../shared/fonts.mjs';
3
4
  import { checkSourceDesignSystem } from '../../design-system.mjs';
4
5
  import { isFullPage } from '../../shared/page.mjs';
5
6
  import { applyInlineIgnores } from '../../shared/inline-ignores.mjs';
@@ -19,8 +20,8 @@ const isSafeElement = (line) => /<(?:blockquote|nav[\s>]|pre[\s>]|code[\s>]|a\s|
19
20
  * content-text analyzers don't false-positive on code or CSS. */
20
21
  function stripHtmlToText(html) {
21
22
  return html
22
- .replace(/<script\b[^>]*>[\s\S]*?<\/script[^>]*>/gi, ' ')
23
- .replace(/<style\b[^>]*>[\s\S]*?<\/style[^>]*>/gi, ' ')
23
+ .replace(/<script\b[^>]*>[\s\S]*?<\/script\b[^>]*>/gi, ' ')
24
+ .replace(/<style\b[^>]*>[\s\S]*?<\/style\b[^>]*>/gi, ' ')
24
25
  .replace(/<!--[\s\S]*?-->/g, ' ')
25
26
  .replace(/<[^>]+>/g, ' ')
26
27
  .replace(/\s+/g, ' ');
@@ -38,6 +39,10 @@ function shouldRunPageAnalyzers(content, filePath) {
38
39
  return !ext || PAGE_ANALYZER_EXTS.has(ext);
39
40
  }
40
41
 
42
+ function firstOverusedGoogleFont(text) {
43
+ return extractGoogleFontFamilies(text).find(f => OVERUSED_FONTS.has(f)) || '';
44
+ }
45
+
41
46
  function isNeutralBorderColor(str) {
42
47
  const m = str.match(/solid\s+((?:rgba?|hsla?|oklch|oklab|lab|lch|hwb|color)\([^)]*\)|#[0-9a-f]{3,8}\b|[a-z]+)/i);
43
48
  if (!m) return false;
@@ -88,9 +93,12 @@ const REGEX_MATCHERS = [
88
93
  { id: 'overused-font', regex: /font-family\s*:\s*['"]?(Inter|Roboto|Open Sans|Lato|Montserrat|Arial|Helvetica|Fraunces|Geist Sans|Geist Mono|Geist|Mona Sans|Plus Jakarta Sans|Space Grotesk|Recoleta|Instrument Sans|Instrument Serif)\b/gi,
89
94
  test: () => true,
90
95
  fmt: (m) => m[0] },
91
- { id: 'overused-font', regex: /fonts\.googleapis\.com\/css2?\?family=(Inter|Roboto|Open\+Sans|Lato|Montserrat|Fraunces|Plus\+Jakarta\+Sans|Space\+Grotesk|Instrument\+Sans|Instrument\+Serif|Mona\+Sans|Geist)\b/gi,
92
- test: () => true,
93
- fmt: (m) => `Google Fonts: ${m[1].replace(/\+/g, ' ')}` },
96
+ { id: 'overused-font', regex: /fonts\.googleapis\.com\/css2?\?[^"'\s)<>]*/gi,
97
+ test: (m) => {
98
+ m.overusedGoogleFont = firstOverusedGoogleFont(m[0]);
99
+ return Boolean(m.overusedGoogleFont);
100
+ },
101
+ fmt: (m) => `Google Fonts: ${m.overusedGoogleFont || firstOverusedGoogleFont(m[0])}` },
94
102
  // --- Gradient text ---
95
103
  { id: 'gradient-text', regex: /background-clip\s*:\s*text|-webkit-background-clip\s*:\s*text/gi,
96
104
  test: (m, line) => /gradient/i.test(line),
@@ -170,10 +178,7 @@ const REGEX_ANALYZERS = [
170
178
  if (f && !GENERIC_FONTS.has(f)) fonts.add(f);
171
179
  }
172
180
  }
173
- const gfRe = /fonts\.googleapis\.com\/css2?\?family=([^&"'\s]+)/gi;
174
- while ((m = gfRe.exec(content)) !== null) {
175
- for (const f of m[1].split('|').map(f => f.split(':')[0].replace(/\+/g, ' ').toLowerCase())) fonts.add(f);
176
- }
181
+ for (const f of extractGoogleFontFamilies(content)) fonts.add(f);
177
182
  if (fonts.size !== 1 || content.split('\n').length < 20) return [];
178
183
  const name = [...fonts][0];
179
184
  const lines = content.split('\n');
@@ -347,7 +352,7 @@ function extractStyleBlocks(content, ext) {
347
352
  ext = ext.toLowerCase();
348
353
  if (ext !== '.vue' && ext !== '.svelte') return [];
349
354
  const blocks = [];
350
- const re = /<style[^>]*>([\s\S]*?)<\/style[^>]*>/gi;
355
+ const re = /<style[^>]*>([\s\S]*?)<\/style\b[^>]*>/gi;
351
356
  let m;
352
357
  while ((m = re.exec(content)) !== null) {
353
358
  const before = content.substring(0, m.index);
@@ -21,6 +21,7 @@ const ANTIPATTERNS = [
21
21
  {
22
22
  id: 'overused-font',
23
23
  category: 'slop',
24
+ scopes: ['type'],
24
25
  name: 'Overused font',
25
26
  description:
26
27
  'Inter, Roboto, Fraunces, Geist, Plus Jakarta Sans, and Space Grotesk are used on so many sites they no longer feel distinctive. Each new wave of AI-generated UIs converges on the same handful of faces. Choose a face that gives your interface personality.',
@@ -30,6 +31,7 @@ const ANTIPATTERNS = [
30
31
  {
31
32
  id: 'single-font',
32
33
  category: 'slop',
34
+ scopes: ['type'],
33
35
  name: 'Single font for everything',
34
36
  description:
35
37
  'Only one font family is used for the entire page. Pair a distinctive display font with a refined body font to create typographic hierarchy.',
@@ -39,6 +41,7 @@ const ANTIPATTERNS = [
39
41
  {
40
42
  id: 'flat-type-hierarchy',
41
43
  category: 'slop',
44
+ scopes: ['type'],
42
45
  name: 'Flat type hierarchy',
43
46
  description:
44
47
  'Font sizes are too close together — no clear visual hierarchy. Use fewer sizes with more contrast (aim for at least a 1.25 ratio between steps).',
@@ -75,6 +78,7 @@ const ANTIPATTERNS = [
75
78
  {
76
79
  id: 'nested-cards',
77
80
  category: 'slop',
81
+ scopes: ['layout'],
78
82
  name: 'Nested cards',
79
83
  description:
80
84
  'Cards inside cards create visual noise and excessive depth. Flatten the hierarchy — use spacing, typography, and dividers instead of nesting containers.',
@@ -84,6 +88,7 @@ const ANTIPATTERNS = [
84
88
  {
85
89
  id: 'monotonous-spacing',
86
90
  category: 'slop',
91
+ scopes: ['layout'],
87
92
  name: 'Monotonous spacing',
88
93
  description:
89
94
  'The same spacing value used everywhere — no rhythm, no variation. Use tight groupings for related items and generous separations between sections.',
@@ -111,6 +116,7 @@ const ANTIPATTERNS = [
111
116
  {
112
117
  id: 'icon-tile-stack',
113
118
  category: 'slop',
119
+ scopes: ['layout'],
114
120
  name: 'Icon tile stacked above heading',
115
121
  description:
116
122
  'A small rounded-square icon container above a heading is the universal AI feature-card template — every generator outputs this exact shape. Try a side-by-side icon and heading, or let the icon sit in flow without its own container.',
@@ -120,6 +126,7 @@ const ANTIPATTERNS = [
120
126
  {
121
127
  id: 'italic-serif-display',
122
128
  category: 'slop',
129
+ scopes: ['type'],
123
130
  name: 'Italic serif display headline',
124
131
  description:
125
132
  'Oversized italic serif (Fraunces, Recoleta, Playfair, Newsreader-italic) as the primary hero headline reads as taste in isolation but has become the universal AI-startup landing page hero. Set roman, or move to a non-serif display face. Editorial / magazine register may legitimately want this — judge by context.',
@@ -129,6 +136,7 @@ const ANTIPATTERNS = [
129
136
  {
130
137
  id: 'hero-eyebrow-chip',
131
138
  category: 'slop',
139
+ scopes: ['type'],
132
140
  name: 'Hero eyebrow / pill chip',
133
141
  description:
134
142
  'A tiny uppercase letter-spaced label sitting immediately above an oversized hero headline — or the same shape rendered as a pill chip — is now the default AI SaaS hero. Drop the eyebrow, integrate the kicker into the headline, or run it as a navigation breadcrumb instead.',
@@ -138,6 +146,7 @@ const ANTIPATTERNS = [
138
146
  {
139
147
  id: 'repeated-section-kickers',
140
148
  category: 'slop',
149
+ scopes: ['type'],
141
150
  severity: 'advisory',
142
151
  name: 'Repeated section kicker labels',
143
152
  description:
@@ -148,6 +157,7 @@ const ANTIPATTERNS = [
148
157
  {
149
158
  id: 'numbered-section-markers',
150
159
  category: 'slop',
160
+ scopes: ['layout'],
151
161
  severity: 'advisory',
152
162
  name: 'Numbered section markers (01 / 02 / 03)',
153
163
  description:
@@ -185,6 +195,7 @@ const ANTIPATTERNS = [
185
195
  {
186
196
  id: 'oversized-h1',
187
197
  category: 'slop',
198
+ scopes: ['type'],
188
199
  name: 'Oversized hero headline',
189
200
  description:
190
201
  'A full-sentence headline set at display size ends up dominating the viewport, leaving no room for anything else above the fold. A punchy one- or two-word headline at that size is fine — the problem is a long headline blown up too large. Set long headlines smaller, or tighten the copy.',
@@ -194,6 +205,7 @@ const ANTIPATTERNS = [
194
205
  {
195
206
  id: 'extreme-negative-tracking',
196
207
  category: 'slop',
208
+ scopes: ['type'],
197
209
  name: 'Crushed letter spacing',
198
210
  description:
199
211
  'Letter-spacing pulled tighter than the point where characters keep their own shapes costs legibility. Tighten display type optically, not destructively.',
@@ -239,6 +251,7 @@ const ANTIPATTERNS = [
239
251
  {
240
252
  id: 'line-length',
241
253
  category: 'quality',
254
+ scopes: ['type', 'layout'],
242
255
  name: 'Line length too long',
243
256
  description:
244
257
  'Text lines wider than ~80 characters are hard to read. The eye loses its place tracking back to the start of the next line. Add a max-width (65ch to 75ch) to text containers.',
@@ -248,6 +261,7 @@ const ANTIPATTERNS = [
248
261
  {
249
262
  id: 'cramped-padding',
250
263
  category: 'quality',
264
+ scopes: ['layout'],
251
265
  name: 'Cramped padding',
252
266
  description:
253
267
  'Text is too close to the edge of its container. Two shapes: (1) an element with its own text where the padding is too low for the font size, and (2) a wrapper with text-bearing children and near-zero padding against a visible boundary (border, outline, or non-transparent background) — children land flush against the boundary line. Add at least 8px (ideally 12–16px) of padding inside bordered, outlined, or colored containers.',
@@ -257,6 +271,7 @@ const ANTIPATTERNS = [
257
271
  {
258
272
  id: 'body-text-viewport-edge',
259
273
  category: 'quality',
274
+ scopes: ['layout'],
260
275
  name: 'Body text touching viewport edge',
261
276
  description:
262
277
  'Body paragraphs render flush against the left or right viewport edge with no container providing horizontal padding. Wrap content in a container with at least 16px (ideally 24-32px) of horizontal padding, or apply max-width with mx-auto.',
@@ -264,6 +279,7 @@ const ANTIPATTERNS = [
264
279
  {
265
280
  id: 'tight-leading',
266
281
  category: 'quality',
282
+ scopes: ['type'],
267
283
  name: 'Tight line height',
268
284
  description:
269
285
  'Line height below 1.3x the font size makes multi-line text hard to read. Use 1.5 to 1.7 for body text so lines have room to breathe.',
@@ -271,6 +287,7 @@ const ANTIPATTERNS = [
271
287
  {
272
288
  id: 'skipped-heading',
273
289
  category: 'quality',
290
+ scopes: ['type'],
274
291
  name: 'Skipped heading level',
275
292
  description:
276
293
  'Heading levels should not skip (e.g. h1 then h3 with no h2). Screen readers use heading hierarchy for navigation. Skipping levels breaks the document outline.',
@@ -278,6 +295,7 @@ const ANTIPATTERNS = [
278
295
  {
279
296
  id: 'justified-text',
280
297
  category: 'quality',
298
+ scopes: ['type'],
281
299
  name: 'Justified text',
282
300
  description:
283
301
  'Justified text without hyphenation creates uneven word spacing ("rivers of white"). Use text-align: left for body text, or enable hyphens: auto if you must justify.',
@@ -285,6 +303,7 @@ const ANTIPATTERNS = [
285
303
  {
286
304
  id: 'tiny-text',
287
305
  category: 'quality',
306
+ scopes: ['type'],
288
307
  name: 'Tiny body text',
289
308
  description:
290
309
  'Body text below 12px is hard to read, especially on high-DPI screens. Use at least 14px for body content, 16px is ideal.',
@@ -292,6 +311,7 @@ const ANTIPATTERNS = [
292
311
  {
293
312
  id: 'all-caps-body',
294
313
  category: 'quality',
314
+ scopes: ['type'],
295
315
  name: 'All-caps body text',
296
316
  description:
297
317
  'Long passages in uppercase are hard to read. We recognize words by shape (ascenders and descenders), which all-caps removes. Reserve uppercase for short labels and headings.',
@@ -301,6 +321,7 @@ const ANTIPATTERNS = [
301
321
  {
302
322
  id: 'wide-tracking',
303
323
  category: 'quality',
324
+ scopes: ['type'],
304
325
  name: 'Wide letter spacing on body text',
305
326
  description:
306
327
  'Letter spacing above 0.05em on body text disrupts natural character groupings and slows reading. Reserve wide tracking for short uppercase labels only.',
@@ -308,6 +329,7 @@ const ANTIPATTERNS = [
308
329
  {
309
330
  id: 'text-overflow',
310
331
  category: 'quality',
332
+ scopes: ['layout'],
311
333
  name: 'Content overflowing its container',
312
334
  description:
313
335
  'Content renders wider than its container, spilling out or forcing a horizontal scrollbar. Let text wrap, constrain widths, or give the region a deliberate scroll affordance.',
@@ -317,6 +339,7 @@ const ANTIPATTERNS = [
317
339
  {
318
340
  id: 'clipped-overflow-container',
319
341
  category: 'quality',
342
+ scopes: ['layout'],
320
343
  name: 'Positioned child clipped by overflow container',
321
344
  description:
322
345
  'A clipping container (overflow hidden or clip) wrapping an absolutely-positioned child cuts off tooltips, menus, and popovers that need to escape. Let the overflow be visible, or move the positioned layer out of the clip.',
@@ -326,6 +349,7 @@ const ANTIPATTERNS = [
326
349
  {
327
350
  id: 'design-system-font',
328
351
  category: 'quality',
352
+ scopes: ['type'],
329
353
  name: 'Font outside DESIGN.md',
330
354
  description:
331
355
  'A font is used that is not declared in DESIGN.md typography. Use the documented type system or update DESIGN.md if this is an intentional brand addition.',
@@ -352,6 +376,17 @@ const ANTIPATTERNS = [
352
376
  skillSection: 'Visual Details',
353
377
  skillGuideline: 'border radius outside the project design system',
354
378
  },
379
+ {
380
+ id: 'design-system-font-size',
381
+ category: 'quality',
382
+ severity: 'advisory',
383
+ scopes: ['type'],
384
+ name: 'Font size outside DESIGN.md',
385
+ description:
386
+ 'A literal font-size is off the type ramp documented in DESIGN.md typography. Use a documented size step or update the design system if the new step is intentional.',
387
+ skillSection: 'Typography',
388
+ skillGuideline: 'font size outside the project design system',
389
+ },
355
390
 
356
391
  // ── Provider tells: opt-in via --gpt / --gemini (gated off by default) ──
357
392
  {
@@ -376,6 +411,17 @@ const ANTIPATTERNS = [
376
411
  skillSection: 'Visual Details',
377
412
  skillGuideline: 'repeating-gradient decorative stripes',
378
413
  },
414
+ {
415
+ id: 'codex-grid-background',
416
+ category: 'slop',
417
+ severity: 'advisory',
418
+ gated: 'gpt',
419
+ name: 'Decorative grid-line background',
420
+ description:
421
+ 'A two-axis grid drawn with hairline linear-gradient layers ("1px, transparent 1px" on both axes) is a recurring generated-UI signature. Reserve grid overlays for actual canvas, map, blueprint, or measurement surfaces; elsewhere use product structure or a plain surface.',
422
+ skillSection: 'Visual Details',
423
+ skillGuideline: 'two-axis grid-line gradient background',
424
+ },
379
425
  {
380
426
  id: 'theater-slop-phrase',
381
427
  category: 'slop',
@@ -437,12 +483,32 @@ function filterByProviders(findings, providers = []) {
437
483
  });
438
484
  }
439
485
 
486
+
487
+ // Set of scope tags rules can declare (e.g. 'type', 'layout'). Used by the
488
+ // CLI --scope flag to narrow output to one design domain.
489
+ const RULE_SCOPES = new Set(
490
+ ANTIPATTERNS.flatMap(rule => rule.scopes || []),
491
+ );
492
+
493
+ // Keep only findings whose rule declares at least one of the requested
494
+ // scopes. An empty scope list means no filtering (default CLI behavior).
495
+ function filterByScopes(findings, scopes = []) {
496
+ if (!scopes || scopes.length === 0) return findings;
497
+ const enabled = new Set(scopes);
498
+ return findings.filter(f => {
499
+ const rule = getAntipattern(f.antipattern);
500
+ return (rule?.scopes || []).some(scope => enabled.has(scope));
501
+ });
502
+ }
503
+
440
504
  export {
441
505
  ANTIPATTERNS,
506
+ RULE_SCOPES,
442
507
  RULE_ENGINE_SUPPORT,
443
508
  GATED_PROVIDERS,
444
509
  getAntipattern,
445
510
  getRulesForCategory,
446
511
  getRuleEngineSupport,
447
512
  filterByProviders,
513
+ filterByScopes,
448
514
  };