@bastani/atomic 0.9.11-alpha.6 → 0.9.11-alpha.8

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 (452) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +3 -5
  3. package/dist/builtin/intercom/package.json +1 -1
  4. package/dist/builtin/mcp/package.json +1 -1
  5. package/dist/builtin/mcp/sampling-handler.ts +1 -5
  6. package/dist/builtin/subagents/package.json +1 -1
  7. package/dist/builtin/web-access/package.json +1 -1
  8. package/dist/builtin/workflows/CHANGELOG.md +1 -0
  9. package/dist/builtin/workflows/README.md +1 -1
  10. package/dist/builtin/workflows/package.json +1 -1
  11. package/dist/builtin/workflows/skills/impeccable/SKILL.md +33 -129
  12. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_asset_producer.toml +11 -3
  13. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_documenter.toml +26 -0
  14. package/dist/builtin/workflows/skills/impeccable/agents/impeccable_finish_reviewer.toml +35 -0
  15. package/dist/builtin/workflows/skills/impeccable/reference/android.md +1 -1
  16. package/dist/builtin/workflows/skills/impeccable/reference/animate.md +72 -189
  17. package/dist/builtin/workflows/skills/impeccable/reference/audit.md +10 -9
  18. package/dist/builtin/workflows/skills/impeccable/reference/audit.native.md +2 -2
  19. package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +19 -108
  20. package/dist/builtin/workflows/skills/impeccable/reference/clarify.md +59 -253
  21. package/dist/builtin/workflows/skills/impeccable/reference/colorize.md +51 -222
  22. package/dist/builtin/workflows/skills/impeccable/reference/craft-floor.md +45 -0
  23. package/dist/builtin/workflows/skills/impeccable/reference/craft.md +3 -121
  24. package/dist/builtin/workflows/skills/impeccable/reference/critique.md +28 -20
  25. package/dist/builtin/workflows/skills/impeccable/reference/degraded/asset-producer.md +97 -0
  26. package/dist/builtin/workflows/skills/impeccable/reference/degraded/documenter.md +23 -0
  27. package/dist/builtin/workflows/skills/impeccable/reference/degraded/finish-reviewer.md +32 -0
  28. package/dist/builtin/workflows/skills/impeccable/reference/degraded/manual-edit-applier.md +92 -0
  29. package/dist/builtin/workflows/skills/impeccable/reference/delight.md +47 -279
  30. package/dist/builtin/workflows/skills/impeccable/reference/distill.md +2 -2
  31. package/dist/builtin/workflows/skills/impeccable/reference/doctor.md +53 -0
  32. package/dist/builtin/workflows/skills/impeccable/reference/document.md +60 -73
  33. package/dist/builtin/workflows/skills/impeccable/reference/harden.md +1 -12
  34. package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +17 -4
  35. package/dist/builtin/workflows/skills/impeccable/reference/init.md +64 -163
  36. package/dist/builtin/workflows/skills/impeccable/reference/ios.md +1 -1
  37. package/dist/builtin/workflows/skills/impeccable/reference/layout.md +52 -153
  38. package/dist/builtin/workflows/skills/impeccable/reference/live.md +44 -32
  39. package/dist/builtin/workflows/skills/impeccable/reference/new-work.md +105 -0
  40. package/dist/builtin/workflows/skills/impeccable/reference/{product.md → operate.md} +6 -5
  41. package/dist/builtin/workflows/skills/impeccable/reference/optimize.md +4 -4
  42. package/dist/builtin/workflows/skills/impeccable/reference/overdrive.md +1 -4
  43. package/dist/builtin/workflows/skills/impeccable/reference/polish.md +68 -212
  44. package/dist/builtin/workflows/skills/impeccable/reference/quieter.md +3 -3
  45. package/dist/builtin/workflows/skills/impeccable/reference/routing.md +18 -0
  46. package/dist/builtin/workflows/skills/impeccable/reference/shape.md +38 -144
  47. package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +48 -269
  48. package/dist/builtin/workflows/skills/impeccable/reference/visualize.md +38 -0
  49. package/dist/builtin/workflows/skills/impeccable/scripts/command-metadata.json +1 -1
  50. package/dist/builtin/workflows/skills/impeccable/scripts/concept-seed.mjs +584 -0
  51. package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +117 -9
  52. package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +486 -59
  53. package/dist/builtin/workflows/skills/impeccable/scripts/critique-storage.mjs +16 -45
  54. package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +96 -10
  55. package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +143 -26
  56. package/dist/builtin/workflows/skills/impeccable/scripts/detector/design-system.mjs +181 -12
  57. package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +3187 -182
  58. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs +102 -7
  59. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +282 -70
  60. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +183 -15
  61. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs +22 -7
  62. package/dist/builtin/workflows/skills/impeccable/scripts/detector/findings.mjs +7 -1
  63. package/dist/builtin/workflows/skills/impeccable/scripts/detector/node/file-system.mjs +16 -2
  64. package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +155 -42
  65. package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +2988 -155
  66. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/constants.mjs +11 -0
  67. package/dist/builtin/workflows/skills/impeccable/scripts/doctor.mjs +336 -0
  68. package/dist/builtin/workflows/skills/impeccable/scripts/generate-image.mjs +232 -0
  69. package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +90 -10
  70. package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +410 -78
  71. package/dist/builtin/workflows/skills/impeccable/scripts/hook.mjs +25 -8
  72. package/dist/builtin/workflows/skills/impeccable/scripts/lib/artifact-schema.mjs +93 -0
  73. package/dist/builtin/workflows/skills/impeccable/scripts/lib/composition-catalog.mjs +165 -0
  74. package/dist/builtin/workflows/skills/impeccable/scripts/lib/concept-catalog.mjs +329 -0
  75. package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-config.mjs +20 -5
  76. package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-paths.mjs +16 -8
  77. package/dist/builtin/workflows/skills/impeccable/scripts/lib/provider.mjs +1 -0
  78. package/dist/builtin/workflows/skills/impeccable/scripts/lib/staleness-deep.mjs +455 -0
  79. package/dist/builtin/workflows/skills/impeccable/scripts/lib/staleness-notice.mjs +169 -0
  80. package/dist/builtin/workflows/skills/impeccable/scripts/lib/staleness.mjs +457 -0
  81. package/dist/builtin/workflows/skills/impeccable/scripts/lib/surface-briefs.mjs +151 -0
  82. package/dist/builtin/workflows/skills/impeccable/scripts/lib/target-slug.mjs +33 -0
  83. package/dist/builtin/workflows/skills/impeccable/scripts/lib/template-extensions.mjs +146 -0
  84. package/dist/builtin/workflows/skills/impeccable/scripts/live/completion.mjs +10 -1
  85. package/dist/builtin/workflows/skills/impeccable/scripts/live/event-validation.mjs +15 -0
  86. package/dist/builtin/workflows/skills/impeccable/scripts/live/generation-preflight.mjs +149 -0
  87. package/dist/builtin/workflows/skills/impeccable/scripts/live/poll-lanes.mjs +14 -0
  88. package/dist/builtin/workflows/skills/impeccable/scripts/live/session-store.mjs +109 -32
  89. package/dist/builtin/workflows/skills/impeccable/scripts/live/source-lock.mjs +105 -0
  90. package/dist/builtin/workflows/skills/impeccable/scripts/live/source-search.mjs +105 -0
  91. package/dist/builtin/workflows/skills/impeccable/scripts/live/sveltekit-adapter.mjs +8 -6
  92. package/dist/builtin/workflows/skills/impeccable/scripts/live/tanstack-adapter.mjs +280 -0
  93. package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +208 -68
  94. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +563 -112
  95. package/dist/builtin/workflows/skills/impeccable/scripts/live-commit-manual-edits.mjs +3 -0
  96. package/dist/builtin/workflows/skills/impeccable/scripts/live-inject.mjs +198 -13
  97. package/dist/builtin/workflows/skills/impeccable/scripts/live-insert.mjs +24 -6
  98. package/dist/builtin/workflows/skills/impeccable/scripts/live-manual-edit-evidence.mjs +6 -1
  99. package/dist/builtin/workflows/skills/impeccable/scripts/live-poll.mjs +44 -14
  100. package/dist/builtin/workflows/skills/impeccable/scripts/live-server.mjs +398 -33
  101. package/dist/builtin/workflows/skills/impeccable/scripts/live-status.mjs +9 -5
  102. package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +81 -67
  103. package/dist/builtin/workflows/skills/impeccable/scripts/live.mjs +7 -2
  104. package/dist/builtin/workflows/skills/impeccable/scripts/palette.mjs +76 -81
  105. package/dist/builtin/workflows/skills/impeccable/scripts/pin.mjs +2 -2
  106. package/dist/builtin/workflows/skills/impeccable/scripts/serve-question.mjs +890 -0
  107. package/dist/builtin/workflows/skills/impeccable/scripts/surface-brief.mjs +74 -0
  108. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +1 -24
  109. package/dist/builtin/workflows/src/extension/index.bundle.mjs +232 -50
  110. package/dist/builtin/workflows/src/extension/workflow-model-catalog.ts +26 -0
  111. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +3 -2
  112. package/dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts +23 -9
  113. package/dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts +1 -0
  114. package/dist/builtin/workflows/src/runs/foreground/postmortem-stage-chat.ts +20 -5
  115. package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +10 -0
  116. package/dist/builtin/workflows/src/runs/foreground/stage-delivery-activity.ts +86 -0
  117. package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +6 -2
  118. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +24 -18
  119. package/dist/builtin/workflows/src/runs/foreground/stage-runner-send-user-message.ts +8 -0
  120. package/dist/builtin/workflows/src/runs/foreground/stage-runner-session-options.ts +3 -3
  121. package/dist/builtin/workflows/src/runs/foreground/stage-runner-session.ts +2 -2
  122. package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +16 -0
  123. package/dist/builtin/workflows/src/tui/stage-chat-view-delivery-activity.ts +121 -0
  124. package/dist/builtin/workflows/src/tui/stage-chat-view-live-events.ts +42 -0
  125. package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +16 -0
  126. package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +4 -0
  127. package/dist/cli/list-models.d.ts +2 -2
  128. package/dist/cli/list-models.d.ts.map +1 -1
  129. package/dist/cli/list-models.js +5 -5
  130. package/dist/cli/list-models.js.map +1 -1
  131. package/dist/core/agent-session-accessors.js +1 -1
  132. package/dist/core/agent-session-accessors.js.map +1 -1
  133. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  134. package/dist/core/agent-session-auto-compaction.js +2 -5
  135. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  136. package/dist/core/agent-session-compaction.js +1 -1
  137. package/dist/core/agent-session-compaction.js.map +1 -1
  138. package/dist/core/agent-session-extension-bindings.js +5 -5
  139. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  140. package/dist/core/agent-session-methods.d.ts +4 -4
  141. package/dist/core/agent-session-methods.d.ts.map +1 -1
  142. package/dist/core/agent-session-methods.js.map +1 -1
  143. package/dist/core/agent-session-models.d.ts +1 -1
  144. package/dist/core/agent-session-models.d.ts.map +1 -1
  145. package/dist/core/agent-session-models.js +18 -14
  146. package/dist/core/agent-session-models.js.map +1 -1
  147. package/dist/core/agent-session-post-tool-compaction.d.ts.map +1 -1
  148. package/dist/core/agent-session-post-tool-compaction.js +2 -4
  149. package/dist/core/agent-session-post-tool-compaction.js.map +1 -1
  150. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  151. package/dist/core/agent-session-prompt.js +3 -7
  152. package/dist/core/agent-session-prompt.js.map +1 -1
  153. package/dist/core/agent-session-retry.js +1 -1
  154. package/dist/core/agent-session-retry.js.map +1 -1
  155. package/dist/core/agent-session-runtime-auth.d.ts +3 -3
  156. package/dist/core/agent-session-runtime-auth.d.ts.map +1 -1
  157. package/dist/core/agent-session-runtime-auth.js +4 -14
  158. package/dist/core/agent-session-runtime-auth.js.map +1 -1
  159. package/dist/core/agent-session-runtime.d.ts +1 -1
  160. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  161. package/dist/core/agent-session-runtime.js +3 -3
  162. package/dist/core/agent-session-runtime.js.map +1 -1
  163. package/dist/core/agent-session-services.d.ts +3 -8
  164. package/dist/core/agent-session-services.d.ts.map +1 -1
  165. package/dist/core/agent-session-services.js +16 -23
  166. package/dist/core/agent-session-services.js.map +1 -1
  167. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  168. package/dist/core/agent-session-tool-registry.js +2 -1
  169. package/dist/core/agent-session-tool-registry.js.map +1 -1
  170. package/dist/core/agent-session-types.d.ts +2 -2
  171. package/dist/core/agent-session-types.d.ts.map +1 -1
  172. package/dist/core/agent-session-types.js.map +1 -1
  173. package/dist/core/agent-session.d.ts +2 -2
  174. package/dist/core/agent-session.d.ts.map +1 -1
  175. package/dist/core/agent-session.js +1 -1
  176. package/dist/core/agent-session.js.map +1 -1
  177. package/dist/core/auth-storage-backends.d.ts +1 -0
  178. package/dist/core/auth-storage-backends.d.ts.map +1 -1
  179. package/dist/core/auth-storage-backends.js +18 -4
  180. package/dist/core/auth-storage-backends.js.map +1 -1
  181. package/dist/core/auth-storage.d.ts +12 -139
  182. package/dist/core/auth-storage.d.ts.map +1 -1
  183. package/dist/core/auth-storage.js +68 -374
  184. package/dist/core/auth-storage.js.map +1 -1
  185. package/dist/core/copilot-env-routing.d.ts +36 -0
  186. package/dist/core/copilot-env-routing.d.ts.map +1 -0
  187. package/dist/core/copilot-env-routing.js +94 -0
  188. package/dist/core/copilot-env-routing.js.map +1 -0
  189. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  190. package/dist/core/extensions/loader-virtual-modules.js +10 -2
  191. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  192. package/dist/core/extensions/provider-types.d.ts +0 -40
  193. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  194. package/dist/core/extensions/provider-types.js.map +1 -1
  195. package/dist/core/fallback-models.d.ts +4 -4
  196. package/dist/core/fallback-models.d.ts.map +1 -1
  197. package/dist/core/fallback-models.js +3 -3
  198. package/dist/core/fallback-models.js.map +1 -1
  199. package/dist/core/model-config.d.ts +542 -0
  200. package/dist/core/model-config.d.ts.map +1 -0
  201. package/dist/core/{model-registry-schemas.js → model-config.js} +85 -34
  202. package/dist/core/model-config.js.map +1 -0
  203. package/dist/core/model-registry.d.ts +25 -85
  204. package/dist/core/model-registry.d.ts.map +1 -1
  205. package/dist/core/model-registry.js +65 -388
  206. package/dist/core/model-registry.js.map +1 -1
  207. package/dist/core/model-resolver-cli.d.ts +2 -2
  208. package/dist/core/model-resolver-cli.d.ts.map +1 -1
  209. package/dist/core/model-resolver-cli.js +2 -2
  210. package/dist/core/model-resolver-cli.js.map +1 -1
  211. package/dist/core/model-resolver-initial.d.ts +4 -4
  212. package/dist/core/model-resolver-initial.d.ts.map +1 -1
  213. package/dist/core/model-resolver-initial.js +17 -17
  214. package/dist/core/model-resolver-initial.js.map +1 -1
  215. package/dist/core/model-resolver-scope.d.ts +3 -3
  216. package/dist/core/model-resolver-scope.d.ts.map +1 -1
  217. package/dist/core/model-resolver-scope.js +4 -4
  218. package/dist/core/model-resolver-scope.js.map +1 -1
  219. package/dist/core/model-runtime-auth.d.ts +7 -0
  220. package/dist/core/model-runtime-auth.d.ts.map +1 -0
  221. package/dist/core/model-runtime-auth.js +14 -0
  222. package/dist/core/model-runtime-auth.js.map +1 -0
  223. package/dist/core/model-runtime-providers.d.ts +6 -0
  224. package/dist/core/model-runtime-providers.d.ts.map +1 -0
  225. package/dist/core/model-runtime-providers.js +22 -0
  226. package/dist/core/model-runtime-providers.js.map +1 -0
  227. package/dist/core/model-runtime-restoration.d.ts +6 -0
  228. package/dist/core/model-runtime-restoration.d.ts.map +1 -0
  229. package/dist/core/model-runtime-restoration.js +21 -0
  230. package/dist/core/model-runtime-restoration.js.map +1 -0
  231. package/dist/core/model-runtime-snapshot.d.ts +16 -0
  232. package/dist/core/model-runtime-snapshot.d.ts.map +1 -0
  233. package/dist/core/model-runtime-snapshot.js +52 -0
  234. package/dist/core/model-runtime-snapshot.js.map +1 -0
  235. package/dist/core/model-runtime-streaming.d.ts +17 -0
  236. package/dist/core/model-runtime-streaming.d.ts.map +1 -0
  237. package/dist/core/model-runtime-streaming.js +66 -0
  238. package/dist/core/model-runtime-streaming.js.map +1 -0
  239. package/dist/core/model-runtime-types.d.ts +21 -0
  240. package/dist/core/model-runtime-types.d.ts.map +1 -0
  241. package/dist/core/model-runtime-types.js +2 -0
  242. package/dist/core/model-runtime-types.js.map +1 -0
  243. package/dist/core/model-runtime.d.ts +50 -29
  244. package/dist/core/model-runtime.d.ts.map +1 -1
  245. package/dist/core/model-runtime.js +330 -90
  246. package/dist/core/model-runtime.js.map +1 -1
  247. package/dist/core/models-store.d.ts +2 -10
  248. package/dist/core/models-store.d.ts.map +1 -1
  249. package/dist/core/models-store.js +2 -29
  250. package/dist/core/models-store.js.map +1 -1
  251. package/dist/core/oauth-login.d.ts +24 -0
  252. package/dist/core/oauth-login.d.ts.map +1 -0
  253. package/dist/core/oauth-login.js +87 -0
  254. package/dist/core/oauth-login.js.map +1 -0
  255. package/dist/core/oauth-provider-metadata.d.ts +5 -0
  256. package/dist/core/oauth-provider-metadata.d.ts.map +1 -0
  257. package/dist/core/oauth-provider-metadata.js +19 -0
  258. package/dist/core/oauth-provider-metadata.js.map +1 -0
  259. package/dist/core/provider-composer-internal.d.ts +53 -0
  260. package/dist/core/provider-composer-internal.d.ts.map +1 -0
  261. package/dist/core/provider-composer-internal.js +273 -0
  262. package/dist/core/provider-composer-internal.js.map +1 -0
  263. package/dist/core/provider-composer.d.ts +16 -0
  264. package/dist/core/provider-composer.d.ts.map +1 -0
  265. package/dist/core/provider-composer.js +108 -0
  266. package/dist/core/provider-composer.js.map +1 -0
  267. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  268. package/dist/core/remote-catalog-provider.js +74 -122
  269. package/dist/core/remote-catalog-provider.js.map +1 -1
  270. package/dist/core/resolve-config-value.d.ts +8 -7
  271. package/dist/core/resolve-config-value.d.ts.map +1 -1
  272. package/dist/core/resolve-config-value.js +26 -23
  273. package/dist/core/resolve-config-value.js.map +1 -1
  274. package/dist/core/runtime-credentials.d.ts +16 -0
  275. package/dist/core/runtime-credentials.d.ts.map +1 -0
  276. package/dist/core/runtime-credentials.js +42 -0
  277. package/dist/core/runtime-credentials.js.map +1 -0
  278. package/dist/core/sdk-types.d.ts +1 -7
  279. package/dist/core/sdk-types.d.ts.map +1 -1
  280. package/dist/core/sdk-types.js.map +1 -1
  281. package/dist/core/sdk.d.ts.map +1 -1
  282. package/dist/core/sdk.js +27 -28
  283. package/dist/core/sdk.js.map +1 -1
  284. package/dist/extensions/llama/index.js +1 -1
  285. package/dist/extensions/llama/index.js.map +1 -1
  286. package/dist/extensions/llama/provider.d.ts +2 -4
  287. package/dist/extensions/llama/provider.d.ts.map +1 -1
  288. package/dist/extensions/llama/provider.js +25 -17
  289. package/dist/extensions/llama/provider.js.map +1 -1
  290. package/dist/index.d.ts +2 -3
  291. package/dist/index.d.ts.map +1 -1
  292. package/dist/index.js +3 -4
  293. package/dist/index.js.map +1 -1
  294. package/dist/main-runtime-api-key.d.ts +6 -0
  295. package/dist/main-runtime-api-key.d.ts.map +1 -0
  296. package/dist/main-runtime-api-key.js +6 -0
  297. package/dist/main-runtime-api-key.js.map +1 -0
  298. package/dist/main-session-options.d.ts +2 -2
  299. package/dist/main-session-options.d.ts.map +1 -1
  300. package/dist/main-session-options.js +3 -3
  301. package/dist/main-session-options.js.map +1 -1
  302. package/dist/main.d.ts.map +1 -1
  303. package/dist/main.js +9 -11
  304. package/dist/main.js.map +1 -1
  305. package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
  306. package/dist/modes/interactive/components/chat-session-host-actions.js +2 -14
  307. package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
  308. package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
  309. package/dist/modes/interactive/components/chat-session-host-events.js +9 -0
  310. package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
  311. package/dist/modes/interactive/components/chat-session-host-runtime.d.ts +25 -0
  312. package/dist/modes/interactive/components/chat-session-host-runtime.d.ts.map +1 -1
  313. package/dist/modes/interactive/components/chat-session-host-runtime.js +53 -0
  314. package/dist/modes/interactive/components/chat-session-host-runtime.js.map +1 -1
  315. package/dist/modes/interactive/components/chat-session-host.d.ts +13 -0
  316. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  317. package/dist/modes/interactive/components/chat-session-host.js +22 -1
  318. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  319. package/dist/modes/interactive/components/footer.js +1 -1
  320. package/dist/modes/interactive/components/footer.js.map +1 -1
  321. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  322. package/dist/modes/interactive/components/login-dialog.js +1 -3
  323. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  324. package/dist/modes/interactive/components/model-selector.d.ts +4 -3
  325. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  326. package/dist/modes/interactive/components/model-selector.js +56 -73
  327. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  328. package/dist/modes/interactive/components/oauth-selector.d.ts +4 -3
  329. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  330. package/dist/modes/interactive/components/oauth-selector.js +15 -24
  331. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  332. package/dist/modes/interactive/interactive-agent-events.js +10 -4
  333. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  334. package/dist/modes/interactive/interactive-auth-login.js +20 -31
  335. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  336. package/dist/modes/interactive/interactive-auth-routing.d.ts +1 -1
  337. package/dist/modes/interactive/interactive-auth-routing.d.ts.map +1 -1
  338. package/dist/modes/interactive/interactive-auth-routing.js +21 -47
  339. package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
  340. package/dist/modes/interactive/interactive-autocomplete.js +3 -3
  341. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  342. package/dist/modes/interactive/interactive-deferred-startup.js +8 -8
  343. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  344. package/dist/modes/interactive/interactive-extension-runtime.js +2 -1
  345. package/dist/modes/interactive/interactive-extension-runtime.js.map +1 -1
  346. package/dist/modes/interactive/interactive-model-catalog-startup.js +2 -2
  347. package/dist/modes/interactive/interactive-model-catalog-startup.js.map +1 -1
  348. package/dist/modes/interactive/interactive-model-routing.js +11 -11
  349. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  350. package/dist/modes/interactive/interactive-render-chat.js +1 -1
  351. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  352. package/dist/modes/interactive/interactive-slash-commands.js +2 -2
  353. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  354. package/dist/modes/interactive/interactive-startup.js +1 -1
  355. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  356. package/dist/modes/interactive-engine/isolated-auth.d.ts +2 -2
  357. package/dist/modes/interactive-engine/isolated-auth.d.ts.map +1 -1
  358. package/dist/modes/interactive-engine/isolated-auth.js +4 -3
  359. package/dist/modes/interactive-engine/isolated-auth.js.map +1 -1
  360. package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
  361. package/dist/modes/interactive-engine/isolated-runtime.js +4 -3
  362. package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
  363. package/dist/modes/interactive-engine/remote-model-catalog.d.ts +0 -1
  364. package/dist/modes/interactive-engine/remote-model-catalog.d.ts.map +1 -1
  365. package/dist/modes/interactive-engine/remote-model-catalog.js +11 -50
  366. package/dist/modes/interactive-engine/remote-model-catalog.js.map +1 -1
  367. package/dist/modes/rpc/rpc-client-api.d.ts +2 -2
  368. package/dist/modes/rpc/rpc-client-api.d.ts.map +1 -1
  369. package/dist/modes/rpc/rpc-client-api.js.map +1 -1
  370. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  371. package/dist/modes/rpc/rpc-command-handler.js +26 -19
  372. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  373. package/dist/modes/rpc/rpc-oauth-client.d.ts +1 -1
  374. package/dist/modes/rpc/rpc-oauth-client.d.ts.map +1 -1
  375. package/dist/modes/rpc/rpc-oauth-client.js +1 -1
  376. package/dist/modes/rpc/rpc-oauth-client.js.map +1 -1
  377. package/dist/modes/rpc/rpc-oauth-interaction.d.ts +1 -1
  378. package/dist/modes/rpc/rpc-oauth-interaction.d.ts.map +1 -1
  379. package/dist/modes/rpc/rpc-oauth-interaction.js +1 -1
  380. package/dist/modes/rpc/rpc-oauth-interaction.js.map +1 -1
  381. package/dist/modes/rpc/rpc-provider-auth.d.ts +4 -5
  382. package/dist/modes/rpc/rpc-provider-auth.d.ts.map +1 -1
  383. package/dist/modes/rpc/rpc-provider-auth.js +19 -66
  384. package/dist/modes/rpc/rpc-provider-auth.js.map +1 -1
  385. package/dist/modes/rpc/rpc-session-binding.js +1 -1
  386. package/dist/modes/rpc/rpc-session-binding.js.map +1 -1
  387. package/dist/modes/rpc/rpc-types.d.ts +7 -4
  388. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  389. package/dist/modes/rpc/rpc-types.js.map +1 -1
  390. package/dist/package-manager-cli.d.ts.map +1 -1
  391. package/dist/package-manager-cli.js +5 -7
  392. package/dist/package-manager-cli.js.map +1 -1
  393. package/docs/changelog.mdx +1 -1
  394. package/docs/custom-provider.md +1 -1
  395. package/docs/models.md +4 -6
  396. package/docs/providers.md +13 -0
  397. package/docs/quickstart.md +2 -1
  398. package/docs/sdk.md +32 -49
  399. package/docs/tui.md +7 -2
  400. package/docs/workflows.md +4 -4
  401. package/examples/sdk/02-custom-model.ts +8 -10
  402. package/examples/sdk/09-api-keys-and-oauth.ts +17 -23
  403. package/examples/sdk/12-full-control.ts +9 -11
  404. package/examples/sdk/README.md +17 -21
  405. package/npm-shrinkwrap.json +23 -23
  406. package/package.json +2 -2
  407. package/dist/builtin/workflows/skills/impeccable/reference/brand.md +0 -108
  408. package/dist/builtin/workflows/skills/impeccable/reference/codex.md +0 -105
  409. package/dist/builtin/workflows/skills/impeccable/reference/interaction-design.md +0 -189
  410. package/dist/core/model-registry-auth.d.ts +0 -10
  411. package/dist/core/model-registry-auth.d.ts.map +0 -1
  412. package/dist/core/model-registry-auth.js +0 -98
  413. package/dist/core/model-registry-auth.js.map +0 -1
  414. package/dist/core/model-registry-builtins.d.ts +0 -8
  415. package/dist/core/model-registry-builtins.d.ts.map +0 -1
  416. package/dist/core/model-registry-builtins.js +0 -104
  417. package/dist/core/model-registry-builtins.js.map +0 -1
  418. package/dist/core/model-registry-custom-loader.d.ts +0 -3
  419. package/dist/core/model-registry-custom-loader.d.ts.map +0 -1
  420. package/dist/core/model-registry-custom-loader.js +0 -255
  421. package/dist/core/model-registry-custom-loader.js.map +0 -1
  422. package/dist/core/model-registry-dynamic.d.ts +0 -7
  423. package/dist/core/model-registry-dynamic.d.ts.map +0 -1
  424. package/dist/core/model-registry-dynamic.js +0 -189
  425. package/dist/core/model-registry-dynamic.js.map +0 -1
  426. package/dist/core/model-registry-extension-refresh.d.ts +0 -23
  427. package/dist/core/model-registry-extension-refresh.d.ts.map +0 -1
  428. package/dist/core/model-registry-extension-refresh.js +0 -32
  429. package/dist/core/model-registry-extension-refresh.js.map +0 -1
  430. package/dist/core/model-registry-loader.d.ts +0 -5
  431. package/dist/core/model-registry-loader.d.ts.map +0 -1
  432. package/dist/core/model-registry-loader.js +0 -29
  433. package/dist/core/model-registry-loader.js.map +0 -1
  434. package/dist/core/model-registry-schemas.d.ts +0 -1399
  435. package/dist/core/model-registry-schemas.d.ts.map +0 -1
  436. package/dist/core/model-registry-schemas.js.map +0 -1
  437. package/dist/core/model-registry-types.d.ts +0 -91
  438. package/dist/core/model-registry-types.d.ts.map +0 -1
  439. package/dist/core/model-registry-types.js +0 -2
  440. package/dist/core/model-registry-types.js.map +0 -1
  441. package/dist/core/model-registry-validation.d.ts +0 -7
  442. package/dist/core/model-registry-validation.d.ts.map +0 -1
  443. package/dist/core/model-registry-validation.js +0 -12
  444. package/dist/core/model-registry-validation.js.map +0 -1
  445. package/dist/core/oauth-compat.d.ts +0 -17
  446. package/dist/core/oauth-compat.d.ts.map +0 -1
  447. package/dist/core/oauth-compat.js +0 -2
  448. package/dist/core/oauth-compat.js.map +0 -1
  449. package/dist/core/oauth-provider-bridge.d.ts +0 -63
  450. package/dist/core/oauth-provider-bridge.d.ts.map +0 -1
  451. package/dist/core/oauth-provider-bridge.js +0 -232
  452. package/dist/core/oauth-provider-bridge.js.map +0 -1
@@ -2,7 +2,7 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
 
4
4
  import { profileStep, recordProfileEvent } from '../../profile/profiler.mjs';
5
- import { parseAnyColor, resolveLengthPx, resolveVarRefs } from '../../rules/checks.mjs';
5
+ import { CSS_NAMED_COLORS, collectCssCustomProps, cssLengthToPx, parseAnyColor, resolveLengthPx, resolveVarRefs } from '../../rules/checks.mjs';
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
8
  // jsdom CSS-variable border override map
@@ -223,7 +223,7 @@ function unwrapCssAtLayer(source) {
223
223
  // ---------------------------------------------------------------------------
224
224
 
225
225
  const STATIC_INHERITED_PROPS = new Set([
226
- 'color', 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight',
226
+ 'color', 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight', 'fontVariant',
227
227
  'lineHeight', 'letterSpacing', 'textTransform', 'textAlign', 'hyphens',
228
228
  'webkitHyphens',
229
229
  ]);
@@ -245,9 +245,14 @@ const STATIC_DEFAULT_STYLE = {
245
245
  outlineColor: 'rgb(0, 0, 0)',
246
246
  outlineStyle: 'none',
247
247
  boxShadow: 'none',
248
+ // NOT in STATIC_INHERITED_PROPS even though text-shadow inherits in real
249
+ // CSS: the glow check only needs to fire once, on the element that
250
+ // declares the shadow, not on every descendant.
251
+ textShadow: 'none',
248
252
  fontFamily: '',
249
253
  fontSize: '16px',
250
254
  fontStyle: 'normal',
255
+ fontVariant: 'normal',
251
256
  fontWeight: '400',
252
257
  lineHeight: 'normal',
253
258
  letterSpacing: 'normal',
@@ -302,6 +307,7 @@ const STATIC_PROP_MAP = {
302
307
  'outline-color': 'outlineColor',
303
308
  'outline-style': 'outlineStyle',
304
309
  'box-shadow': 'boxShadow',
310
+ 'text-shadow': 'textShadow',
305
311
  'font-family': 'fontFamily',
306
312
  'font-size': 'fontSize',
307
313
  'font-style': 'fontStyle',
@@ -339,18 +345,29 @@ const STATIC_PROP_MAP = {
339
345
  'overflow-y': 'overflowY',
340
346
  };
341
347
 
348
+ // parseStaticColor tries parseAnyColor first, which already resolves every
349
+ // name in the shared CSS_NAMED_COLORS table. This fallback only carries the
350
+ // keywords parseAnyColor deliberately returns null for: the cascade needs
351
+ // `transparent` to read as an actual zero-alpha color.
342
352
  const STATIC_NAMED_COLORS = {
343
- black: { r: 0, g: 0, b: 0, a: 1 },
344
- white: { r: 255, g: 255, b: 255, a: 1 },
345
353
  transparent: { r: 0, g: 0, b: 0, a: 0 },
346
- gray: { r: 128, g: 128, b: 128, a: 1 },
347
- grey: { r: 128, g: 128, b: 128, a: 1 },
348
- silver: { r: 192, g: 192, b: 192, a: 1 },
349
- red: { r: 255, g: 0, b: 0, a: 1 },
350
- green: { r: 0, g: 128, b: 0, a: 1 },
351
- blue: { r: 0, g: 0, b: 255, a: 1 },
352
354
  };
353
355
 
356
+ // Named-color alternation for plucking a color token out of shorthand values
357
+ // (issue #359: a hardcoded 9-name list here silently dropped `purple`,
358
+ // `crimson`, `teal`, ... from border shorthands, so the side defaulted to
359
+ // neutral black and side-tab never fired on .html files). Derived from the
360
+ // same table parseAnyColor resolves against, so extraction and parsing can't
361
+ // drift apart. Longest-first so names containing other names as substrings
362
+ // (rebeccapurple) are matched whole.
363
+ const NAMED_COLOR_TOKENS = [...Object.keys(CSS_NAMED_COLORS), ...Object.keys(STATIC_NAMED_COLORS)]
364
+ .sort((a, b) => b.length - a.length)
365
+ .join('|');
366
+ const STATIC_COLOR_TOKEN_RE = new RegExp(
367
+ `(?:rgba?\\([^)]+\\)|oklch\\([^)]+\\)|oklab\\([^)]+\\)|lch\\([^)]+\\)|lab\\([^)]+\\)|hsla?\\([^)]+\\)|hwb\\([^)]+\\)|#[0-9a-f]{3,8}\\b|\\b(?:${NAMED_COLOR_TOKENS})\\b)`,
368
+ 'i'
369
+ );
370
+
354
371
  function splitCssList(value) {
355
372
  const parts = [];
356
373
  let depth = 0, quote = '', start = 0;
@@ -420,7 +437,23 @@ function extractStaticColor(value) {
420
437
  if (!value) return '';
421
438
  const raw = String(value).trim();
422
439
  if (/^var\(/i.test(raw)) return raw;
423
- const colorLike = raw.match(/(?:rgba?\([^)]+\)|oklch\([^)]+\)|oklab\([^)]+\)|lch\([^)]+\)|lab\([^)]+\)|hsla?\([^)]+\)|hwb\([^)]+\)|#[0-9a-f]{3,8}\b|\b(?:black|white|gray|grey|silver|red|green|blue|transparent)\b)/i);
440
+ // color-mix(...) needs balanced-paren capture (its arguments regularly
441
+ // contain nested var()/oklch() calls AND the keyword `transparent`, which
442
+ // the flat regex below would otherwise pluck out of the middle of the
443
+ // expression and report as the whole color).
444
+ const mixStart = raw.search(/color-mix\(/i);
445
+ if (mixStart !== -1) {
446
+ let depth = 0;
447
+ for (let i = raw.indexOf('(', mixStart); i < raw.length; i++) {
448
+ if (raw[i] === '(') depth++;
449
+ else if (raw[i] === ')') {
450
+ depth--;
451
+ if (depth === 0) return raw.slice(mixStart, i + 1);
452
+ }
453
+ }
454
+ return '';
455
+ }
456
+ const colorLike = raw.match(STATIC_COLOR_TOKEN_RE);
424
457
  if (!colorLike) return '';
425
458
  return colorLike[0];
426
459
  }
@@ -532,6 +565,15 @@ function expandStaticDeclaration(prop, value) {
532
565
  const beforeImage = hasImage ? v.split(/(?:repeating-)?(?:linear|radial|conic)-gradient\(|url\(/i)[0] : v;
533
566
  const color = extractStaticColor(hasImage ? beforeImage : v);
534
567
  if (color) out.push(['backgroundColor', color]);
568
+ // The `background` shorthand resets every longhand it does not set.
569
+ // Without this, `pre code { background: none }` leaves an earlier
570
+ // `background: var(--surface)` color standing and the contrast checks
571
+ // measure text against a surface the browser never paints. var() values
572
+ // stay untouched: they may resolve to a color later in the pipeline.
573
+ if (!color && !hasImage && !/var\(/i.test(v)) {
574
+ out.push(['backgroundColor', 'rgba(0, 0, 0, 0)']);
575
+ out.push(['backgroundImage', 'none']);
576
+ }
535
577
  return out;
536
578
  }
537
579
  if (p === 'border') {
@@ -702,7 +744,20 @@ function collectStaticCssRules(cssText, csstree) {
702
744
  });
703
745
  });
704
746
  for (const selector of splitCssList(selectorText)) {
705
- if (selector) rules.push({ selector, declarations, specificity: staticSpecificity(selector), order: order++ });
747
+ if (!selector) continue;
748
+ // :hover rules can't be matched statically as-is (no interaction
749
+ // state), but they carry real cascade weight while hovered. Tag
750
+ // them and record a state-stripped selector so the hover pass can
751
+ // find their targets; specificity stays computed from the ORIGINAL
752
+ // selector (per CSS, :hover counts as a class).
753
+ const isHover = /:hover\b/i.test(selector);
754
+ let matchSelector = null;
755
+ if (isHover) {
756
+ matchSelector = selector.replace(/:hover\b/gi, '').trim();
757
+ if (!matchSelector || /[>+~]\s*$/.test(matchSelector)) matchSelector = null;
758
+ else matchSelector = matchSelector.replace(/(^|[\s>+~])(?=$|[\s>+~])/g, '$1*');
759
+ }
760
+ rules.push({ selector, declarations, specificity: staticSpecificity(selector), order: order++, isHover, matchSelector });
706
761
  }
707
762
  return;
708
763
  }
@@ -805,6 +860,13 @@ class StaticDocument {
805
860
  this.domutils = modules.domutils;
806
861
  this._wrappers = new WeakMap();
807
862
  this._styleMap = new WeakMap();
863
+ this._hoverStyleMap = new WeakMap();
864
+ this._accentDashPseudo = new WeakSet();
865
+ // Elements whose ::before/::after paints a full-cover opaque surface
866
+ // (position absolute/fixed + inset 0 + solid background). The pseudo is
867
+ // the element's visible background for contrast purposes even though it
868
+ // never joins the element cascade.
869
+ this._pseudoSurface = new WeakMap();
808
870
  }
809
871
  wrap(node) {
810
872
  let wrapped = this._wrappers.get(node);
@@ -841,6 +903,24 @@ class StaticDocument {
841
903
  getStyle(el) {
842
904
  return this._styleMap.get(el.node) || makeStaticStyle();
843
905
  }
906
+ setHoverStyle(node, style) {
907
+ this._hoverStyleMap.set(node, style);
908
+ }
909
+ getHoverStyle(el) {
910
+ return this._hoverStyleMap.get(el.node) || null;
911
+ }
912
+ setAccentDashPseudo(node) {
913
+ this._accentDashPseudo.add(node);
914
+ }
915
+ hasAccentDashPseudo(el) {
916
+ return this._accentDashPseudo.has(el.node);
917
+ }
918
+ setPseudoSurface(node, color) {
919
+ this._pseudoSurface.set(node, color);
920
+ }
921
+ getPseudoSurface(el) {
922
+ return this._pseudoSurface.get(el.node) || null;
923
+ }
844
924
  }
845
925
 
846
926
  function makeStaticStyle(values = {}) {
@@ -856,6 +936,9 @@ function buildStaticWindow(staticDoc) {
856
936
  return {
857
937
  document: staticDoc,
858
938
  getComputedStyle: (el) => staticDoc.getStyle(el),
939
+ getHoverStyle: (el) => staticDoc.getHoverStyle(el),
940
+ hasAccentDashPseudo: (el) => staticDoc.hasAccentDashPseudo(el),
941
+ getPseudoSurface: (el) => staticDoc.getPseudoSurface(el),
859
942
  };
860
943
  }
861
944
 
@@ -886,6 +969,13 @@ function collectStaticCssText(root, fileDir, profile, filePath, modules) {
886
969
 
887
970
  function buildStaticStyleMap(root, staticDoc, cssText, modules, profile, filePath) {
888
971
  const specified = new Map();
972
+ // Declarations from :hover rules, matched via their state-stripped
973
+ // selectors. Merged per-property against the resting cascade in
974
+ // computeNode — a hover declaration only takes effect if it would win
975
+ // the cascade while the element is hovered (all resting rules still
976
+ // apply in that state).
977
+ const hoverSpecified = new Map();
978
+ const rootCustomProps = collectCssCustomProps(cssText);
889
979
  const allNodes = modules.selectAll('*', root.children || []);
890
980
  const rules = profileStep(profile, {
891
981
  engine: 'static-html',
@@ -901,9 +991,65 @@ function buildStaticStyleMap(root, staticDoc, cssText, modules, profile, filePat
901
991
  target: filePath,
902
992
  }, () => {
903
993
  for (const rule of rules) {
994
+ // ::before/::after rules can't join the element cascade (pseudo
995
+ // elements aren't DOM nodes), but one shape matters to the eyebrow
996
+ // check: the short chromatic "kicker dash" (content box 8-80px wide,
997
+ // 1-6px tall, accent-colored fill). Mark the base-selector matches
998
+ // so checkElementHeroEyebrow can see the dash.
999
+ if (!rule.isHover) {
1000
+ const pm = rule.selector.match(/^(.+?)\s*::?(?:before|after)$/i);
1001
+ if (pm) {
1002
+ const decls = new Map();
1003
+ for (const d of rule.declarations) decls.set(d.prop.toLowerCase(), d.value);
1004
+ const w = cssLengthToPx(resolveVarRefs(decls.get('width') || decls.get('inline-size') || '', rootCustomProps));
1005
+ const h = cssLengthToPx(resolveVarRefs(decls.get('height') || decls.get('block-size') || '', rootCustomProps));
1006
+ if (w != null && h != null && w >= 8 && w <= 80 && h >= 1 && h <= 6) {
1007
+ const bgRaw = String(resolveVarRefs(decls.get('background-color') || decls.get('background') || '', rootCustomProps));
1008
+ const token = bgRaw.match(/(?:rgba?|hsla?|oklch|oklab|lab|lch|hwb|color-mix)\([^)]*(?:\([^)]*\))?[^)]*\)|#[0-9a-f]{3,8}\b/i);
1009
+ const c = parseAnyColor(token ? token[0] : bgRaw);
1010
+ if (c && (c.a ?? 1) >= 0.1 && Math.max(c.r, c.g, c.b) - Math.min(c.r, c.g, c.b) >= 30) {
1011
+ try {
1012
+ for (const node of modules.selectAll(pm[1], root.children || [])) {
1013
+ staticDoc.setAccentDashPseudo(node);
1014
+ }
1015
+ } catch { /* unsupported base selector */ }
1016
+ }
1017
+ }
1018
+ // Full-cover surface pseudo: the CTA construction where the
1019
+ // element itself stays transparent and a ::before/::after with
1020
+ // position absolute/fixed + inset 0 (or all four sides 0, or
1021
+ // 100% width and height) plus an opaque background paints the
1022
+ // visible surface. Mark base-selector matches so the contrast
1023
+ // checks measure text against the surface the browser renders.
1024
+ const pseudoPos = String(decls.get('position') || '').toLowerCase();
1025
+ if (pseudoPos === 'absolute' || pseudoPos === 'fixed') {
1026
+ const zeroLen = v => v != null && /^0(?:px)?$/.test(String(v).trim());
1027
+ const insetRaw = String(decls.get('inset') || '').trim();
1028
+ const coversBox = (insetRaw !== '' && insetRaw.split(/\s+/).every(t => /^0(?:px)?$/.test(t)))
1029
+ || ['top', 'right', 'bottom', 'left'].every(side => zeroLen(decls.get(side)))
1030
+ || (String(decls.get('width') || '').trim() === '100%'
1031
+ && String(decls.get('height') || '').trim() === '100%');
1032
+ if (coversBox && decls.has('content')) {
1033
+ const surfRaw = String(resolveVarRefs(decls.get('background-color') || decls.get('background') || '', rootCustomProps));
1034
+ const surfToken = surfRaw.match(/(?:rgba?|hsla?|oklch|oklab|lab|lch|hwb|color-mix)\([^)]*(?:\([^)]*\))?[^)]*\)|#[0-9a-f]{3,8}\b/i);
1035
+ const surf = parseAnyColor(surfToken ? surfToken[0] : surfRaw);
1036
+ if (surf && (surf.a ?? 1) >= 0.9 && !/gradient/i.test(surfRaw)) {
1037
+ try {
1038
+ for (const node of modules.selectAll(pm[1], root.children || [])) {
1039
+ staticDoc.setPseudoSurface(node, surf);
1040
+ }
1041
+ } catch { /* unsupported base selector */ }
1042
+ }
1043
+ }
1044
+ }
1045
+ continue;
1046
+ }
1047
+ }
1048
+ const matchSelector = rule.isHover ? rule.matchSelector : rule.selector;
1049
+ if (!matchSelector) continue;
904
1050
  let matched;
905
1051
  try {
906
- matched = modules.selectAll(rule.selector, root.children || []);
1052
+ matched = modules.selectAll(matchSelector, root.children || []);
907
1053
  } catch {
908
1054
  recordProfileEvent(profile, {
909
1055
  engine: 'static-html',
@@ -912,13 +1058,13 @@ function buildStaticStyleMap(root, staticDoc, cssText, modules, profile, filePat
912
1058
  target: filePath,
913
1059
  ms: 0,
914
1060
  findings: 0,
915
- detail: rule.selector,
1061
+ detail: matchSelector,
916
1062
  });
917
1063
  continue;
918
1064
  }
919
1065
  for (const node of matched) {
920
1066
  for (const decl of rule.declarations) {
921
- applyStaticDeclaration(specified, node, decl.prop, decl.value, {
1067
+ applyStaticDeclaration(rule.isHover ? hoverSpecified : specified, node, decl.prop, decl.value, {
922
1068
  important: decl.important,
923
1069
  specificity: rule.specificity,
924
1070
  order: rule.order,
@@ -961,6 +1107,28 @@ function buildStaticStyleMap(root, staticDoc, cssText, modules, profile, filePat
961
1107
  }
962
1108
  const style = makeStaticStyle(values);
963
1109
  staticDoc.setStyle(node, style);
1110
+
1111
+ // Hover pass: limited to the two properties the hover-contrast check
1112
+ // consumes. A hover declaration wins only if it beats the resting
1113
+ // winner for that property under normal cascade rules (specificity /
1114
+ // order / importance) — exactly what a browser computes while the
1115
+ // element is hovered.
1116
+ const hoverMap = hoverSpecified.get(node);
1117
+ if (hoverMap) {
1118
+ let hoverValues = null;
1119
+ for (const prop of ['color', 'backgroundColor']) {
1120
+ const hoverDecl = hoverMap.get(prop);
1121
+ if (!hoverDecl) continue;
1122
+ const restingDecl = specifiedMap.get(prop);
1123
+ if (!compareStaticPriority(restingDecl, hoverDecl)) continue;
1124
+ const next = normalizeStaticCssValue(prop, hoverDecl.value, customProps, parentStyle, values);
1125
+ if (next === values[prop]) continue;
1126
+ if (!hoverValues) hoverValues = { ...values };
1127
+ hoverValues[prop] = next;
1128
+ }
1129
+ if (hoverValues) staticDoc.setHoverStyle(node, makeStaticStyle(hoverValues));
1130
+ }
1131
+
964
1132
  for (const child of node.children || []) {
965
1133
  if (child.type === 'tag') computeNode(child, style, customProps);
966
1134
  }
@@ -18,20 +18,23 @@ import {
18
18
  checkElementGlow,
19
19
  checkElementGptBorderShadow,
20
20
  checkElementHeroEyebrow,
21
+ checkElementHoverContrast,
21
22
  checkElementIconTile,
22
23
  checkElementItalicSerif,
23
24
  checkElementMotion,
24
25
  checkElementOversizedH1,
25
26
  checkElementQuality,
27
+ checkElementRadialSpotlight,
26
28
  checkCreamPalette,
27
29
  checkHtmlPatterns,
30
+ checkKickerAboveHeadingFromDoc,
31
+ checkNumberedSectionLabelsFromDoc,
28
32
  checkPageLayout,
29
33
  checkPageQualityFromDoc,
30
- checkRepeatedSectionKickersFromDoc,
34
+ checkRepeatedContainerTextFromDoc,
31
35
  resolveBackground,
32
36
  resolveBorderRadiusPx,
33
37
  } from '../../rules/checks.mjs';
34
- import { filterByProviders } from '../../registry/antipatterns.mjs';
35
38
  import { detectText, runTextContentAnalyzers } from '../regex/detect-text.mjs';
36
39
  import {
37
40
  StaticDocument,
@@ -90,8 +93,9 @@ function checkElementBrokenImage(el) {
90
93
  }
91
94
 
92
95
  const STATIC_ELEMENT_RULES = [
93
- { id: 'border-rules', selector: '*', run: (el, tag, style, window, customPropMap) => checkElementBorders(tag, style, null, resolveBorderRadiusPx(el, style, parseFloat(style.width) || 0, window)) },
96
+ { id: 'border-rules', selector: '*', run: (el, tag, style, window, customPropMap) => checkElementBorders(tag, style, null, resolveBorderRadiusPx(el, style, parseFloat(style.width) || 0, window), el) },
94
97
  { id: 'color-rules', selector: '*', run: (el, tag, style, window, customPropMap) => checkElementColors(el, style, tag, window, customPropMap, false) },
98
+ { id: 'hover-color-rules', selector: '*', run: (el, tag, style, window) => checkElementHoverContrast(el, style, tag, window) },
95
99
  { id: 'dark-glow', selector: '*', run: (el, tag, style, window, customPropMap) => checkElementGlow(tag, style, resolveBackground(el.parentElement || el, window, customPropMap)) },
96
100
  { id: 'motion-rules', selector: '*', run: (el, tag, style) => checkElementMotion(tag, style) },
97
101
  { id: 'icon-tile-stack', selector: 'h1,h2,h3,h4,h5,h6', run: (el, tag, _style, window) => checkElementIconTile(el, tag, window) },
@@ -102,6 +106,7 @@ const STATIC_ELEMENT_RULES = [
102
106
  { id: 'oversized-h1', selector: 'h1', run: (el, tag, style, window) => checkElementOversizedH1(el, style, tag, window) },
103
107
  { id: 'clipped-overflow-container', selector: '*', run: (el, tag, style, window) => checkElementClippedOverflow(el, style, tag, window) },
104
108
  { id: 'gpt-thin-border-wide-shadow', selector: '*', run: (el, tag, style) => checkElementGptBorderShadow(el, style) },
109
+ { id: 'radial-spotlight-glow', selector: '*', run: (el, tag, style, window) => checkElementRadialSpotlight(el, style, tag, window) },
105
110
  ];
106
111
 
107
112
  async function detectHtml(filePath, options = {}) {
@@ -197,7 +202,13 @@ async function detectHtml(filePath, options = {}) {
197
202
  for (const f of runPageCheck('typography-rules', () => checkStaticPageTypography(document, window))) {
198
203
  findings.push(finding(f.id, filePath, f.snippet));
199
204
  }
200
- for (const f of runPageCheck('repeated-section-kickers', () => checkRepeatedSectionKickersFromDoc(document, window))) {
205
+ for (const f of runPageCheck('kicker-above-heading', () => checkKickerAboveHeadingFromDoc(document, window))) {
206
+ findings.push(finding(f.id, filePath, f.snippet));
207
+ }
208
+ for (const f of runPageCheck('numbered-section-labels', () => checkNumberedSectionLabelsFromDoc(document, window))) {
209
+ findings.push(finding(f.id, filePath, f.snippet));
210
+ }
211
+ for (const f of runPageCheck('repeated-container-text', () => checkRepeatedContainerTextFromDoc(document, window))) {
201
212
  findings.push(finding(f.id, filePath, f.snippet));
202
213
  }
203
214
  for (const f of runPageCheck('layout-rules', () => checkPageLayout(document, window))) {
@@ -212,7 +223,12 @@ async function detectHtml(filePath, options = {}) {
212
223
  for (const f of runPageCheck('html-patterns', () => checkHtmlPatterns(html).filter(item =>
213
224
  item.id !== 'bounce-easing' && item.id !== 'layout-transition'
214
225
  ))) {
215
- findings.push(finding(f.id, filePath, f.snippet));
226
+ const item = finding(f.id, filePath, f.snippet);
227
+ // Position-aware severity promotion: checks may attach a per-finding
228
+ // severity (e.g. a pulsing dot inside a header/nav landmark) that
229
+ // overrides the registry default.
230
+ if (f.severity) item.severity = f.severity;
231
+ findings.push(item);
216
232
  }
217
233
  // Text-content analyzers (em-dash overuse, marketing buzzwords,
218
234
  // numbered section markers, aphoristic cadence) live in the regex
@@ -224,11 +240,10 @@ async function detectHtml(filePath, options = {}) {
224
240
  }
225
241
  }
226
242
 
227
- const byProvider = filterByProviders(findings, options.providers);
228
243
  // Static-HTML findings carry no line number, so only whole-file
229
244
  // `impeccable-disable` directives apply here — exactly the standalone-document
230
245
  // waiver this primitive targets. Bypassed by `--no-config` / `--no-inline-ignores`.
231
- return options?.inlineIgnores === false ? byProvider : applyInlineIgnores(byProvider, html);
246
+ return options?.inlineIgnores === false ? findings : applyInlineIgnores(findings, html);
232
247
  }
233
248
 
234
249
  export { checkStaticPageTypography, STATIC_ELEMENT_RULES, detectHtml };
@@ -6,7 +6,13 @@ function getAP(id) {
6
6
 
7
7
  function finding(id, filePath, snippet, line = 0) {
8
8
  const ap = getAP(id);
9
- return { antipattern: id, name: ap.name, description: ap.description, severity: ap.severity || 'warning', file: filePath, line, snippet };
9
+ const base = { antipattern: id, name: ap.name, description: ap.description, severity: ap.severity || 'warning', category: ap.category || null, file: filePath, line, snippet };
10
+ // Advisory findings are detected but reported separately and never counted as
11
+ // failures. Carry the flag on the finding so every consumer (CLI, JSON, hook)
12
+ // can partition without a registry lookup. Only stamped when true to keep the
13
+ // finding shape stable for the vast majority of rules.
14
+ if (ap.advisory === true) base.advisory = true;
15
+ return base;
10
16
  }
11
17
 
12
18
  export { getAP, finding };
@@ -5,11 +5,24 @@ import path from 'node:path';
5
5
  // File walker
6
6
  // ---------------------------------------------------------------------------
7
7
 
8
+ // Hidden directories are skipped wholesale during recursion (below), which
9
+ // covers .git / .next / .nuxt / .svelte-kit / .turbo / .vercel and — the
10
+ // issue #303 class — every vendored AI-harness install (.claude, .cursor,
11
+ // .codex, .agents, .impeccable, ...) whose bundled detector source would
12
+ // otherwise be reported as findings on a root scan. Only the non-hidden
13
+ // build/dependency dirs need naming. An explicitly passed hidden target
14
+ // still scans: walkDir name-checks children, never the root it's given.
8
15
  const SKIP_DIRS = new Set([
9
- 'node_modules', '.git', 'dist', 'build', '.next', '.nuxt', '.output',
10
- '.svelte-kit', '__pycache__', '.turbo', '.vercel',
16
+ 'node_modules', 'dist', 'build', '__pycache__',
11
17
  ]);
12
18
 
19
+ // The exceptions to the hidden-dir rule: hidden directories that
20
+ // conventionally hold real UI source rather than tooling or vendored code.
21
+ // VitePress and VuePress keep custom theme components in
22
+ // .vitepress/theme/*.vue / .vuepress/theme/, and Storybook keeps preview
23
+ // decorators/styles in .storybook/.
24
+ const HIDDEN_SOURCE_DIRS = new Set(['.vitepress', '.vuepress', '.storybook']);
25
+
13
26
  const SCANNABLE_EXTENSIONS = new Set([
14
27
  '.html', '.htm', '.css', '.scss', '.sass', '.less',
15
28
  '.jsx', '.tsx', '.js', '.ts',
@@ -24,6 +37,7 @@ function walkDir(dir) {
24
37
  try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return files; }
25
38
  for (const entry of entries) {
26
39
  if (SKIP_DIRS.has(entry.name)) continue;
40
+ if (entry.isDirectory() && entry.name.startsWith('.') && !HIDDEN_SOURCE_DIRS.has(entry.name)) continue;
27
41
  const full = path.join(dir, entry.name);
28
42
  if (entry.isDirectory()) files.push(...walkDir(full));
29
43
  else if (SCANNABLE_EXTENSIONS.has(path.extname(entry.name).toLowerCase())) files.push(full);