oh-my-opencode 5.1.44 β†’ 5.1.46

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 (626) hide show
  1. package/.agents/command/publish.md +9 -9
  2. package/.agents/skills/publish/SKILL.md +9 -9
  3. package/.opencode/command/publish.md +9 -9
  4. package/README.de.md +0 -5
  5. package/README.es.md +0 -5
  6. package/README.fr.md +0 -5
  7. package/README.it.md +0 -5
  8. package/README.ja.md +0 -5
  9. package/README.ko.md +0 -5
  10. package/README.md +4 -5
  11. package/README.pt-br.md +0 -5
  12. package/README.ru.md +0 -6
  13. package/README.zh-cn.md +0 -5
  14. package/dist/cli/index.js +865 -413
  15. package/dist/cli/service-auth/keystore.d.ts +4 -2
  16. package/dist/cli-node/index.js +865 -413
  17. package/dist/features/builtin-commands/templates/hyperplan.d.ts +1 -1
  18. package/dist/features/builtin-commands/templates/refactor-sections/team-mode-addendum.d.ts +1 -1
  19. package/dist/features/builtin-commands/templates/remove-ai-slops.d.ts +1 -1
  20. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  21. package/dist/index.js +5270 -2308
  22. package/dist/oh-my-opencode.schema.json +2 -2
  23. package/dist/plugin/command-execute-before.d.ts +3 -0
  24. package/dist/plugin/skill-context.d.ts +2 -0
  25. package/dist/plugin/skill-security-notice.d.ts +3 -0
  26. package/dist/plugin-config/omo-config-chain.d.ts +1 -0
  27. package/dist/skills/ast-grep/AGENTS.md +1 -1
  28. package/dist/skills/browser/SKILL.md +21 -22
  29. package/dist/skills/browser/references/commands.md +2 -9
  30. package/dist/skills/browser/references/install.md +1 -2
  31. package/dist/skills/browser/runtime/omowright/manifest.json +1 -1
  32. package/dist/skills/browser/scripts/browser-doctor.mjs +2 -2
  33. package/dist/skills/browser/scripts/browser-engine-guard.mjs +63 -487
  34. package/dist/skills/browser/scripts/browser-install.mjs +1 -1
  35. package/dist/skills/browser/scripts/omowright.mjs +1 -10
  36. package/dist/skills/frontend/ATTRIBUTION.md +2 -2
  37. package/dist/skills/frontend/SKILL.md +79 -118
  38. package/dist/skills/frontend/references/design/README.md +75 -224
  39. package/dist/skills/frontend/references/design/stylegallery.md +32 -27
  40. package/dist/skills/frontend/references/perfection/README.md +2 -2
  41. package/dist/skills/frontend/scripts/perfection/check-accent-stripes.ts +8 -24
  42. package/dist/skills/frontend/scripts/perfection/check-draft-guard.test.ts +101 -0
  43. package/dist/skills/frontend/scripts/perfection/check-draft-guard.ts +40 -0
  44. package/dist/skills/frontend/scripts/perfection/collect-files.test.ts +50 -0
  45. package/dist/skills/frontend/scripts/perfection/collect-files.ts +53 -0
  46. package/dist/skills/frontend/scripts/perfection/draft-guard/findings.ts +16 -0
  47. package/dist/skills/frontend/scripts/perfection/draft-guard/lint.ts +38 -0
  48. package/dist/skills/frontend/scripts/perfection/draft-guard/rules.ts +69 -0
  49. package/dist/skills/frontend/scripts/perfection/draft-guard/text-nodes.ts +121 -0
  50. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/attr-lookalikes.tsx +10 -0
  51. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/bound-values.tsx +12 -0
  52. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/const-generics.tsx +3 -0
  53. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/generics.tsx +7 -0
  54. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/measured-stats.html +6 -0
  55. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/plain-copy.html +9 -0
  56. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/state-copy.html +11 -0
  57. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/attribute-edges.html +7 -0
  58. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/components.tsx +16 -0
  59. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/decorative-badge.vue +7 -0
  60. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/emoji-icons.tsx +9 -0
  61. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/jsx-edges.tsx +1 -0
  62. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/promo-copy.html +6 -0
  63. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/promo-copy.tsx +8 -0
  64. package/dist/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/vanity-stats.html +5 -0
  65. package/dist/skills/programming/SKILL.md +10 -7
  66. package/dist/skills/programming/references/typescript/README.md +10 -7
  67. package/dist/skills/programming/references/typescript/bootstrap.md +9 -23
  68. package/dist/skills/programming/references/typescript/oxc-lint.md +130 -0
  69. package/dist/skills/programming/references/typescript/tsconfig-strict.md +6 -62
  70. package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.ts +12 -12
  71. package/dist/skills/programming/scripts/typescript/new-project.test.ts +162 -0
  72. package/dist/skills/programming/scripts/typescript/new-project.ts +20 -81
  73. package/dist/skills/programming/scripts/typescript/oxc/.oxfmtrc.json +9 -0
  74. package/dist/skills/programming/scripts/typescript/oxc/.oxlintrc.json +46 -0
  75. package/dist/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/LICENSE +21 -0
  76. package/dist/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/index.js +10 -0
  77. package/dist/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/no-em-dash-copy.js +28 -0
  78. package/dist/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/require-suppression-reason.js +62 -0
  79. package/dist/skills/programming/scripts/typescript/oxc/tsconfig.json +29 -0
  80. package/dist/skills/refactor/SKILL.md +13 -13
  81. package/dist/skills/ultimate-browsing/engine/AGENTS.md +1 -1
  82. package/dist/skills/ulw-execute/SKILL.md +1 -1
  83. package/dist/skills/ulw-research/AGENTS.md +21 -3
  84. package/dist/skills/ulw-research/SKILL.md +37 -12
  85. package/dist/skills/ulw-research/references/deliverable-phase.md +77 -16
  86. package/dist/skills/ulw-research/references/fact-ledger-grammar.md +134 -0
  87. package/dist/skills/ulw-research/references/fact-ledger.md +95 -0
  88. package/dist/skills/ulw-research/references/fidelity-claim-kinds.md +19 -0
  89. package/dist/skills/ulw-research/references/report-gates.md +68 -3
  90. package/dist/skills/ulw-research/references/report-visualization.md +2 -0
  91. package/dist/skills/ulw-research/references/unit-rules.md +157 -0
  92. package/dist/skills/ulw-research/scripts/claim-kinds.mjs +116 -0
  93. package/dist/skills/ulw-research/scripts/claim-kinds.test.ts +193 -0
  94. package/dist/skills/ulw-research/scripts/claims-index.mjs +125 -0
  95. package/dist/skills/ulw-research/scripts/claims-index.test.ts +149 -0
  96. package/dist/skills/ulw-research/scripts/cli-support.mjs +19 -5
  97. package/dist/skills/ulw-research/scripts/cli-support.test.ts +13 -2
  98. package/dist/skills/ulw-research/scripts/contracts.mjs +89 -3
  99. package/dist/skills/ulw-research/scripts/contracts.test.ts +100 -12
  100. package/dist/skills/ulw-research/scripts/copy-returns.test.ts +183 -0
  101. package/dist/skills/ulw-research/scripts/delivery-barrier.test.ts +245 -0
  102. package/dist/skills/ulw-research/scripts/fact-commands-meaning.mjs +191 -0
  103. package/dist/skills/ulw-research/scripts/fact-commands-verify.mjs +164 -0
  104. package/dist/skills/ulw-research/scripts/fact-commands.mjs +239 -0
  105. package/dist/skills/ulw-research/scripts/fact-derive.mjs +66 -0
  106. package/dist/skills/ulw-research/scripts/fact-derive.test.ts +375 -0
  107. package/dist/skills/ulw-research/scripts/fact-expr.mjs +108 -0
  108. package/dist/skills/ulw-research/scripts/fact-fill.mjs +194 -0
  109. package/dist/skills/ulw-research/scripts/fact-fill.test.ts +221 -0
  110. package/dist/skills/ulw-research/scripts/fact-ledger-grammar.test.ts +197 -0
  111. package/dist/skills/ulw-research/scripts/fact-ledger-kinds.mjs +250 -0
  112. package/dist/skills/ulw-research/scripts/fact-ledger-kinds.test.ts +156 -0
  113. package/dist/skills/ulw-research/scripts/fact-ledger-legacy.test.ts +160 -0
  114. package/dist/skills/ulw-research/scripts/fact-ledger-schema.mjs +221 -0
  115. package/dist/skills/ulw-research/scripts/fact-ledger-schema.test.ts +43 -0
  116. package/dist/skills/ulw-research/scripts/fact-ledger.mjs +123 -0
  117. package/dist/skills/ulw-research/scripts/fact-ledger.test.ts +254 -0
  118. package/dist/skills/ulw-research/scripts/fact-locate.mjs +231 -0
  119. package/dist/skills/ulw-research/scripts/fact-locate.test.ts +118 -0
  120. package/dist/skills/ulw-research/scripts/fact-pairs.mjs +187 -0
  121. package/dist/skills/ulw-research/scripts/fact-pairs.test.ts +167 -0
  122. package/dist/skills/ulw-research/scripts/fact-recompute.mjs +89 -0
  123. package/dist/skills/ulw-research/scripts/fact-unit-dimensions.test.ts +409 -0
  124. package/dist/skills/ulw-research/scripts/fact-unit-rules.test.ts +388 -0
  125. package/dist/skills/ulw-research/scripts/fidelity-binding.mjs +130 -0
  126. package/dist/skills/ulw-research/scripts/fidelity-binding.test.ts +81 -0
  127. package/dist/skills/ulw-research/scripts/fidelity-brief.mjs +150 -0
  128. package/dist/skills/ulw-research/scripts/fidelity-brief.test.ts +179 -0
  129. package/dist/skills/ulw-research/scripts/fidelity-claims.mjs +89 -0
  130. package/dist/skills/ulw-research/scripts/fidelity-lexicon.mjs +145 -0
  131. package/dist/skills/ulw-research/scripts/fidelity-lexicon.test.ts +117 -0
  132. package/dist/skills/ulw-research/scripts/fidelity-records.mjs +163 -0
  133. package/dist/skills/ulw-research/scripts/fidelity-state.mjs +64 -0
  134. package/dist/skills/ulw-research/scripts/fidelity-state.test.ts +46 -0
  135. package/dist/skills/ulw-research/scripts/fidelity-trace.mjs +85 -0
  136. package/dist/skills/ulw-research/scripts/fidelity-trace.test.ts +58 -0
  137. package/dist/skills/ulw-research/scripts/fidelity-values.mjs +229 -0
  138. package/dist/skills/ulw-research/scripts/fidelity-values.test.ts +270 -0
  139. package/dist/skills/ulw-research/scripts/gates-context.test.ts +64 -0
  140. package/dist/skills/ulw-research/scripts/gates-fidelity.mjs +113 -0
  141. package/dist/skills/ulw-research/scripts/gates-fidelity.test.ts +73 -0
  142. package/dist/skills/ulw-research/scripts/gates-static.mjs +29 -9
  143. package/dist/skills/ulw-research/scripts/gates-structure.mjs +1 -1
  144. package/dist/skills/ulw-research/scripts/gates-text.mjs +1 -27
  145. package/dist/skills/ulw-research/scripts/html-lite.mjs +2 -2
  146. package/dist/skills/ulw-research/scripts/html-markup.mjs +182 -0
  147. package/dist/skills/ulw-research/scripts/lexicon.mjs +47 -0
  148. package/dist/skills/ulw-research/scripts/lexicon.test.ts +57 -0
  149. package/dist/skills/ulw-research/scripts/md-lite.mjs +193 -0
  150. package/dist/skills/ulw-research/scripts/md-lite.test.ts +271 -0
  151. package/dist/skills/ulw-research/scripts/meaning-check.mjs +196 -0
  152. package/dist/skills/ulw-research/scripts/meaning-check.test.ts +228 -0
  153. package/dist/skills/ulw-research/scripts/numerals.mjs +226 -0
  154. package/dist/skills/ulw-research/scripts/numerals.test.ts +120 -0
  155. package/dist/skills/ulw-research/scripts/outcome.mjs +8 -8
  156. package/dist/skills/ulw-research/scripts/outcome.test.ts +29 -0
  157. package/dist/skills/ulw-research/scripts/particles-ko.mjs +108 -0
  158. package/dist/skills/ulw-research/scripts/particles-ko.test.ts +86 -0
  159. package/dist/skills/ulw-research/scripts/placeholder.mjs +184 -0
  160. package/dist/skills/ulw-research/scripts/placeholder.test.ts +77 -0
  161. package/dist/skills/ulw-research/scripts/polish-apply.mjs +115 -0
  162. package/dist/skills/ulw-research/scripts/polish-apply.test.ts +363 -0
  163. package/dist/skills/ulw-research/scripts/polish-diff.mjs +31 -0
  164. package/dist/skills/ulw-research/scripts/polish-diff.test.ts +168 -0
  165. package/dist/skills/ulw-research/scripts/polish-markup.test.ts +187 -0
  166. package/dist/skills/ulw-research/scripts/polish-project.mjs +125 -0
  167. package/dist/skills/ulw-research/scripts/polish-rules.mjs +170 -0
  168. package/dist/skills/ulw-research/scripts/rational.mjs +139 -0
  169. package/dist/skills/ulw-research/scripts/rational.test.ts +46 -0
  170. package/dist/skills/ulw-research/scripts/report-tools-commands.mjs +21 -10
  171. package/dist/skills/ulw-research/scripts/report-tools.mjs +15 -0
  172. package/dist/skills/ulw-research/scripts/report-tools.test.ts +458 -2
  173. package/dist/skills/ulw-research/scripts/sentence-split.mjs +77 -0
  174. package/dist/skills/ulw-research/scripts/sentence-split.test.ts +109 -0
  175. package/dist/skills/ulw-research/scripts/source-commands.mjs +140 -0
  176. package/dist/skills/ulw-research/scripts/source-snapshot.mjs +176 -0
  177. package/dist/skills/ulw-research/scripts/source-snapshot.test.ts +113 -0
  178. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/assets/share.csv +3 -0
  179. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/claim-graph.md +13 -0
  180. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/gen-legacy-dev.mjs +89 -0
  181. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/ledger-basic.json +223 -0
  182. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/ledger-legacy-dev.json +859 -0
  183. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/ledger-verify.json +420 -0
  184. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/report-bad.html +19 -0
  185. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/report-good.html +39 -0
  186. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S4/acronyms.json +3 -0
  187. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S4/meta.json +9 -0
  188. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S4/sentences.jsonl +7 -0
  189. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S4/text.txt +7 -0
  190. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S4.html +19 -0
  191. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S5/acronyms.json +1 -0
  192. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S5/meta.json +9 -0
  193. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S5/sentences.jsonl +1 -0
  194. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S5/text.txt +1 -0
  195. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S9.txt +1 -0
  196. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity-brief-locked.md +17 -0
  197. package/dist/skills/ulw-research/scripts/tests/fixtures/fidelity-brief-pending.md +17 -0
  198. package/dist/skills/ulw-research/scripts/text-normalize.mjs +82 -0
  199. package/dist/skills/ulw-research/scripts/text-normalize.test.ts +73 -0
  200. package/dist/skills/ulw-research/scripts/text-similarity.mjs +28 -0
  201. package/dist/skills/ulw-research/scripts/text-similarity.test.ts +38 -0
  202. package/dist/skills/ulw-research/scripts/unit-algebra.mjs +101 -0
  203. package/dist/skills/ulw-research/scripts/unit-errors.mjs +23 -0
  204. package/dist/skills/ulw-research/scripts/unit-metadata.mjs +31 -0
  205. package/dist/skills/ulw-research/scripts/unit-pairs.mjs +72 -0
  206. package/dist/skills/ulw-research/scripts/unit-precision.mjs +44 -0
  207. package/dist/skills/ulw-research/scripts/unit-rules-shapes.mjs +64 -0
  208. package/dist/skills/ulw-research/scripts/unit-rules.mjs +173 -0
  209. package/dist/skills/ulw-research/scripts/units.mjs +105 -0
  210. package/dist/skills/ulw-research/scripts/units.test.ts +83 -0
  211. package/dist/skills/visual-qa/SKILL.md +70 -63
  212. package/dist/skills/visual-qa/scripts/skill-doc-fields.test.ts +34 -0
  213. package/dist/testing/module-mock-lifecycle.d.ts +1 -1
  214. package/dist/tools/delegate-task/constants.d.ts +1 -1
  215. package/dist/tools/session-manager/constants.d.ts +1 -1
  216. package/dist/tools/session-manager/file-storage.d.ts +9 -2
  217. package/dist/tools/session-manager/sdk-storage.d.ts +19 -1
  218. package/dist/tools/session-manager/session-formatter.d.ts +3 -3
  219. package/dist/tools/session-manager/storage.d.ts +8 -2
  220. package/dist/tools/skill/mcp-capability-formatter.d.ts +1 -1
  221. package/dist/tools/skill/native-skills.d.ts +2 -2
  222. package/dist/tools/skill/skill-mcp-authority.d.ts +3 -0
  223. package/dist/tui.js +537 -104
  224. package/docs/reference/web-terminal-visual-qa.md +8 -0
  225. package/package.json +24 -16
  226. package/packages/lsp-core/src/lsp/client-wrapper.ts +4 -4
  227. package/packages/lsp-core/src/mcp-protocol-pin.test.ts +29 -0
  228. package/packages/lsp-core/src/mcp.ts +5 -2
  229. package/packages/lsp-core/src/post-edit/not-installed.test.ts +2 -2
  230. package/packages/lsp-daemon/dist/cli.js +7 -7
  231. package/packages/lsp-daemon/dist/client.js +7 -7
  232. package/packages/lsp-daemon/dist/index.js +7 -7
  233. package/packages/lsp-daemon/package.json +3 -3
  234. package/packages/lsp-tools-mcp/dist/cli.js +7 -7
  235. package/packages/lsp-tools-mcp/dist/mcp.js +7 -7
  236. package/packages/lsp-tools-mcp/dist/tools.js +4 -4
  237. package/packages/lsp-tools-mcp/package.json +3 -3
  238. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  239. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +77 -26
  240. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  241. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  242. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -1
  243. package/packages/omo-codex/plugin/components/comment-checker/biome.json +1 -21
  244. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  245. package/packages/omo-codex/plugin/components/comment-checker/package.json +4 -4
  246. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  247. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  248. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +1 -21
  249. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  250. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +4 -4
  251. package/packages/omo-codex/plugin/components/lsp/biome.json +1 -21
  252. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  253. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +4 -4
  254. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  255. package/packages/omo-codex/plugin/components/lsp/package.json +4 -4
  256. package/packages/omo-codex/plugin/components/lsp/scripts/build-runtime.mjs +0 -1
  257. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-not-installed.test.ts +1 -1
  258. package/packages/omo-codex/plugin/components/rules/biome.json +1 -21
  259. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  260. package/packages/omo-codex/plugin/components/rules/package.json +4 -4
  261. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  262. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  263. package/packages/omo-codex/plugin/components/telemetry/biome.json +1 -21
  264. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +90 -1
  265. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +91 -1
  266. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  267. package/packages/omo-codex/plugin/components/telemetry/package.json +4 -4
  268. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +2 -2
  269. package/packages/omo-codex/plugin/components/ultrawork/biome.json +1 -21
  270. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  271. package/packages/omo-codex/plugin/components/ultrawork/package.json +4 -4
  272. package/packages/omo-codex/plugin/components/ulw-execute-continuation/biome.json +1 -21
  273. package/packages/omo-codex/plugin/components/ulw-execute-continuation/directive.md +1 -1
  274. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  275. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +4 -4
  276. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +1 -21
  277. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +1 -1
  278. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +7 -7
  279. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +5 -5
  280. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +1 -1
  281. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  282. package/packages/omo-codex/plugin/components/ulw-loop/package.json +4 -4
  283. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +1 -1
  284. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +5 -5
  285. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +1 -1
  286. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-mutations.mjs +2 -0
  287. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  288. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  289. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  290. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  291. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  292. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  293. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  294. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  295. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  296. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  297. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  298. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  299. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  300. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  301. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  302. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  303. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  304. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  305. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  306. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  307. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  308. package/packages/omo-codex/plugin/package-lock.json +12 -12
  309. package/packages/omo-codex/plugin/package.json +1 -1
  310. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +14 -9
  311. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +1 -1
  312. package/packages/omo-codex/plugin/skills/browser/SKILL.md +21 -22
  313. package/packages/omo-codex/plugin/skills/browser/references/commands.md +2 -9
  314. package/packages/omo-codex/plugin/skills/browser/references/install.md +1 -2
  315. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +1 -1
  316. package/packages/omo-codex/plugin/skills/browser/scripts/browser-doctor.mjs +2 -2
  317. package/packages/omo-codex/plugin/skills/browser/scripts/browser-engine-guard.mjs +63 -487
  318. package/packages/omo-codex/plugin/skills/browser/scripts/browser-install.mjs +1 -1
  319. package/packages/omo-codex/plugin/skills/browser/scripts/omowright.mjs +1 -10
  320. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +2 -2
  321. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +79 -118
  322. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +75 -224
  323. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +32 -27
  324. package/packages/omo-codex/plugin/skills/frontend/references/perfection/README.md +2 -2
  325. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/check-accent-stripes.ts +8 -24
  326. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/check-draft-guard.ts +40 -0
  327. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/collect-files.ts +53 -0
  328. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/draft-guard/findings.ts +16 -0
  329. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/draft-guard/lint.ts +38 -0
  330. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/draft-guard/rules.ts +69 -0
  331. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/draft-guard/text-nodes.ts +121 -0
  332. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/attr-lookalikes.tsx +10 -0
  333. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/bound-values.tsx +12 -0
  334. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/const-generics.tsx +3 -0
  335. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/generics.tsx +7 -0
  336. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/measured-stats.html +6 -0
  337. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/plain-copy.html +9 -0
  338. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/state-copy.html +11 -0
  339. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/attribute-edges.html +7 -0
  340. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/components.tsx +16 -0
  341. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/decorative-badge.vue +7 -0
  342. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/emoji-icons.tsx +9 -0
  343. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/jsx-edges.tsx +1 -0
  344. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/promo-copy.html +6 -0
  345. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/promo-copy.tsx +8 -0
  346. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/vanity-stats.html +5 -0
  347. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +1 -1
  348. package/packages/omo-codex/plugin/skills/programming/SKILL.md +10 -7
  349. package/packages/omo-codex/plugin/skills/programming/references/typescript/README.md +10 -7
  350. package/packages/omo-codex/plugin/skills/programming/references/typescript/bootstrap.md +9 -23
  351. package/packages/omo-codex/plugin/skills/programming/references/typescript/oxc-lint.md +130 -0
  352. package/packages/omo-codex/plugin/skills/programming/references/typescript/tsconfig-strict.md +6 -62
  353. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +12 -12
  354. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/new-project.ts +20 -81
  355. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/.oxfmtrc.json +9 -0
  356. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/.oxlintrc.json +46 -0
  357. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/LICENSE +21 -0
  358. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/index.js +10 -0
  359. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/no-em-dash-copy.js +28 -0
  360. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/require-suppression-reason.js +62 -0
  361. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/tsconfig.json +29 -0
  362. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +14 -14
  363. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +1 -1
  364. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +2 -2
  365. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +1 -1
  366. package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +2 -2
  367. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +1 -1
  368. package/packages/omo-codex/plugin/skills/ulw-research/AGENTS.md +21 -3
  369. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +37 -12
  370. package/packages/omo-codex/plugin/skills/ulw-research/references/deliverable-phase.md +77 -16
  371. package/packages/omo-codex/plugin/skills/ulw-research/references/fact-ledger-grammar.md +134 -0
  372. package/packages/omo-codex/plugin/skills/ulw-research/references/fact-ledger.md +95 -0
  373. package/packages/omo-codex/plugin/skills/ulw-research/references/fidelity-claim-kinds.md +19 -0
  374. package/packages/omo-codex/plugin/skills/ulw-research/references/report-gates.md +68 -3
  375. package/packages/omo-codex/plugin/skills/ulw-research/references/report-visualization.md +2 -0
  376. package/packages/omo-codex/plugin/skills/ulw-research/references/unit-rules.md +157 -0
  377. package/packages/omo-codex/plugin/skills/ulw-research/scripts/claim-kinds.mjs +116 -0
  378. package/packages/omo-codex/plugin/skills/ulw-research/scripts/claims-index.mjs +125 -0
  379. package/packages/omo-codex/plugin/skills/ulw-research/scripts/cli-support.mjs +19 -5
  380. package/packages/omo-codex/plugin/skills/ulw-research/scripts/contracts.mjs +89 -3
  381. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-meaning.mjs +191 -0
  382. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-verify.mjs +164 -0
  383. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands.mjs +239 -0
  384. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-derive.mjs +66 -0
  385. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-expr.mjs +108 -0
  386. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-fill.mjs +194 -0
  387. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-ledger-kinds.mjs +250 -0
  388. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-ledger-schema.mjs +221 -0
  389. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-ledger.mjs +123 -0
  390. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-locate.mjs +231 -0
  391. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-pairs.mjs +187 -0
  392. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-recompute.mjs +89 -0
  393. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-binding.mjs +130 -0
  394. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-brief.mjs +150 -0
  395. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-claims.mjs +89 -0
  396. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-lexicon.mjs +145 -0
  397. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-records.mjs +163 -0
  398. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-state.mjs +64 -0
  399. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-trace.mjs +85 -0
  400. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-values.mjs +229 -0
  401. package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-fidelity.mjs +113 -0
  402. package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-static.mjs +29 -9
  403. package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-structure.mjs +1 -1
  404. package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-text.mjs +1 -27
  405. package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-lite.mjs +2 -2
  406. package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-markup.mjs +182 -0
  407. package/packages/omo-codex/plugin/skills/ulw-research/scripts/lexicon.mjs +47 -0
  408. package/packages/omo-codex/plugin/skills/ulw-research/scripts/md-lite.mjs +193 -0
  409. package/packages/omo-codex/plugin/skills/ulw-research/scripts/meaning-check.mjs +196 -0
  410. package/packages/omo-codex/plugin/skills/ulw-research/scripts/numerals.mjs +226 -0
  411. package/packages/omo-codex/plugin/skills/ulw-research/scripts/outcome.mjs +8 -8
  412. package/packages/omo-codex/plugin/skills/ulw-research/scripts/particles-ko.mjs +108 -0
  413. package/packages/omo-codex/plugin/skills/ulw-research/scripts/placeholder.mjs +184 -0
  414. package/packages/omo-codex/plugin/skills/ulw-research/scripts/polish-apply.mjs +115 -0
  415. package/packages/omo-codex/plugin/skills/ulw-research/scripts/polish-diff.mjs +31 -0
  416. package/packages/omo-codex/plugin/skills/ulw-research/scripts/polish-project.mjs +125 -0
  417. package/packages/omo-codex/plugin/skills/ulw-research/scripts/polish-rules.mjs +170 -0
  418. package/packages/omo-codex/plugin/skills/ulw-research/scripts/rational.mjs +139 -0
  419. package/packages/omo-codex/plugin/skills/ulw-research/scripts/report-tools-commands.mjs +21 -10
  420. package/packages/omo-codex/plugin/skills/ulw-research/scripts/report-tools.mjs +15 -0
  421. package/packages/omo-codex/plugin/skills/ulw-research/scripts/sentence-split.mjs +77 -0
  422. package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-commands.mjs +140 -0
  423. package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-snapshot.mjs +176 -0
  424. package/packages/omo-codex/plugin/skills/ulw-research/scripts/text-normalize.mjs +82 -0
  425. package/packages/omo-codex/plugin/skills/ulw-research/scripts/text-similarity.mjs +28 -0
  426. package/packages/omo-codex/plugin/skills/ulw-research/scripts/unit-algebra.mjs +101 -0
  427. package/packages/omo-codex/plugin/skills/ulw-research/scripts/unit-errors.mjs +23 -0
  428. package/packages/omo-codex/plugin/skills/ulw-research/scripts/unit-metadata.mjs +31 -0
  429. package/packages/omo-codex/plugin/skills/ulw-research/scripts/unit-pairs.mjs +72 -0
  430. package/packages/omo-codex/plugin/skills/ulw-research/scripts/unit-precision.mjs +44 -0
  431. package/packages/omo-codex/plugin/skills/ulw-research/scripts/unit-rules-shapes.mjs +64 -0
  432. package/packages/omo-codex/plugin/skills/ulw-research/scripts/unit-rules.mjs +173 -0
  433. package/packages/omo-codex/plugin/skills/ulw-research/scripts/units.mjs +105 -0
  434. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +71 -64
  435. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +4 -1
  436. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +19 -0
  437. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +12 -8
  438. package/packages/omo-codex/scripts/install-dist/install-local.mjs +169 -30
  439. package/packages/shared-skills/skills/ast-grep/AGENTS.md +1 -1
  440. package/packages/shared-skills/skills/browser/SKILL.md +21 -22
  441. package/packages/shared-skills/skills/browser/references/commands.md +2 -9
  442. package/packages/shared-skills/skills/browser/references/install.md +1 -2
  443. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +1 -1
  444. package/packages/shared-skills/skills/browser/scripts/browser-doctor.mjs +2 -2
  445. package/packages/shared-skills/skills/browser/scripts/browser-engine-guard.mjs +63 -487
  446. package/packages/shared-skills/skills/browser/scripts/browser-install.mjs +1 -1
  447. package/packages/shared-skills/skills/browser/scripts/omowright.mjs +1 -10
  448. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +2 -2
  449. package/packages/shared-skills/skills/frontend/SKILL.md +79 -118
  450. package/packages/shared-skills/skills/frontend/references/design/README.md +75 -224
  451. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +32 -27
  452. package/packages/shared-skills/skills/frontend/references/perfection/README.md +2 -2
  453. package/packages/shared-skills/skills/frontend/scripts/perfection/check-accent-stripes.ts +8 -24
  454. package/packages/shared-skills/skills/frontend/scripts/perfection/check-draft-guard.test.ts +101 -0
  455. package/packages/shared-skills/skills/frontend/scripts/perfection/check-draft-guard.ts +40 -0
  456. package/packages/shared-skills/skills/frontend/scripts/perfection/collect-files.test.ts +50 -0
  457. package/packages/shared-skills/skills/frontend/scripts/perfection/collect-files.ts +53 -0
  458. package/packages/shared-skills/skills/frontend/scripts/perfection/draft-guard/findings.ts +16 -0
  459. package/packages/shared-skills/skills/frontend/scripts/perfection/draft-guard/lint.ts +38 -0
  460. package/packages/shared-skills/skills/frontend/scripts/perfection/draft-guard/rules.ts +69 -0
  461. package/packages/shared-skills/skills/frontend/scripts/perfection/draft-guard/text-nodes.ts +121 -0
  462. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/attr-lookalikes.tsx +10 -0
  463. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/bound-values.tsx +12 -0
  464. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/const-generics.tsx +3 -0
  465. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/generics.tsx +7 -0
  466. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/measured-stats.html +6 -0
  467. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/plain-copy.html +9 -0
  468. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/state-copy.html +11 -0
  469. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/attribute-edges.html +7 -0
  470. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/components.tsx +16 -0
  471. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/decorative-badge.vue +7 -0
  472. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/emoji-icons.tsx +9 -0
  473. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/jsx-edges.tsx +1 -0
  474. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/promo-copy.html +6 -0
  475. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/promo-copy.tsx +8 -0
  476. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/vanity-stats.html +5 -0
  477. package/packages/shared-skills/skills/programming/SKILL.md +10 -7
  478. package/packages/shared-skills/skills/programming/references/typescript/README.md +10 -7
  479. package/packages/shared-skills/skills/programming/references/typescript/bootstrap.md +9 -23
  480. package/packages/shared-skills/skills/programming/references/typescript/oxc-lint.md +130 -0
  481. package/packages/shared-skills/skills/programming/references/typescript/tsconfig-strict.md +6 -62
  482. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.ts +12 -12
  483. package/packages/shared-skills/skills/programming/scripts/typescript/new-project.test.ts +162 -0
  484. package/packages/shared-skills/skills/programming/scripts/typescript/new-project.ts +20 -81
  485. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/.oxfmtrc.json +9 -0
  486. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/.oxlintrc.json +46 -0
  487. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/LICENSE +21 -0
  488. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/index.js +10 -0
  489. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/no-em-dash-copy.js +28 -0
  490. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/require-suppression-reason.js +62 -0
  491. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/tsconfig.json +29 -0
  492. package/packages/shared-skills/skills/refactor/SKILL.md +13 -13
  493. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +1 -1
  494. package/packages/shared-skills/skills/ulw-execute/SKILL.md +1 -1
  495. package/packages/shared-skills/skills/ulw-research/AGENTS.md +21 -3
  496. package/packages/shared-skills/skills/ulw-research/SKILL.md +37 -12
  497. package/packages/shared-skills/skills/ulw-research/references/deliverable-phase.md +77 -16
  498. package/packages/shared-skills/skills/ulw-research/references/fact-ledger-grammar.md +134 -0
  499. package/packages/shared-skills/skills/ulw-research/references/fact-ledger.md +95 -0
  500. package/packages/shared-skills/skills/ulw-research/references/fidelity-claim-kinds.md +19 -0
  501. package/packages/shared-skills/skills/ulw-research/references/report-gates.md +68 -3
  502. package/packages/shared-skills/skills/ulw-research/references/report-visualization.md +2 -0
  503. package/packages/shared-skills/skills/ulw-research/references/unit-rules.md +157 -0
  504. package/packages/shared-skills/skills/ulw-research/scripts/claim-kinds.mjs +116 -0
  505. package/packages/shared-skills/skills/ulw-research/scripts/claim-kinds.test.ts +193 -0
  506. package/packages/shared-skills/skills/ulw-research/scripts/claims-index.mjs +125 -0
  507. package/packages/shared-skills/skills/ulw-research/scripts/claims-index.test.ts +149 -0
  508. package/packages/shared-skills/skills/ulw-research/scripts/cli-support.mjs +19 -5
  509. package/packages/shared-skills/skills/ulw-research/scripts/cli-support.test.ts +13 -2
  510. package/packages/shared-skills/skills/ulw-research/scripts/contracts.mjs +89 -3
  511. package/packages/shared-skills/skills/ulw-research/scripts/contracts.test.ts +100 -12
  512. package/packages/shared-skills/skills/ulw-research/scripts/copy-returns.test.ts +183 -0
  513. package/packages/shared-skills/skills/ulw-research/scripts/delivery-barrier.test.ts +245 -0
  514. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-meaning.mjs +191 -0
  515. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-verify.mjs +164 -0
  516. package/packages/shared-skills/skills/ulw-research/scripts/fact-commands.mjs +239 -0
  517. package/packages/shared-skills/skills/ulw-research/scripts/fact-derive.mjs +66 -0
  518. package/packages/shared-skills/skills/ulw-research/scripts/fact-derive.test.ts +375 -0
  519. package/packages/shared-skills/skills/ulw-research/scripts/fact-expr.mjs +108 -0
  520. package/packages/shared-skills/skills/ulw-research/scripts/fact-fill.mjs +194 -0
  521. package/packages/shared-skills/skills/ulw-research/scripts/fact-fill.test.ts +221 -0
  522. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-grammar.test.ts +197 -0
  523. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-kinds.mjs +250 -0
  524. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-kinds.test.ts +156 -0
  525. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-legacy.test.ts +160 -0
  526. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-schema.mjs +221 -0
  527. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-schema.test.ts +43 -0
  528. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger.mjs +123 -0
  529. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger.test.ts +254 -0
  530. package/packages/shared-skills/skills/ulw-research/scripts/fact-locate.mjs +231 -0
  531. package/packages/shared-skills/skills/ulw-research/scripts/fact-locate.test.ts +118 -0
  532. package/packages/shared-skills/skills/ulw-research/scripts/fact-pairs.mjs +187 -0
  533. package/packages/shared-skills/skills/ulw-research/scripts/fact-pairs.test.ts +167 -0
  534. package/packages/shared-skills/skills/ulw-research/scripts/fact-recompute.mjs +89 -0
  535. package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-dimensions.test.ts +409 -0
  536. package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-rules.test.ts +388 -0
  537. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-binding.mjs +130 -0
  538. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-binding.test.ts +81 -0
  539. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-brief.mjs +150 -0
  540. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-brief.test.ts +179 -0
  541. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-claims.mjs +89 -0
  542. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-lexicon.mjs +145 -0
  543. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-lexicon.test.ts +117 -0
  544. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-records.mjs +163 -0
  545. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-state.mjs +64 -0
  546. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-state.test.ts +46 -0
  547. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-trace.mjs +85 -0
  548. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-trace.test.ts +58 -0
  549. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-values.mjs +229 -0
  550. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-values.test.ts +270 -0
  551. package/packages/shared-skills/skills/ulw-research/scripts/gates-context.test.ts +64 -0
  552. package/packages/shared-skills/skills/ulw-research/scripts/gates-fidelity.mjs +113 -0
  553. package/packages/shared-skills/skills/ulw-research/scripts/gates-fidelity.test.ts +73 -0
  554. package/packages/shared-skills/skills/ulw-research/scripts/gates-static.mjs +29 -9
  555. package/packages/shared-skills/skills/ulw-research/scripts/gates-structure.mjs +1 -1
  556. package/packages/shared-skills/skills/ulw-research/scripts/gates-text.mjs +1 -27
  557. package/packages/shared-skills/skills/ulw-research/scripts/html-lite.mjs +2 -2
  558. package/packages/shared-skills/skills/ulw-research/scripts/html-markup.mjs +182 -0
  559. package/packages/shared-skills/skills/ulw-research/scripts/lexicon.mjs +47 -0
  560. package/packages/shared-skills/skills/ulw-research/scripts/lexicon.test.ts +57 -0
  561. package/packages/shared-skills/skills/ulw-research/scripts/md-lite.mjs +193 -0
  562. package/packages/shared-skills/skills/ulw-research/scripts/md-lite.test.ts +271 -0
  563. package/packages/shared-skills/skills/ulw-research/scripts/meaning-check.mjs +196 -0
  564. package/packages/shared-skills/skills/ulw-research/scripts/meaning-check.test.ts +228 -0
  565. package/packages/shared-skills/skills/ulw-research/scripts/numerals.mjs +226 -0
  566. package/packages/shared-skills/skills/ulw-research/scripts/numerals.test.ts +120 -0
  567. package/packages/shared-skills/skills/ulw-research/scripts/outcome.mjs +8 -8
  568. package/packages/shared-skills/skills/ulw-research/scripts/outcome.test.ts +29 -0
  569. package/packages/shared-skills/skills/ulw-research/scripts/particles-ko.mjs +108 -0
  570. package/packages/shared-skills/skills/ulw-research/scripts/particles-ko.test.ts +86 -0
  571. package/packages/shared-skills/skills/ulw-research/scripts/placeholder.mjs +184 -0
  572. package/packages/shared-skills/skills/ulw-research/scripts/placeholder.test.ts +77 -0
  573. package/packages/shared-skills/skills/ulw-research/scripts/polish-apply.mjs +115 -0
  574. package/packages/shared-skills/skills/ulw-research/scripts/polish-apply.test.ts +363 -0
  575. package/packages/shared-skills/skills/ulw-research/scripts/polish-diff.mjs +31 -0
  576. package/packages/shared-skills/skills/ulw-research/scripts/polish-diff.test.ts +168 -0
  577. package/packages/shared-skills/skills/ulw-research/scripts/polish-markup.test.ts +187 -0
  578. package/packages/shared-skills/skills/ulw-research/scripts/polish-project.mjs +125 -0
  579. package/packages/shared-skills/skills/ulw-research/scripts/polish-rules.mjs +170 -0
  580. package/packages/shared-skills/skills/ulw-research/scripts/rational.mjs +139 -0
  581. package/packages/shared-skills/skills/ulw-research/scripts/rational.test.ts +46 -0
  582. package/packages/shared-skills/skills/ulw-research/scripts/report-tools-commands.mjs +21 -10
  583. package/packages/shared-skills/skills/ulw-research/scripts/report-tools.mjs +15 -0
  584. package/packages/shared-skills/skills/ulw-research/scripts/report-tools.test.ts +458 -2
  585. package/packages/shared-skills/skills/ulw-research/scripts/sentence-split.mjs +77 -0
  586. package/packages/shared-skills/skills/ulw-research/scripts/sentence-split.test.ts +109 -0
  587. package/packages/shared-skills/skills/ulw-research/scripts/source-commands.mjs +140 -0
  588. package/packages/shared-skills/skills/ulw-research/scripts/source-snapshot.mjs +176 -0
  589. package/packages/shared-skills/skills/ulw-research/scripts/source-snapshot.test.ts +113 -0
  590. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/assets/share.csv +3 -0
  591. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/claim-graph.md +13 -0
  592. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/gen-legacy-dev.mjs +89 -0
  593. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/ledger-basic.json +223 -0
  594. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/ledger-legacy-dev.json +859 -0
  595. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/ledger-verify.json +420 -0
  596. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/report-bad.html +19 -0
  597. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/report-good.html +39 -0
  598. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S4/acronyms.json +3 -0
  599. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S4/meta.json +9 -0
  600. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S4/sentences.jsonl +7 -0
  601. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S4/text.txt +7 -0
  602. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S4.html +19 -0
  603. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S5/acronyms.json +1 -0
  604. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S5/meta.json +9 -0
  605. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S5/sentences.jsonl +1 -0
  606. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S5/text.txt +1 -0
  607. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/sources/S9.txt +1 -0
  608. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity-brief-locked.md +17 -0
  609. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity-brief-pending.md +17 -0
  610. package/packages/shared-skills/skills/ulw-research/scripts/text-normalize.mjs +82 -0
  611. package/packages/shared-skills/skills/ulw-research/scripts/text-normalize.test.ts +73 -0
  612. package/packages/shared-skills/skills/ulw-research/scripts/text-similarity.mjs +28 -0
  613. package/packages/shared-skills/skills/ulw-research/scripts/text-similarity.test.ts +38 -0
  614. package/packages/shared-skills/skills/ulw-research/scripts/unit-algebra.mjs +101 -0
  615. package/packages/shared-skills/skills/ulw-research/scripts/unit-errors.mjs +23 -0
  616. package/packages/shared-skills/skills/ulw-research/scripts/unit-metadata.mjs +31 -0
  617. package/packages/shared-skills/skills/ulw-research/scripts/unit-pairs.mjs +72 -0
  618. package/packages/shared-skills/skills/ulw-research/scripts/unit-precision.mjs +44 -0
  619. package/packages/shared-skills/skills/ulw-research/scripts/unit-rules-shapes.mjs +64 -0
  620. package/packages/shared-skills/skills/ulw-research/scripts/unit-rules.mjs +173 -0
  621. package/packages/shared-skills/skills/ulw-research/scripts/units.mjs +105 -0
  622. package/packages/shared-skills/skills/ulw-research/scripts/units.test.ts +83 -0
  623. package/packages/shared-skills/skills/visual-qa/SKILL.md +70 -63
  624. package/packages/shared-skills/skills/visual-qa/scripts/skill-doc-fields.test.ts +34 -0
  625. package/script/qa/web-terminal-visual-qa.mjs +6 -2
  626. package/script/qa/xterm-live-terminal.mjs +26 -3
@@ -0,0 +1,101 @@
1
+ import { describe, expect, test } from "bun:test"
2
+ import { spawnSync } from "node:child_process"
3
+ import { readdirSync, readFileSync } from "node:fs"
4
+ import { join } from "node:path"
5
+ import type { DraftRuleId } from "./draft-guard/findings"
6
+ import { lintDraft } from "./draft-guard/lint"
7
+
8
+ const FIXTURES = join(import.meta.dir, "fixtures", "draft-guard")
9
+ const ACCENT_FIXTURES = join(import.meta.dir, "fixtures", "accent-stripes")
10
+ const SCRIPT = join(import.meta.dir, "check-draft-guard.ts")
11
+
12
+ const EXPECTED: Readonly<Record<string, ReadonlyArray<[number, DraftRuleId]>>> = {
13
+ "promo-copy.html": [[2, "promo-copy"], [3, "promo-copy"], [5, "promo-copy"]],
14
+ "promo-copy.tsx": [[4, "promo-copy"], [5, "promo-copy"]],
15
+ "emoji-icons.tsx": [[4, "emoji-icon"], [6, "emoji-icon"]],
16
+ "vanity-stats.html": [[2, "vanity-stat"], [3, "vanity-stat"], [4, "vanity-stat"]],
17
+ "decorative-badge.vue": [[3, "decorative-badge"], [4, "decorative-badge"]],
18
+ "components.tsx": [
19
+ [5, "decorative-badge"],
20
+ [6, "decorative-badge"],
21
+ [7, "emoji-icon"],
22
+ [7, "decorative-badge"],
23
+ [8, "emoji-icon"],
24
+ [9, "emoji-icon"],
25
+ [10, "vanity-stat"],
26
+ [11, "vanity-stat"],
27
+ [12, "vanity-stat"],
28
+ [13, "promo-copy"],
29
+ ],
30
+ "attribute-edges.html": [[2, "promo-copy"], [3, "promo-copy"], [4, "vanity-stat"], [5, "decorative-badge"], [6, "promo-copy"]],
31
+ "jsx-edges.tsx": [[1, "promo-copy"]],
32
+ }
33
+
34
+ function lintFixture(dir: string, name: string) {
35
+ const path = join(FIXTURES, dir, name)
36
+ return lintDraft([{ path, text: readFileSync(path, "utf8") }])
37
+ }
38
+
39
+ describe("#given a positive fixture with a generated-look tell in its markup", () => {
40
+ test("#then every positive fixture has an expectation", () => {
41
+ expect(readdirSync(join(FIXTURES, "positive")).sort()).toEqual(Object.keys(EXPECTED).sort())
42
+ })
43
+
44
+ for (const [name, expected] of Object.entries(EXPECTED)) {
45
+ test(`#when ${name} is linted #then it reports exactly ${expected.length} finding(s) at the expected lines`, () => {
46
+ const findings = lintFixture("positive", name).map((f): [number, DraftRuleId] => [f.line, f.rule])
47
+ expect(findings).toEqual([...expected])
48
+ })
49
+ }
50
+ })
51
+
52
+ describe("#given a negative fixture (plain copy, code, scripts, styles, comments, bound values, status badges)", () => {
53
+ for (const name of readdirSync(join(FIXTURES, "negative"))) {
54
+ test(`#when ${name} is linted #then it reports nothing`, () => {
55
+ expect(lintFixture("negative", name)).toEqual([])
56
+ })
57
+ }
58
+ })
59
+
60
+ describe("#given a generated page written on one line", () => {
61
+ test("#when it holds two promo phrases #then both are reported, each at its own column", () => {
62
+ const text = "<p>Seamless sync and effortless setup</p>\n"
63
+ const findings = lintDraft([{ path: "page.html", text }])
64
+ expect(findings.map((f) => [f.line, f.column, f.rule])).toEqual([
65
+ [1, text.indexOf("Seamless") + 1, "promo-copy"],
66
+ [1, text.indexOf("effortless") + 1, "promo-copy"],
67
+ ])
68
+ })
69
+ })
70
+
71
+ describe("#given a stylesheet", () => {
72
+ test("#when it is linted #then text rules are not applied to CSS", () => {
73
+ expect(lintDraft([{ path: "a.css", text: '.hero::before { content: "Unlock πŸš€"; }\n' }])).toEqual([])
74
+ })
75
+ })
76
+
77
+ describe("#given the CLI", () => {
78
+ const run = (...args: string[]) => spawnSync(process.execPath, [SCRIPT, ...args], { encoding: "utf8", timeout: 30_000 })
79
+
80
+ test("#when it scans the draft-guard positives #then it exits 1 and prints file:line findings", () => {
81
+ const result = run(join(FIXTURES, "positive"))
82
+ expect(result.status).toBe(1)
83
+ expect(result.stdout).toMatch(/vanity-stats\.html:2:\d+ {2}vanity-stat/)
84
+ })
85
+
86
+ test("#when it scans an accent-stripe positive #then the accent-stripe rules still report through it", () => {
87
+ const result = run("--json", join(ACCENT_FIXTURES, "positive", "border-top-card.css"))
88
+ expect(JSON.parse(result.stdout)).toEqual([expect.objectContaining({ line: 4, rule: "edge-stripe" })])
89
+ expect(result.status).toBe(1)
90
+ })
91
+
92
+ test("#when it scans both negative fixture sets #then it exits 0", () => {
93
+ expect(run(join(FIXTURES, "negative"), join(ACCENT_FIXTURES, "negative")).status).toBe(0)
94
+ })
95
+
96
+ test("#when no path is given #then it exits 2 with usage", () => {
97
+ const result = run()
98
+ expect(result.status).toBe(2)
99
+ expect(result.stderr).toContain("usage:")
100
+ })
101
+ })
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env bun
2
+ // The draft guard in one command: accent stripes plus generated-look copy and markup (promo copy, emoji icons, hype badges, vanity stats).
3
+ // Usage: bun check-draft-guard.ts [--json] <file-or-dir>... Exit 0 clean, 1 findings, 2 usage or unreadable target.
4
+ import { readFileSync } from "node:fs"
5
+ import { RULE_MESSAGES } from "./accent-stripes/findings"
6
+ import { lintFiles, type SourceFile } from "./accent-stripes/lint"
7
+ import { collectFiles } from "./collect-files"
8
+ import { DRAFT_RULE_MESSAGES } from "./draft-guard/findings"
9
+ import { lintDraft } from "./draft-guard/lint"
10
+
11
+ const MESSAGES: Readonly<Record<string, string>> = { ...RULE_MESSAGES, ...DRAFT_RULE_MESSAGES }
12
+
13
+ function main(argv: readonly string[]): number {
14
+ const json = argv.includes("--json")
15
+ const targets = argv.filter((a) => a !== "--json")
16
+ if (targets.length === 0) {
17
+ process.stderr.write("usage: check-draft-guard.ts [--json] <file-or-dir>...\n")
18
+ return 2
19
+ }
20
+ const { paths, missing } = collectFiles(targets)
21
+ if (missing.length > 0) {
22
+ process.stderr.write(`check-draft-guard: cannot read ${missing.join(", ")}\n`)
23
+ return 2
24
+ }
25
+ const files: SourceFile[] = paths.map((path) => ({ path, text: readFileSync(path, "utf8") }))
26
+ const findings = [...lintFiles(files), ...lintDraft(files)].sort(
27
+ (a, b) => a.file.localeCompare(b.file) || a.line - b.line || a.column - b.column,
28
+ )
29
+ if (json) process.stdout.write(`${JSON.stringify(findings, null, 2)}\n`)
30
+ else {
31
+ for (const f of findings) {
32
+ process.stdout.write(`${f.file}:${f.line}:${f.column} ${f.rule} ${MESSAGES[f.rule]}\n > ${f.excerpt}\n`)
33
+ }
34
+ const summary = findings.length === 0 ? "clean" : `${findings.length} finding(s); fix each before visual QA`
35
+ process.stdout.write(`check-draft-guard: ${paths.length} file(s), ${summary}\n`)
36
+ }
37
+ return findings.length === 0 ? 0 : 1
38
+ }
39
+
40
+ process.exitCode = main(process.argv.slice(2))
@@ -0,0 +1,50 @@
1
+ import { describe, expect, test } from "bun:test"
2
+ import { chmodSync, mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from "node:fs"
3
+ import { tmpdir } from "node:os"
4
+ import { join } from "node:path"
5
+ import { collectFiles } from "./collect-files"
6
+
7
+ // Owner test for the file-walk contract both perfection CLIs share (check-accent-stripes.ts, check-draft-guard.ts).
8
+ function withDir(run: (dir: string) => void): void {
9
+ const dir = mkdtempSync(join(tmpdir(), "collect-files-"))
10
+ try {
11
+ run(dir)
12
+ } finally {
13
+ chmodSync(dir, 0o700)
14
+ rmSync(dir, { recursive: true, force: true })
15
+ }
16
+ }
17
+
18
+ // Permission bits do not stop root, and Windows ignores chmod, so the unreadable-directory case cannot be built there.
19
+ const cannotBuildUnreadableDir = process.platform === "win32" || process.getuid?.() === 0
20
+
21
+ describe("#given a scanned directory", () => {
22
+ test("#when it holds a dangling symlink #then the link is skipped and the rest is collected", () => {
23
+ withDir((dir) => {
24
+ symlinkSync(join(dir, "missing-target"), join(dir, "broken-link.tsx"))
25
+ writeFileSync(join(dir, "page.html"), "<p>ok</p>\n")
26
+ expect(collectFiles([dir])).toEqual({ paths: [join(dir, "page.html")], missing: [] })
27
+ })
28
+ })
29
+
30
+ test.skipIf(cannotBuildUnreadableDir)("#when a nested directory cannot be listed #then it is skipped and the rest is collected", () => {
31
+ withDir((dir) => {
32
+ const locked = join(dir, "locked")
33
+ mkdirSync(locked)
34
+ writeFileSync(join(locked, "hidden.css"), ".a {}\n")
35
+ writeFileSync(join(dir, "page.html"), "<p>ok</p>\n")
36
+ chmodSync(locked, 0o000)
37
+ try {
38
+ expect(collectFiles([dir])).toEqual({ paths: [join(dir, "page.html")], missing: [] })
39
+ } finally {
40
+ chmodSync(locked, 0o700)
41
+ }
42
+ })
43
+ })
44
+
45
+ test("#when an explicit target does not exist #then it is reported as missing", () => {
46
+ withDir((dir) => {
47
+ expect(collectFiles([join(dir, "nope")])).toEqual({ paths: [], missing: [join(dir, "nope")] })
48
+ })
49
+ })
50
+ })
@@ -0,0 +1,53 @@
1
+ import { readdirSync, statSync, type Stats } from "node:fs"
2
+ import { join } from "node:path"
3
+
4
+ const SCANNED = /\.(?:css|scss|less|pcss|postcss|html?|[cm]?[jt]sx?|vue|svelte|astro)$/i
5
+ const SKIPPED_DIRS = new Set([
6
+ "node_modules", ".git", "dist", "build", "out", ".next", ".nuxt", ".svelte-kit", ".astro",
7
+ ".turbo", ".cache", "coverage", "vendor", ".vercel", ".output",
8
+ ])
9
+ const MAX_BYTES = 1_000_000
10
+
11
+ function statOrNull(path: string): Stats | null {
12
+ try {
13
+ return statSync(path)
14
+ } catch {
15
+ return null
16
+ }
17
+ }
18
+
19
+ function entriesOrNull(path: string): string[] | null {
20
+ try {
21
+ return readdirSync(path)
22
+ } catch {
23
+ return null
24
+ }
25
+ }
26
+
27
+ /** Lintable source files under the targets; dangling links and unreadable entries are skipped, an unreadable explicit target is reported. */
28
+ export function collectFiles(targets: readonly string[]): { readonly paths: string[]; readonly missing: string[] } {
29
+ const paths: string[] = []
30
+ const missing: string[] = []
31
+ const walk = (path: string, explicit: boolean): void => {
32
+ const stat = statOrNull(path)
33
+ if (!stat) {
34
+ if (explicit) missing.push(path)
35
+ return
36
+ }
37
+ if (stat.isDirectory()) {
38
+ const entries = entriesOrNull(path)
39
+ if (entries === null) {
40
+ if (explicit) missing.push(path)
41
+ return
42
+ }
43
+ for (const entry of entries) {
44
+ if (!SKIPPED_DIRS.has(entry)) walk(join(path, entry), false)
45
+ }
46
+ return
47
+ }
48
+ const minified = /\.min\.[a-z]+$/i.test(path) || path.endsWith(".d.ts")
49
+ if (SCANNED.test(path) && !minified && stat.size <= MAX_BYTES) paths.push(path)
50
+ }
51
+ for (const target of targets) walk(target, true)
52
+ return { paths, missing }
53
+ }
@@ -0,0 +1,16 @@
1
+ export type DraftRuleId = "promo-copy" | "emoji-icon" | "decorative-badge" | "vanity-stat"
2
+
3
+ export type DraftFinding = {
4
+ readonly file: string
5
+ readonly line: number
6
+ readonly column: number
7
+ readonly rule: DraftRuleId
8
+ readonly excerpt: string
9
+ }
10
+
11
+ export const DRAFT_RULE_MESSAGES: Readonly<Record<DraftRuleId, string>> = {
12
+ "promo-copy": "promotional filler in visible copy; say what the screen does or shows instead",
13
+ "emoji-icon": "emoji used as an icon or bullet; use an SVG icon from the project's icon set, or nothing",
14
+ "decorative-badge": "badge or chip carrying a hype label instead of a state; remove it or show a real status",
15
+ "vanity-stat": "stat tile with a marketing-form number (10x, 500+, 24/7); show the measured figure with its unit and period, or remove the tile",
16
+ }
@@ -0,0 +1,38 @@
1
+ import { lineLocator } from "../accent-stripes/findings"
2
+ import type { SourceFile } from "../accent-stripes/lint"
3
+ import type { DraftFinding } from "./findings"
4
+ import { checkNode } from "./rules"
5
+ import { type MarkupKind, textNodes } from "./text-nodes"
6
+
7
+ function markupKind(path: string): MarkupKind | null {
8
+ if (/\.html?$/i.test(path)) return "html"
9
+ if (/\.[cm]?[jt]sx$/i.test(path)) return "jsx"
10
+ if (/\.(?:vue|svelte|astro)$/i.test(path)) return "sfc"
11
+ return null
12
+ }
13
+
14
+ function excerptAt(text: string, offset: number): string {
15
+ const lineStart = text.lastIndexOf("\n", offset - 1) + 1
16
+ const lineEnd = text.indexOf("\n", offset)
17
+ return text.slice(lineStart, lineEnd < 0 ? undefined : lineEnd).trim().slice(0, 140)
18
+ }
19
+
20
+ export function lintDraft(files: readonly SourceFile[]): DraftFinding[] {
21
+ const findings: DraftFinding[] = []
22
+ for (const file of files) {
23
+ const kind = markupKind(file.path)
24
+ if (kind === null) continue
25
+ const locate = lineLocator(file.text)
26
+ const seen = new Set<string>()
27
+ for (const node of textNodes(file.text, kind)) {
28
+ for (const hit of checkNode(node)) {
29
+ const at = locate(hit.offset)
30
+ const key = `${hit.offset}:${hit.rule}`
31
+ if (seen.has(key)) continue
32
+ seen.add(key)
33
+ findings.push({ file: file.path, ...at, rule: hit.rule, excerpt: excerptAt(file.text, hit.offset) })
34
+ }
35
+ }
36
+ }
37
+ return findings.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line || a.column - b.column)
38
+ }
@@ -0,0 +1,69 @@
1
+ import type { DraftRuleId } from "./findings"
2
+ import { type Element, isStatElement, type TextNode } from "./text-nodes"
3
+
4
+ export type RuleHit = { readonly rule: DraftRuleId; readonly offset: number }
5
+
6
+ const PROMO_PHRASES = new RegExp(
7
+ [
8
+ String.raw`\bseamless(?:ly)?\b`,
9
+ String.raw`\beffortless(?:ly)?\b`,
10
+ String.raw`\bsupercharge[sd]?\b`,
11
+ String.raw`\bunlock (?:the (?:full )?power|the full potential|your (?:full )?potential)\b`,
12
+ String.raw`\bat a glance\b`,
13
+ String.raw`\bcutting[- ]edge\b`,
14
+ String.raw`\bgame[- ]chang(?:er|ing)\b`,
15
+ String.raw`\brevolutioni[sz]e\b`,
16
+ String.raw`\bnext[- ]level\b`,
17
+ String.raw`\bworld[- ]class\b`,
18
+ String.raw`\belevate your\b`,
19
+ "ν•œλˆˆμ—",
20
+ "μ†μ‰½κ²Œ",
21
+ "μŠ€λ§ˆνŠΈν•œ",
22
+ "ν˜μ‹ μ μΈ",
23
+ ].join("|"),
24
+ "giu",
25
+ )
26
+
27
+ const EMOJI = /\p{Emoji_Presentation}|\p{Extended_Pictographic}\uFE0F/u
28
+ const EMOJI_ALL = /\p{Emoji_Presentation}|\p{Extended_Pictographic}\uFE0F?/gu
29
+ const NUMERIC_ENTITY = /&#(?:x([0-9a-f]+)|(\d+));/gi
30
+ const BADGE_CLASS = /^(?:badge|chip|pill|tag)(?:$|[-_])/
31
+ const BADGE_COMPONENT = /^(?:Badge|Chip|Pill|Tag)$/
32
+ const HYPE_LABEL = /^(?:new!?|hot|trending|popular|featured|ai|ai[- ]powered|premium|recommended|best|μ‹ κ·œ|인기|μΆ”μ²œ|베슀트)$/i
33
+ const AMOUNT = String.raw`(?:\d{1,3}(?:[.,]\d{3})+|\d+)(?:[.,]\d+)?`
34
+ const MARKETING_NUMBER = new RegExp(String.raw`^(?:[$€£Β₯β‚©]?${AMOUNT}\s*(?:[kmb]|%)?\s*\+|${AMOUNT}\s*[xΓ—]|24\/7)$`, "i")
35
+
36
+ const isBadge = (element: Element | undefined): boolean =>
37
+ element !== undefined && !element.stateful && (BADGE_COMPONENT.test(element.name) || element.classes.some((c) => BADGE_CLASS.test(c)))
38
+
39
+ function leadingOffset(node: TextNode): number {
40
+ return node.offset + (node.text.length - node.text.trimStart().length)
41
+ }
42
+
43
+ function emojiOffset(text: string): number | null {
44
+ const direct = EMOJI.exec(text)
45
+ if (direct) return direct.index
46
+ for (const m of text.matchAll(NUMERIC_ENTITY)) {
47
+ const code = m[1] === undefined ? Number(m[2]) : Number.parseInt(m[1], 16)
48
+ if (Number.isInteger(code) && code <= 0x10ffff && EMOJI.test(String.fromCodePoint(code))) return m.index ?? 0
49
+ }
50
+ return null
51
+ }
52
+
53
+ /** A stat is a vanity number only in marketing form (10x, 500+, $2M+, 24/7); a measured figure such as 42% or 1.2k passes. */
54
+ export function checkNode(node: TextNode): RuleHit[] {
55
+ const hits: RuleHit[] = []
56
+ const label = node.text.trim()
57
+ if (node.kind !== "value") {
58
+ for (const m of node.text.matchAll(PROMO_PHRASES)) hits.push({ rule: "promo-copy", offset: node.offset + (m.index ?? 0) })
59
+ const emoji = emojiOffset(node.text)
60
+ if (emoji !== null) hits.push({ rule: "emoji-icon", offset: node.offset + emoji })
61
+ }
62
+ if (node.kind === "text" && isBadge(node.stack.at(-1)) && HYPE_LABEL.test(label.replace(EMOJI_ALL, "").trim())) {
63
+ hits.push({ rule: "decorative-badge", offset: leadingOffset(node) })
64
+ }
65
+ if (node.kind !== "label" && node.stack.some(isStatElement) && MARKETING_NUMBER.test(label)) {
66
+ hits.push({ rule: "vanity-stat", offset: leadingOffset(node) })
67
+ }
68
+ return hits
69
+ }
@@ -0,0 +1,121 @@
1
+ export type Element = {
2
+ readonly tag: string
3
+ readonly name: string
4
+ readonly classes: readonly string[]
5
+ readonly stateful: boolean
6
+ }
7
+
8
+ /** `text` is visible copy, `label` an announced attribute (aria-label, title, alt, placeholder), `value` a stat component's value prop. */
9
+ export type NodeKind = "text" | "label" | "value"
10
+ export type TextNode = { readonly kind: NodeKind; readonly text: string; readonly offset: number; readonly stack: readonly Element[] }
11
+
12
+ export type MarkupKind = "html" | "jsx" | "sfc"
13
+
14
+ const NEVER_RENDERED = /<(script|style|pre|code|textarea|noscript)\b[^>]*>[\s\S]*?<\/\1\s*>|<!--[\s\S]*?-->|\{\/\*[\s\S]*?\*\/\}/gi
15
+ const HTML_TEMPLATE = /<template\b(?![^>]*\s(?:x-[\w-]+|v-[\w-]+|[:@#][\w.-]+))[^>]*>[\s\S]*?<\/template\s*>/gi
16
+ const TAG = /<(\/?)([A-Za-z][\w.:-]*)((?:[^>"'{}]|"[^"]*"|'[^']*'|\{(?:[^{}]|\{[^{}]*\})*\})*)>/g
17
+ const CLASS_ATTR = /\b(?:class|className)\s*=\s*(?:"([^"]*)"|'([^']*)'|\{((?:[^{}]|\{[^{}]*\})*)\})/
18
+ const STRING_LITERAL = /["'`]([^"'`]*)["'`]/g
19
+ const ANNOUNCED_NAME = /(?:^|\s)(?:aria-label|title|alt|placeholder)\s*=/g
20
+ const VALUE_NAME = /(?:^|\s)value\s*=/
21
+ const LITERAL_VALUE = /^\s*(?:"([^"]*)"|'([^']*)'|\{\s*["'`]([^"'`]*)["'`]\s*\})/
22
+ const HIDDEN_ATTR = /(?:^|\s)hidden(?=\s|=|\/|$)/
23
+ const STATE_ATTR = /(?:^|\s)(?:data-status|data-state|aria-(?:current|selected|pressed|checked|expanded|busy|invalid|disabled|valuenow))\s*=/
24
+ const ATTR_VALUES = /"[^"]*"|'[^']*'|\{(?:[^{}]|\{[^{}]*\})*\}/g
25
+ const STAT_COMPONENT = /^(?:Stats?|Metrics?|Kpis?|KPIs?)(?:[A-Z]\w*)?$/
26
+ const STAT_CLASS = /^(?:stat|stats|metric|metrics|kpi)(?:$|[-_])/
27
+ const VOID_TAGS = new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "source", "track", "wbr"])
28
+ const JSX_LEAD = new Set(["(", "[", "{", "}", ",", ":", "?", "=", ">", "&", "|", ";"])
29
+
30
+ function blank(text: string, pattern: RegExp): string {
31
+ return text.replace(pattern, (m) => m.replace(/[^\n]/g, " "))
32
+ }
33
+
34
+ function classesOf(attrs: string): string[] {
35
+ const m = CLASS_ATTR.exec(attrs)
36
+ if (!m) return []
37
+ const literal = m[1] ?? m[2]
38
+ const raw = literal ?? [...(m[3] ?? "").matchAll(STRING_LITERAL)].map((s) => s[1] ?? "").join(" ")
39
+ return raw.split(/\s+/).filter(Boolean)
40
+ }
41
+
42
+ export function isStatElement(element: Element): boolean {
43
+ return STAT_COMPONENT.test(element.name) || element.classes.some((c) => STAT_CLASS.test(c))
44
+ }
45
+
46
+ function closeTo(stack: Element[], tag: string): void {
47
+ const at = stack.map((e) => e.tag).lastIndexOf(tag)
48
+ if (at >= 0) stack.length = at
49
+ }
50
+
51
+ /** In a script, `<` opens JSX only where an expression can start; `Array<string>`, `pick<T>(` and `a<b` stay code. */
52
+ function opensJsx(text: string, start: number, name: string, attrs: string): boolean {
53
+ if (/^\s*,|^\s+extends\b/.test(attrs)) return false
54
+ if (/^(?:const|in|out)$/.test(name) && /^\s+[A-Za-z_$]/.test(attrs)) return false
55
+ const before = text.slice(0, start).trimEnd()
56
+ if (before === "" || /\b(?:return|yield|default)$/.test(before)) return true
57
+ return JSX_LEAD.has(before.at(-1) ?? "")
58
+ }
59
+
60
+ function literalAfter(attrs: string, from: number): { readonly value: string; readonly at: number } | null {
61
+ const m = LITERAL_VALUE.exec(attrs.slice(from))
62
+ if (!m) return null
63
+ const value = m[1] ?? m[2] ?? m[3] ?? ""
64
+ return { value, at: from + m[0].lastIndexOf(value) }
65
+ }
66
+
67
+ function keepLiterals(segment: string): string {
68
+ return segment.replace(/\{[^{}]*\}/g, (m) => {
69
+ const lit = /^\{\s*(["'`])([^"'`]*)\1\s*\}$/.exec(m)
70
+ if (!lit) return " ".repeat(m.length)
71
+ const inner = lit[2] ?? ""
72
+ const at = m.indexOf(lit[1] ?? "") + 1
73
+ return " ".repeat(at) + inner + " ".repeat(m.length - at - inner.length)
74
+ })
75
+ }
76
+
77
+ /** Copy a reader sees or hears, each piece with the elements open around it. Code, hidden elements and never-rendered blocks are skipped. */
78
+ export function textNodes(source: string, kind: MarkupKind): TextNode[] {
79
+ const text = kind === "html" ? blank(blank(source, NEVER_RENDERED), HTML_TEMPLATE) : blank(source, NEVER_RENDERED)
80
+ const nodes: TextNode[] = []
81
+ const stack: Element[] = []
82
+ let hiddenDepth = 0
83
+ let cursor = 0
84
+ const flush = (end: number) => {
85
+ if (stack.length === 0 || hiddenDepth > 0) return
86
+ const segment = keepLiterals(text.slice(cursor, end))
87
+ if (segment.trim()) nodes.push({ kind: "text", text: segment, offset: cursor, stack: [...stack] })
88
+ }
89
+ for (const m of text.matchAll(TAG)) {
90
+ const start = m.index ?? 0
91
+ const [whole, closing, rawName = "", attrs = ""] = m
92
+ const end = start + whole.length
93
+ if (kind === "jsx" && !closing && stack.length === 0 && !opensJsx(text, start, rawName, attrs)) continue
94
+ flush(start)
95
+ cursor = end
96
+ const tag = rawName.toLowerCase()
97
+ if (closing) {
98
+ const at = stack.map((e) => e.tag).lastIndexOf(tag)
99
+ if (at >= 0 && hiddenDepth > at) hiddenDepth = 0
100
+ closeTo(stack, tag)
101
+ continue
102
+ }
103
+ const names = attrs.replace(ATTR_VALUES, (v) => " ".repeat(v.length))
104
+ const element: Element = { tag, name: rawName, classes: classesOf(attrs), stateful: STATE_ATTR.test(names) }
105
+ const attrsAt = start + 1 + rawName.length
106
+ const hidden = hiddenDepth > 0 || HIDDEN_ATTR.test(names)
107
+ if (!hidden) {
108
+ for (const a of names.matchAll(ANNOUNCED_NAME)) {
109
+ const lit = literalAfter(attrs, (a.index ?? 0) + a[0].length)
110
+ if (lit?.value.trim()) nodes.push({ kind: "label", text: lit.value, offset: attrsAt + lit.at, stack: [...stack, element] })
111
+ }
112
+ const v = isStatElement(element) ? VALUE_NAME.exec(names) : null
113
+ const lit = v ? literalAfter(attrs, v.index + v[0].length) : null
114
+ if (lit?.value.trim()) nodes.push({ kind: "value", text: lit.value, offset: attrsAt + lit.at, stack: [...stack, element] })
115
+ }
116
+ if (VOID_TAGS.has(tag) || attrs.trimEnd().endsWith("/")) continue
117
+ stack.push(element)
118
+ if (hiddenDepth === 0 && HIDDEN_ATTR.test(names)) hiddenDepth = stack.length
119
+ }
120
+ return nodes
121
+ }
@@ -0,0 +1,10 @@
1
+ export function Bar() {
2
+ return (
3
+ <div data-title="Supercharge your team">
4
+ <StatusBar><span>24/7</span></StatusBar>
5
+ <span className="badge" aria-current="page">New</span>
6
+ <div data-x="a title='Supercharge your team'" />
7
+ <Stat data-value="10x" />
8
+ </div>
9
+ )
10
+ }
@@ -0,0 +1,12 @@
1
+ export function Summary({ count, status, uptime }: { count: number; status: string; uptime: string }) {
2
+ return (
3
+ <section>
4
+ <div className="stat"><span className="stat-value">{count}</span><span>open tickets</span></div>
5
+ <div className="metric">{uptime}</div>
6
+ <span className="badge" data-status={status}>{status}</span>
7
+ <span className="badge">3</span>
8
+ <span className="chip">Failed</span>
9
+ <p>Seams in the fabric are reinforced.</p>
10
+ </section>
11
+ )
12
+ }
@@ -0,0 +1,3 @@
1
+ export const keep = <const T,>(x: T) => x
2
+ export const label = "Seamless sync"
3
+ export const Saved = () => <p>saved</p>
@@ -0,0 +1,7 @@
1
+ export const labels: Array<string> = ["Unlock the power", "πŸš€ launch"]
2
+ export const pick = <T,>(xs: T[]): T | undefined => xs[0]
3
+ export const first = <T extends object>(xs: T[]) => xs[0]
4
+ export const flag = (a: number, b: number) => (a<b && b>a ? "seamless sync" : "x")
5
+ export function Saved() {
6
+ return <p>Saved 3 files</p>
7
+ }
@@ -0,0 +1,6 @@
1
+ <section class="stats">
2
+ <div class="stat"><span class="stat-value">42%</span><span>refund rate, Q3</span></div>
3
+ <div class="metric">99.9%</div>
4
+ <div class="kpi"><strong>1.2k</strong> open tickets</div>
5
+ <div class="stat">$2M</div>
6
+ </section>
@@ -0,0 +1,9 @@
1
+ <main>
2
+ <h1>Monthly revenue</h1>
3
+ <p>Revenue rose 4% after the refund fix shipped on 3 June.</p>
4
+ <pre><code>const seamless = "Supercharge"</code></pre>
5
+ <footer>Β© 2026 Example Inc. Next page β†’</footer>
6
+ <script>const label = "Unlock the power of your data πŸš€"</script>
7
+ <style>.stat::after { content: "10x"; }</style>
8
+ <!-- ν•œλˆˆμ— λ³΄λŠ” λ©”λͺ¨ -->
9
+ </main>
@@ -0,0 +1,11 @@
1
+ <main>
2
+ <p>Unlock your account to continue.</p>
3
+ <p>졜적의 경둜λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.</p>
4
+ <p>Docs β†—</p>
5
+ <p>β–Ά Play</p>
6
+ <li>Inbox <span class="badge" data-status="unread">New</span></li>
7
+ <span class="pill">Pro</span>
8
+ <div hidden>Seamless onboarding</div>
9
+ <noscript>Supercharge your browser</noscript>
10
+ <template><p>Unlock the power of templates</p></template>
11
+ </main>
@@ -0,0 +1,7 @@
1
+ <main>
2
+ <div class="block hidden md:flex"><p>Seamless sync</p></div>
3
+ <button title="Show hidden files"><span>Supercharge your team</span></button>
4
+ <div class="stat"><span>1,000,000+</span></div>
5
+ <span class="badge" aria-hidden="true">New</span>
6
+ <template x-if="open"><p>Effortless setup</p></template>
7
+ </main>
@@ -0,0 +1,16 @@
1
+ const cn = (...names: string[]) => names.join(" ")
2
+ export function Page() {
3
+ return (
4
+ <main>
5
+ <Badge>New</Badge>
6
+ <span className={cn("badge", "badge--hot")}>Hot</span>
7
+ <span className="badge">✨ New</span>
8
+ <p>Launch &#x1F680; today</p>
9
+ <button type="button" aria-label="πŸš€ Launch">Go</button>
10
+ <Stat value="10x" />
11
+ <StatCard><p>10x</p></StatCard>
12
+ <div className="metric">{"500+"}</div>
13
+ <input placeholder="Supercharge your search" />
14
+ </main>
15
+ )
16
+ }
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <div>
3
+ <span class="badge">New</span>
4
+ <span class="chip chip--accent">AI-powered</span>
5
+ <h3>Monthly revenue</h3>
6
+ </div>
7
+ </template>
@@ -0,0 +1,9 @@
1
+ export function Actions() {
2
+ return (
3
+ <ul>
4
+ <li>βœ… Fast setup</li>
5
+ <li>Plain item</li>
6
+ <button type="button">πŸš€ Launch</button>
7
+ </ul>
8
+ )
9
+ }
@@ -0,0 +1 @@
1
+ export const Beta = () => <p>(beta) Seamless sync</p>
@@ -0,0 +1,6 @@
1
+ <section class="hero">
2
+ <h1>Seamlessly manage every report</h1>
3
+ <p>ν•œλˆˆμ— λ³΄λŠ” 맀좜 ν˜„ν™©</p>
4
+ <p>Track revenue and refunds.</p>
5
+ <p>Unlock the power of your data</p>
6
+ </section>
@@ -0,0 +1,8 @@
1
+ export function Hero() {
2
+ return (
3
+ <header>
4
+ <h2>Supercharge your workflow</h2>
5
+ <p>μ†μ‰½κ²Œ μ‹œμž‘ν•˜μ„Έμš”</p>
6
+ </header>
7
+ )
8
+ }
@@ -0,0 +1,5 @@
1
+ <div class="stats">
2
+ <div class="stat"><span class="stat-value">10x</span><span>faster</span></div>
3
+ <div class="metric">$2M+</div>
4
+ <div class="kpi-card"><strong>24/7</strong></div>
5
+ </div>