lazycodex-ai 5.1.44 → 5.1.45

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 (273) hide show
  1. package/dist/cli/index.js +948 -416
  2. package/dist/cli/service-auth/keystore.d.ts +4 -2
  3. package/dist/cli-node/index.js +948 -416
  4. package/docs/reference/web-terminal-visual-qa.md +8 -0
  5. package/package.json +1 -1
  6. package/packages/lsp-daemon/dist/cli.js +4 -4
  7. package/packages/lsp-daemon/dist/client.js +4 -4
  8. package/packages/lsp-daemon/dist/index.js +4 -4
  9. package/packages/lsp-daemon/package.json +3 -3
  10. package/packages/lsp-tools-mcp/dist/cli.js +4 -4
  11. package/packages/lsp-tools-mcp/dist/mcp.js +4 -4
  12. package/packages/lsp-tools-mcp/dist/tools.js +4 -4
  13. package/packages/lsp-tools-mcp/package.json +3 -3
  14. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  15. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +62 -21
  16. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  17. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  18. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -1
  19. package/packages/omo-codex/plugin/components/comment-checker/biome.json +1 -21
  20. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  21. package/packages/omo-codex/plugin/components/comment-checker/package.json +4 -4
  22. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  23. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  24. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +1 -21
  25. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  26. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +4 -4
  27. package/packages/omo-codex/plugin/components/lsp/biome.json +1 -21
  28. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  29. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +4 -4
  30. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  31. package/packages/omo-codex/plugin/components/lsp/package.json +4 -4
  32. package/packages/omo-codex/plugin/components/lsp/scripts/build-runtime.mjs +0 -1
  33. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-not-installed.test.ts +1 -1
  34. package/packages/omo-codex/plugin/components/rules/biome.json +1 -21
  35. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  36. package/packages/omo-codex/plugin/components/rules/package.json +4 -4
  37. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  38. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  39. package/packages/omo-codex/plugin/components/telemetry/biome.json +1 -21
  40. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +90 -1
  41. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +91 -1
  42. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  43. package/packages/omo-codex/plugin/components/telemetry/package.json +4 -4
  44. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +2 -2
  45. package/packages/omo-codex/plugin/components/ultrawork/biome.json +1 -21
  46. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  47. package/packages/omo-codex/plugin/components/ultrawork/package.json +4 -4
  48. package/packages/omo-codex/plugin/components/ulw-execute-continuation/biome.json +1 -21
  49. package/packages/omo-codex/plugin/components/ulw-execute-continuation/directive.md +1 -1
  50. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  51. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +4 -4
  52. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +1 -21
  53. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +1 -1
  54. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +7 -7
  55. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +5 -5
  56. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +1 -1
  57. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  58. package/packages/omo-codex/plugin/components/ulw-loop/package.json +4 -4
  59. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +1 -1
  60. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +5 -5
  61. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +1 -1
  62. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-mutations.mjs +2 -0
  63. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  64. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  65. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  66. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  67. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  68. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  69. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  70. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  71. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  72. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  73. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  74. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  75. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  76. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  77. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  78. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  79. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  80. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  81. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  82. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  83. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  84. package/packages/omo-codex/plugin/package-lock.json +12 -12
  85. package/packages/omo-codex/plugin/package.json +1 -1
  86. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +7 -7
  87. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +2 -0
  88. package/packages/omo-codex/plugin/skills/browser/SKILL.md +21 -22
  89. package/packages/omo-codex/plugin/skills/browser/references/commands.md +2 -9
  90. package/packages/omo-codex/plugin/skills/browser/references/install.md +1 -2
  91. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +1 -1
  92. package/packages/omo-codex/plugin/skills/browser/scripts/browser-doctor.mjs +2 -2
  93. package/packages/omo-codex/plugin/skills/browser/scripts/browser-engine-guard.mjs +63 -487
  94. package/packages/omo-codex/plugin/skills/browser/scripts/browser-install.mjs +1 -1
  95. package/packages/omo-codex/plugin/skills/browser/scripts/omowright.mjs +1 -10
  96. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +79 -118
  97. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +75 -224
  98. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +32 -27
  99. package/packages/omo-codex/plugin/skills/frontend/references/perfection/README.md +2 -2
  100. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/check-accent-stripes.ts +8 -24
  101. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/check-draft-guard.ts +40 -0
  102. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/collect-files.ts +53 -0
  103. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/draft-guard/findings.ts +16 -0
  104. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/draft-guard/lint.ts +38 -0
  105. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/draft-guard/rules.ts +69 -0
  106. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/draft-guard/text-nodes.ts +121 -0
  107. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/attr-lookalikes.tsx +10 -0
  108. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/bound-values.tsx +12 -0
  109. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/const-generics.tsx +3 -0
  110. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/generics.tsx +7 -0
  111. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/measured-stats.html +6 -0
  112. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/plain-copy.html +9 -0
  113. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/state-copy.html +11 -0
  114. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/attribute-edges.html +7 -0
  115. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/components.tsx +16 -0
  116. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/decorative-badge.vue +7 -0
  117. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/emoji-icons.tsx +9 -0
  118. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/jsx-edges.tsx +1 -0
  119. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/promo-copy.html +6 -0
  120. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/promo-copy.tsx +8 -0
  121. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/vanity-stats.html +5 -0
  122. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +1 -1
  123. package/packages/omo-codex/plugin/skills/programming/SKILL.md +10 -7
  124. package/packages/omo-codex/plugin/skills/programming/references/typescript/README.md +10 -7
  125. package/packages/omo-codex/plugin/skills/programming/references/typescript/bootstrap.md +9 -23
  126. package/packages/omo-codex/plugin/skills/programming/references/typescript/oxc-lint.md +130 -0
  127. package/packages/omo-codex/plugin/skills/programming/references/typescript/tsconfig-strict.md +6 -62
  128. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +12 -12
  129. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/new-project.ts +20 -81
  130. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/.oxfmtrc.json +9 -0
  131. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/.oxlintrc.json +46 -0
  132. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/LICENSE +21 -0
  133. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/index.js +10 -0
  134. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/no-em-dash-copy.js +28 -0
  135. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/require-suppression-reason.js +62 -0
  136. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/oxc/tsconfig.json +29 -0
  137. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +14 -14
  138. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +1 -1
  139. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +2 -2
  140. package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +2 -2
  141. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +1 -1
  142. package/packages/omo-codex/plugin/skills/ulw-research/AGENTS.md +9 -3
  143. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +2 -2
  144. package/packages/omo-codex/plugin/skills/ulw-research/references/deliverable-phase.md +7 -6
  145. package/packages/omo-codex/plugin/skills/ulw-research/references/fact-ledger-grammar.md +116 -0
  146. package/packages/omo-codex/plugin/skills/ulw-research/references/report-gates.md +51 -3
  147. package/packages/omo-codex/plugin/skills/ulw-research/scripts/claims-index.mjs +125 -0
  148. package/packages/omo-codex/plugin/skills/ulw-research/scripts/contracts.mjs +68 -3
  149. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-ledger-kinds.mjs +136 -0
  150. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-ledger-schema.mjs +204 -0
  151. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-ledger.mjs +103 -0
  152. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-brief.mjs +145 -0
  153. package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-state.mjs +63 -0
  154. package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-static.mjs +1 -1
  155. package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-structure.mjs +1 -1
  156. package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-text.mjs +1 -27
  157. package/packages/omo-codex/plugin/skills/ulw-research/scripts/lexicon.mjs +47 -0
  158. package/packages/omo-codex/plugin/skills/ulw-research/scripts/numerals.mjs +226 -0
  159. package/packages/omo-codex/plugin/skills/ulw-research/scripts/outcome.mjs +2 -3
  160. package/packages/omo-codex/plugin/skills/ulw-research/scripts/particles-ko.mjs +108 -0
  161. package/packages/omo-codex/plugin/skills/ulw-research/scripts/rational.mjs +139 -0
  162. package/packages/omo-codex/plugin/skills/ulw-research/scripts/report-tools-commands.mjs +2 -2
  163. package/packages/omo-codex/plugin/skills/ulw-research/scripts/sentence-split.mjs +77 -0
  164. package/packages/omo-codex/plugin/skills/ulw-research/scripts/text-normalize.mjs +82 -0
  165. package/packages/omo-codex/plugin/skills/ulw-research/scripts/text-similarity.mjs +28 -0
  166. package/packages/omo-codex/plugin/skills/ulw-research/scripts/units.mjs +105 -0
  167. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +71 -64
  168. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +4 -1
  169. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +6 -6
  170. package/packages/omo-codex/scripts/install-dist/install-local.mjs +152 -23
  171. package/packages/shared-skills/skills/browser/SKILL.md +21 -22
  172. package/packages/shared-skills/skills/browser/references/commands.md +2 -9
  173. package/packages/shared-skills/skills/browser/references/install.md +1 -2
  174. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +1 -1
  175. package/packages/shared-skills/skills/browser/scripts/browser-doctor.mjs +2 -2
  176. package/packages/shared-skills/skills/browser/scripts/browser-engine-guard.mjs +63 -487
  177. package/packages/shared-skills/skills/browser/scripts/browser-install.mjs +1 -1
  178. package/packages/shared-skills/skills/browser/scripts/omowright.mjs +1 -10
  179. package/packages/shared-skills/skills/frontend/SKILL.md +79 -118
  180. package/packages/shared-skills/skills/frontend/references/design/README.md +75 -224
  181. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +32 -27
  182. package/packages/shared-skills/skills/frontend/references/perfection/README.md +2 -2
  183. package/packages/shared-skills/skills/frontend/scripts/perfection/check-accent-stripes.ts +8 -24
  184. package/packages/shared-skills/skills/frontend/scripts/perfection/check-draft-guard.test.ts +101 -0
  185. package/packages/shared-skills/skills/frontend/scripts/perfection/check-draft-guard.ts +40 -0
  186. package/packages/shared-skills/skills/frontend/scripts/perfection/collect-files.test.ts +50 -0
  187. package/packages/shared-skills/skills/frontend/scripts/perfection/collect-files.ts +53 -0
  188. package/packages/shared-skills/skills/frontend/scripts/perfection/draft-guard/findings.ts +16 -0
  189. package/packages/shared-skills/skills/frontend/scripts/perfection/draft-guard/lint.ts +38 -0
  190. package/packages/shared-skills/skills/frontend/scripts/perfection/draft-guard/rules.ts +69 -0
  191. package/packages/shared-skills/skills/frontend/scripts/perfection/draft-guard/text-nodes.ts +121 -0
  192. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/attr-lookalikes.tsx +10 -0
  193. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/bound-values.tsx +12 -0
  194. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/const-generics.tsx +3 -0
  195. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/generics.tsx +7 -0
  196. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/measured-stats.html +6 -0
  197. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/plain-copy.html +9 -0
  198. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/negative/state-copy.html +11 -0
  199. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/attribute-edges.html +7 -0
  200. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/components.tsx +16 -0
  201. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/decorative-badge.vue +7 -0
  202. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/emoji-icons.tsx +9 -0
  203. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/jsx-edges.tsx +1 -0
  204. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/promo-copy.html +6 -0
  205. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/promo-copy.tsx +8 -0
  206. package/packages/shared-skills/skills/frontend/scripts/perfection/fixtures/draft-guard/positive/vanity-stats.html +5 -0
  207. package/packages/shared-skills/skills/programming/SKILL.md +10 -7
  208. package/packages/shared-skills/skills/programming/references/typescript/README.md +10 -7
  209. package/packages/shared-skills/skills/programming/references/typescript/bootstrap.md +9 -23
  210. package/packages/shared-skills/skills/programming/references/typescript/oxc-lint.md +130 -0
  211. package/packages/shared-skills/skills/programming/references/typescript/tsconfig-strict.md +6 -62
  212. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.ts +12 -12
  213. package/packages/shared-skills/skills/programming/scripts/typescript/new-project.test.ts +162 -0
  214. package/packages/shared-skills/skills/programming/scripts/typescript/new-project.ts +20 -81
  215. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/.oxfmtrc.json +9 -0
  216. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/.oxlintrc.json +46 -0
  217. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/LICENSE +21 -0
  218. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/index.js +10 -0
  219. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/no-em-dash-copy.js +28 -0
  220. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/lint/oxlint-plugin/require-suppression-reason.js +62 -0
  221. package/packages/shared-skills/skills/programming/scripts/typescript/oxc/tsconfig.json +29 -0
  222. package/packages/shared-skills/skills/refactor/SKILL.md +13 -13
  223. package/packages/shared-skills/skills/ulw-execute/SKILL.md +1 -1
  224. package/packages/shared-skills/skills/ulw-research/AGENTS.md +9 -3
  225. package/packages/shared-skills/skills/ulw-research/SKILL.md +2 -2
  226. package/packages/shared-skills/skills/ulw-research/references/deliverable-phase.md +7 -6
  227. package/packages/shared-skills/skills/ulw-research/references/fact-ledger-grammar.md +116 -0
  228. package/packages/shared-skills/skills/ulw-research/references/report-gates.md +51 -3
  229. package/packages/shared-skills/skills/ulw-research/scripts/claims-index.mjs +125 -0
  230. package/packages/shared-skills/skills/ulw-research/scripts/claims-index.test.ts +149 -0
  231. package/packages/shared-skills/skills/ulw-research/scripts/contracts.mjs +68 -3
  232. package/packages/shared-skills/skills/ulw-research/scripts/contracts.test.ts +97 -12
  233. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-grammar.test.ts +190 -0
  234. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-kinds.mjs +136 -0
  235. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-kinds.test.ts +141 -0
  236. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-schema.mjs +204 -0
  237. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-schema.test.ts +43 -0
  238. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger.mjs +103 -0
  239. package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger.test.ts +252 -0
  240. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-brief.mjs +145 -0
  241. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-brief.test.ts +179 -0
  242. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-state.mjs +63 -0
  243. package/packages/shared-skills/skills/ulw-research/scripts/fidelity-state.test.ts +46 -0
  244. package/packages/shared-skills/skills/ulw-research/scripts/gates-context.test.ts +64 -0
  245. package/packages/shared-skills/skills/ulw-research/scripts/gates-static.mjs +1 -1
  246. package/packages/shared-skills/skills/ulw-research/scripts/gates-structure.mjs +1 -1
  247. package/packages/shared-skills/skills/ulw-research/scripts/gates-text.mjs +1 -27
  248. package/packages/shared-skills/skills/ulw-research/scripts/lexicon.mjs +47 -0
  249. package/packages/shared-skills/skills/ulw-research/scripts/lexicon.test.ts +57 -0
  250. package/packages/shared-skills/skills/ulw-research/scripts/numerals.mjs +226 -0
  251. package/packages/shared-skills/skills/ulw-research/scripts/numerals.test.ts +120 -0
  252. package/packages/shared-skills/skills/ulw-research/scripts/outcome.mjs +2 -3
  253. package/packages/shared-skills/skills/ulw-research/scripts/outcome.test.ts +29 -0
  254. package/packages/shared-skills/skills/ulw-research/scripts/particles-ko.mjs +108 -0
  255. package/packages/shared-skills/skills/ulw-research/scripts/particles-ko.test.ts +86 -0
  256. package/packages/shared-skills/skills/ulw-research/scripts/rational.mjs +139 -0
  257. package/packages/shared-skills/skills/ulw-research/scripts/rational.test.ts +46 -0
  258. package/packages/shared-skills/skills/ulw-research/scripts/report-tools-commands.mjs +2 -2
  259. package/packages/shared-skills/skills/ulw-research/scripts/sentence-split.mjs +77 -0
  260. package/packages/shared-skills/skills/ulw-research/scripts/sentence-split.test.ts +109 -0
  261. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity/claim-graph.md +13 -0
  262. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity-brief-locked.md +17 -0
  263. package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/fidelity-brief-pending.md +17 -0
  264. package/packages/shared-skills/skills/ulw-research/scripts/text-normalize.mjs +82 -0
  265. package/packages/shared-skills/skills/ulw-research/scripts/text-normalize.test.ts +73 -0
  266. package/packages/shared-skills/skills/ulw-research/scripts/text-similarity.mjs +28 -0
  267. package/packages/shared-skills/skills/ulw-research/scripts/text-similarity.test.ts +38 -0
  268. package/packages/shared-skills/skills/ulw-research/scripts/units.mjs +105 -0
  269. package/packages/shared-skills/skills/ulw-research/scripts/units.test.ts +83 -0
  270. package/packages/shared-skills/skills/visual-qa/SKILL.md +70 -63
  271. package/packages/shared-skills/skills/visual-qa/scripts/skill-doc-fields.test.ts +34 -0
  272. package/script/qa/web-terminal-visual-qa.mjs +6 -2
  273. package/script/qa/xterm-live-terminal.mjs +26 -3
@@ -0,0 +1,162 @@
1
+ import { afterAll, beforeAll, describe, expect, test } from "bun:test";
2
+ import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { pathToFileURL } from "node:url";
6
+
7
+ const runRoot = mkdtempSync(join(process.env.RUN_TMP ?? tmpdir(), "programming-scaffold-"));
8
+ const project = join(runRoot, "example");
9
+
10
+ async function run(args: string[], cwd = project) {
11
+ const child = Bun.spawn(args, { cwd, stdout: "pipe", stderr: "pipe" });
12
+ const [stdout, stderr, code] = await Promise.all([
13
+ new Response(child.stdout).text(),
14
+ new Response(child.stderr).text(),
15
+ child.exited,
16
+ ]);
17
+ return { stdout, stderr, code };
18
+ }
19
+
20
+ describe("#given a newly scaffolded TypeScript project", () => {
21
+ beforeAll(async () => {
22
+ const result = await run(
23
+ [process.execPath, join(import.meta.dir, "new-project.ts"), "example", "--path", runRoot],
24
+ runRoot,
25
+ );
26
+ expect(result.code).toBe(0);
27
+ });
28
+
29
+ afterAll(() => rmSync(runRoot, { recursive: true, force: true }));
30
+
31
+ test("#when scaffolding offline #then OXC configs and the local plugin are generated", async () => {
32
+ for (const file of [
33
+ ".oxlintrc.json",
34
+ ".oxfmtrc.json",
35
+ "package.json",
36
+ "tsconfig.json",
37
+ "src/index.ts",
38
+ ".gitignore",
39
+ "lint/oxlint-plugin/index.js",
40
+ "lint/oxlint-plugin/no-em-dash-copy.js",
41
+ "lint/oxlint-plugin/require-suppression-reason.js",
42
+ "lint/oxlint-plugin/LICENSE",
43
+ ]) {
44
+ expect(existsSync(join(project, file))).toBe(true);
45
+ }
46
+ expect(existsSync(join(project, "biome.json"))).toBe(false);
47
+ const pkg = await Bun.file(join(project, "package.json")).json();
48
+ expect(pkg.devDependencies.oxlint).toBeDefined();
49
+ expect(pkg.devDependencies.oxfmt).toBeDefined();
50
+ expect(pkg.devDependencies["oxlint-tsgolint"]).toBeDefined();
51
+ expect(pkg.scripts.lint).toBe("oxlint --type-aware --deny-warnings");
52
+ const config = await Bun.file(join(project, ".oxlintrc.json")).json();
53
+ expect(config.jsPlugins).toContainEqual({
54
+ name: "programming",
55
+ specifier: "./lint/oxlint-plugin/index.js",
56
+ });
57
+ expect(config.rules["programming/require-suppression-reason"]).toBe("error");
58
+ expect(config.overrides[0].rules["programming/no-em-dash-copy"]).toBe("error");
59
+ const tsconfig = await Bun.file(join(project, "tsconfig.json")).json();
60
+ expect(tsconfig.include).toEqual(["src/**/*.ts", "src/**/*.tsx"]);
61
+ expect(tsconfig.compilerOptions.jsx).toBe("react-jsx");
62
+ });
63
+
64
+ test("#when visiting copy offline #then the generated plugin reports em dashes", async () => {
65
+ const { default: plugin } = await import(
66
+ pathToFileURL(join(project, "lint/oxlint-plugin/index.js")).href
67
+ );
68
+ const reports: unknown[] = [];
69
+ const visitors = plugin.rules["no-em-dash-copy"].create({
70
+ report: (report: unknown) => reports.push(report),
71
+ });
72
+ const literal = { type: "Literal", value: "Hello\u2014world" };
73
+ const template = { type: "TemplateElement", value: { cooked: "Hello\u2014world" } };
74
+ const jsx = { type: "JSXText", value: "Hello\u2014world" };
75
+ visitors.Literal(literal);
76
+ visitors.TemplateElement(template);
77
+ visitors.JSXText(jsx);
78
+ expect(reports).toHaveLength(3);
79
+ expect(reports).toEqual([
80
+ expect.objectContaining({ node: literal }),
81
+ expect.objectContaining({ node: template }),
82
+ expect.objectContaining({ node: jsx }),
83
+ ]);
84
+ visitors.Literal({ type: "Literal", value: "Hello, world" });
85
+ visitors.Literal({ type: "Literal", value: /Hello\u2014world/ });
86
+ visitors.TemplateElement({ type: "TemplateElement", value: { cooked: null } });
87
+ visitors.JSXText({ type: "JSXText", value: "Hello, world" });
88
+ expect(reports).toHaveLength(3);
89
+ });
90
+
91
+ // Opt in to registry-dependent install + lint/format/typecheck coverage:
92
+ // OMO_TEST_SCAFFOLD_INSTALL=1 bun test packages/shared-skills/skills/programming/scripts/typescript/new-project.test.ts
93
+ test.skipIf(process.env.OMO_TEST_SCAFFOLD_INSTALL !== "1")(
94
+ "#when linting seeded product copy #then the installed generated rule rejects it",
95
+ async () => {
96
+ // given the dependencies and configuration emitted by the real scaffold
97
+ const pkg = await Bun.file(join(project, "package.json")).json();
98
+ expect(pkg.devDependencies.oxlint).toBeDefined();
99
+ const install = await run([process.execPath, "install", "--ignore-scripts"]);
100
+ expect(install.code).toBe(0);
101
+ const clean = await run([process.execPath, "run", "lint"]);
102
+ expect(clean.stdout + clean.stderr).not.toContain("Unknown rule");
103
+ expect(clean.code).toBe(0);
104
+ const formatted = await run([process.execPath, "run", "fmt:check"]);
105
+ expect(formatted.code).toBe(0);
106
+ const typed = await run([process.execPath, "run", "typecheck"]);
107
+ expect(typed.code).toBe(0);
108
+ writeFileSync(join(project, "src/copy.ts"), 'export const copy = "Hello\\u2014world"\n');
109
+
110
+ // when the generated project's own lint command runs
111
+ const result = await run([process.execPath, "run", "lint"]);
112
+
113
+ // then it fails for the copy rule, rather than a missing tool or invalid configuration
114
+ expect(result.code).toBe(1);
115
+ expect(result.stdout + result.stderr).toContain("programming(no-em-dash-copy)");
116
+
117
+ // given cooked template text and JSX copy, not only string literals
118
+ writeFileSync(
119
+ join(project, "src/copy.tsx"),
120
+ "export const template = `Hello\\u2014world`\nexport const view = <p>Hello\u2014world</p>\n",
121
+ );
122
+ const jsx = await run([process.execPath, "run", "lint", "--", "src/copy.tsx"]);
123
+ expect(jsx.code).toBe(1);
124
+ expect((jsx.stdout + jsx.stderr).match(/programming\(no-em-dash-copy\)/g)).toHaveLength(2);
125
+
126
+ // given comments, regexes, and test fixtures outside the copy policy
127
+ writeFileSync(
128
+ join(project, "src/clean.ts"),
129
+ "// Hello\u2014world\nexport const pattern = /Hello\u2014world/\n",
130
+ );
131
+ writeFileSync(join(project, "src/copy.test.ts"), 'export const copy = "Hello\\u2014world"\n');
132
+ const exempt = await run([
133
+ process.execPath,
134
+ "run",
135
+ "lint",
136
+ "--",
137
+ "src/clean.ts",
138
+ "src/copy.test.ts",
139
+ ]);
140
+ expect(exempt.code).toBe(0);
141
+
142
+ // given lint suppressions without a reason, the local reason rule reports them
143
+ writeFileSync(
144
+ join(project, "src/suppression.ts"),
145
+ "// oxlint-disable-next-line no-unused-vars\nconst hidden = 1\n",
146
+ );
147
+ const unexplained = await run([process.execPath, "run", "lint", "--", "src/suppression.ts"]);
148
+ expect(unexplained.code).toBe(1);
149
+ expect(unexplained.stdout + unexplained.stderr).toContain(
150
+ "programming(require-suppression-reason)",
151
+ );
152
+
153
+ writeFileSync(
154
+ join(project, "src/suppression.ts"),
155
+ "// Synthetic legacy interop fixture.\n// oxlint-disable-next-line no-unused-vars\nconst hidden = 1\n",
156
+ );
157
+ const explained = await run([process.execPath, "run", "lint", "--", "src/suppression.ts"]);
158
+ expect(explained.code).toBe(0);
159
+ },
160
+ 120_000,
161
+ );
162
+ });
@@ -11,14 +11,16 @@
11
11
  *
12
12
  * Creates:
13
13
  * <name>/
14
- * package.json (Bun + Hono + Zod + Drizzle + Biome)
15
- * tsconfig.json (ultra-strict from tsconfig-strict.md)
16
- * biome.json (strict from tsconfig-strict.md)
14
+ * package.json (Bun + Hono + Zod + oxlint + oxfmt)
15
+ * tsconfig.json (static ultra-strict config copied from oxc/)
16
+ * .oxlintrc.json (strict rules and local copy plugin)
17
+ * .oxfmtrc.json (format defaults)
18
+ * lint/oxlint-plugin/ (plain-JS rules and MIT license)
17
19
  * src/index.ts (minimal Hono entrypoint)
18
20
  * .gitignore
19
21
  */
20
22
 
21
- import { mkdirSync, writeFileSync, existsSync } from "node:fs";
23
+ import { cpSync, mkdirSync, writeFileSync, existsSync } from "node:fs";
22
24
  import { join, resolve } from "node:path";
23
25
  import { parseArgs } from "node:util";
24
26
 
@@ -44,8 +46,9 @@ Options:
44
46
  process.exit(positionals.length === 0 ? 2 : 0);
45
47
  }
46
48
 
47
- const name = positionals[0]!;
48
- const root = resolve(values.path!, name);
49
+ const name = positionals[0];
50
+ if (!name) throw new Error("Project name is required");
51
+ const root = resolve(values.path ?? ".", name);
49
52
 
50
53
  if (existsSync(root)) {
51
54
  console.error(`Error: ${root} already exists`);
@@ -64,8 +67,12 @@ const pkg = {
64
67
  scripts: {
65
68
  dev: "bun --hot src/index.ts",
66
69
  start: "bun src/index.ts",
67
- check: "bunx biome check . && bunx tsc --noEmit && bun test",
68
- "check:fix": "bunx biome check --write .",
70
+ lint: "oxlint --type-aware --deny-warnings",
71
+ fmt: "oxfmt",
72
+ "fmt:check": "oxfmt --check",
73
+ typecheck: "tsc --noEmit",
74
+ check: "bun run lint && bun run fmt:check && bun run typecheck && bun test",
75
+ "check:fix": "oxlint --type-aware --fix && oxfmt",
69
76
  test: "bun test",
70
77
  },
71
78
  dependencies: {
@@ -73,85 +80,17 @@ const pkg = {
73
80
  zod: "^3.24.0",
74
81
  },
75
82
  devDependencies: {
76
- "@biomejs/biome": "^1.9.0",
77
83
  "@types/bun": "latest",
84
+ oxfmt: "0.74.0",
85
+ oxlint: "1.89.0",
86
+ "oxlint-tsgolint": "7.0.2005",
78
87
  typescript: "^5.8.0",
79
88
  },
80
89
  };
81
90
  writeFileSync(join(root, "package.json"), JSON.stringify(pkg, null, 2) + "\n");
82
91
 
83
- // ── tsconfig.json (ultra-strict) ──
84
- const tsconfig = {
85
- compilerOptions: {
86
- strict: true,
87
- noUncheckedIndexedAccess: true,
88
- exactOptionalPropertyTypes: true,
89
- noFallthroughCasesInSwitch: true,
90
- forceConsistentCasingInFileNames: true,
91
- verbatimModuleSyntax: true,
92
- isolatedModules: true,
93
- esModuleInterop: true,
94
- resolveJsonModule: true,
95
- target: "ESNext",
96
- lib: ["ESNext"],
97
- declaration: true,
98
- declarationMap: true,
99
- sourceMap: true,
100
- outDir: "dist",
101
- rootDir: "src",
102
- module: "ESNext",
103
- moduleResolution: "bundler",
104
- types: ["bun-types"],
105
- skipLibCheck: true,
106
- noEmit: true,
107
- },
108
- include: ["src/**/*.ts"],
109
- exclude: ["node_modules", "dist"],
110
- };
111
- writeFileSync(
112
- join(root, "tsconfig.json"),
113
- JSON.stringify(tsconfig, null, 2) + "\n",
114
- );
115
-
116
- // ── biome.json (strict) ──
117
- const biome = {
118
- $schema: "https://biomejs.dev/schemas/1.9.0/schema.json",
119
- organizeImports: { enabled: true },
120
- formatter: {
121
- enabled: true,
122
- indentStyle: "space",
123
- indentWidth: 2,
124
- lineWidth: 100,
125
- },
126
- linter: {
127
- enabled: true,
128
- rules: {
129
- recommended: true,
130
- complexity: {
131
- noBannedTypes: "error",
132
- noExtraBooleanCast: "error",
133
- noUselessConstructor: "error",
134
- noUselessRename: "error",
135
- noVoid: "error",
136
- },
137
- correctness: {
138
- noUnusedVariables: "error",
139
- noUnusedImports: "error",
140
- useExhaustiveDependencies: "warn",
141
- },
142
- style: {
143
- noNonNullAssertion: "error",
144
- useConst: "error",
145
- noParameterAssign: "error",
146
- },
147
- suspicious: {
148
- noExplicitAny: "error",
149
- noAssertion: "warn",
150
- },
151
- },
152
- },
153
- };
154
- writeFileSync(join(root, "biome.json"), JSON.stringify(biome, null, 2) + "\n");
92
+ // Copy the formatted strict configs and plugin documented in oxc-lint.md.
93
+ cpSync(join(import.meta.dir, "oxc"), root, { recursive: true });
155
94
 
156
95
  // ── src/index.ts ──
157
96
  const indexTs = `import { Hono } from "hono";
@@ -0,0 +1,9 @@
1
+ {
2
+ "$schema": "./node_modules/oxfmt/configuration_schema.json",
3
+ "printWidth": 100,
4
+ "tabWidth": 2,
5
+ "useTabs": false,
6
+ "semi": true,
7
+ "singleQuote": false,
8
+ "ignorePatterns": ["node_modules/**", "dist/**", "build/**", "coverage/**", "vendor/**"]
9
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "$schema": "./node_modules/oxlint/configuration_schema.json",
3
+ "plugins": ["typescript", "import", "oxc"],
4
+ "jsPlugins": [{ "name": "programming", "specifier": "./lint/oxlint-plugin/index.js" }],
5
+ "categories": { "correctness": "error", "suspicious": "error" },
6
+ "rules": {
7
+ "typescript/no-explicit-any": "error",
8
+ "typescript/no-non-null-assertion": "error",
9
+ "typescript/consistent-type-imports": "error",
10
+ "typescript/ban-ts-comment": [
11
+ "error",
12
+ { "ts-expect-error": true, "ts-ignore": true, "ts-nocheck": true, "ts-check": false }
13
+ ],
14
+ "typescript/no-empty-object-type": "error",
15
+ "typescript/no-wrapper-object-types": "error",
16
+ "typescript/no-floating-promises": "error",
17
+ "typescript/no-misused-promises": "error",
18
+ "typescript/switch-exhaustiveness-check": "error",
19
+ "import/no-default-export": "error",
20
+ "no-param-reassign": "error",
21
+ "no-unused-vars": "error",
22
+ "no-empty": "error",
23
+ "no-fallthrough": "error",
24
+ "prefer-const": "error",
25
+ "programming/require-suppression-reason": "error"
26
+ },
27
+ "ignorePatterns": ["node_modules/**", "dist/**", "build/**", "coverage/**", "vendor/**"],
28
+ "overrides": [
29
+ {
30
+ "files": ["src/**/*", "apps/*/src/**/*", "packages/*/src/**/*"],
31
+ "rules": { "programming/no-em-dash-copy": "error" }
32
+ },
33
+ {
34
+ "files": [
35
+ "**/*.{test,spec}.*",
36
+ "**/{test,tests,__tests__,fixtures,__fixtures__,_generated,vendor,vendored}/**",
37
+ "**/*.{gen,generated}.*"
38
+ ],
39
+ "rules": { "programming/no-em-dash-copy": "off" }
40
+ },
41
+ {
42
+ "files": ["src/index.ts", "lint/oxlint-plugin/*.js"],
43
+ "rules": { "import/no-default-export": "off" }
44
+ }
45
+ ]
46
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 T3 Tools Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,10 @@
1
+ import noEmDashCopy from "./no-em-dash-copy.js";
2
+ import requireSuppressionReason from "./require-suppression-reason.js";
3
+
4
+ export default {
5
+ meta: { name: "programming" },
6
+ rules: {
7
+ "no-em-dash-copy": noEmDashCopy,
8
+ "require-suppression-reason": requireSuppressionReason,
9
+ },
10
+ };
@@ -0,0 +1,28 @@
1
+ // Ported from pingdotgg/t3code at d7f3b72 (t3code#23799). MIT; see LICENSE.
2
+ const EM_DASH = "\u2014";
3
+ const MESSAGE = "No em dashes in product copy. Use a period, comma, colon, or parentheses instead.";
4
+
5
+ export default {
6
+ meta: {
7
+ type: "suggestion",
8
+ docs: {
9
+ description: "Disallow em dashes in strings and JSX text that users or agents read.",
10
+ },
11
+ },
12
+ create(context) {
13
+ const check = (node, text) => {
14
+ if (text?.includes(EM_DASH)) context.report({ node, message: MESSAGE });
15
+ };
16
+ return {
17
+ Literal(node) {
18
+ if (typeof node.value === "string") check(node, node.value);
19
+ },
20
+ TemplateElement(node) {
21
+ check(node, node.value.cooked);
22
+ },
23
+ JSXText(node) {
24
+ check(node, node.value);
25
+ },
26
+ };
27
+ },
28
+ };
@@ -0,0 +1,62 @@
1
+ // Ported from pingdotgg/t3code at d7f3b72 (t3code#16294). MIT; see LICENSE.
2
+ // Plain-JS port via sisyphuslabs/omo-relay; TypeScript types and defineRule removed.
3
+ const DIRECTIVE_PATTERN =
4
+ /^\s*\*?\s*(?:(?:oxlint|eslint)-(?:disable|enable)|@ts-(?:expect-error|ignore|nocheck)|@effect-diagnostics)/u;
5
+ const TS_DIRECTIVE_PATTERN = /^\s*\*?\s*@ts-(?:expect-error|ignore|nocheck)(?![\w-])(.*)$/su;
6
+ const EMPTY_COMMENT_PATTERN = /^[\s*]*$/u;
7
+
8
+ export default {
9
+ meta: {
10
+ type: "suggestion",
11
+ docs: {
12
+ description: "Require every lint or type-checker suppression to say why.",
13
+ },
14
+ },
15
+ create(context) {
16
+ const { sourceCode } = context;
17
+ return {
18
+ Program() {
19
+ const comments = sourceCode.getAllComments();
20
+ const ownLineCommentsByEndLine = new Map();
21
+ for (const comment of comments) {
22
+ const { line, column } = comment.loc.start;
23
+ if ((sourceCode.lines[line - 1] ?? "").slice(0, column).trim() === "") {
24
+ ownLineCommentsByEndLine.set(comment.loc.end.line, comment);
25
+ }
26
+ }
27
+
28
+ const explainedAbove = (directive) => {
29
+ let above = ownLineCommentsByEndLine.get(directive.loc.start.line - 1);
30
+ while (
31
+ above &&
32
+ (DIRECTIVE_PATTERN.test(above.value) || EMPTY_COMMENT_PATTERN.test(above.value))
33
+ ) {
34
+ above = ownLineCommentsByEndLine.get(above.loc.start.line - 1);
35
+ }
36
+ return above !== undefined;
37
+ };
38
+
39
+ for (const directive of sourceCode.getDisableDirectives().directives) {
40
+ if (directive.type === "enable" || directive.justification?.trim()) continue;
41
+ if (explainedAbove(directive.node)) continue;
42
+ context.report({
43
+ loc: directive.node.loc,
44
+ message:
45
+ "Say why: end the directive with `-- reason` or put a comment on the line above.",
46
+ });
47
+ }
48
+
49
+ for (const comment of comments) {
50
+ const after = TS_DIRECTIVE_PATTERN.exec(comment.value)?.[1];
51
+ if (after === undefined || after.replace(/^[\s:-]+/u, "").trim()) continue;
52
+ if (explainedAbove(comment)) continue;
53
+ context.report({
54
+ loc: comment.loc,
55
+ message:
56
+ "Say why: write the reason after the directive or in a comment on the line above.",
57
+ });
58
+ }
59
+ },
60
+ };
61
+ },
62
+ };
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ "strict": true,
4
+ "noUncheckedIndexedAccess": true,
5
+ "exactOptionalPropertyTypes": true,
6
+ "noFallthroughCasesInSwitch": true,
7
+ "noPropertyAccessFromIndexSignature": true,
8
+ "forceConsistentCasingInFileNames": true,
9
+ "verbatimModuleSyntax": true,
10
+ "isolatedModules": true,
11
+ "esModuleInterop": true,
12
+ "resolveJsonModule": true,
13
+ "target": "ESNext",
14
+ "lib": ["ESNext"],
15
+ "declaration": true,
16
+ "declarationMap": true,
17
+ "sourceMap": true,
18
+ "outDir": "dist",
19
+ "rootDir": "src",
20
+ "module": "ESNext",
21
+ "moduleResolution": "bundler",
22
+ "jsx": "react-jsx",
23
+ "types": ["bun-types"],
24
+ "skipLibCheck": true,
25
+ "noEmit": true
26
+ },
27
+ "include": ["src/**/*.ts", "src/**/*.tsx"],
28
+ "exclude": ["node_modules", "dist"]
29
+ }
@@ -627,7 +627,7 @@ Team mode is enabled for this session. The rules below **override Phase 4-6** ab
627
627
  When invoking the Plan agent in Phase 4.1, append this additional requirement to the prompt:
628
628
 
629
629
  \`\`\`
630
- 7. (REQUIRED when team mode is active) Output a Team Staffing Recommendation section with these fields — missing fields fail Phase 5.0:
630
+ 7. (REQUIRED when team mode is active) Output a Team Staffing Recommendation section with these fields (missing fields fail Phase 5.0):
631
631
  - total_atomic_steps: integer
632
632
  - file_independent_steps: integer (parallelizable, no cross-file blocker)
633
633
  - cross_file_dependent_steps: integer (has blockers)
@@ -637,8 +637,8 @@ When invoking the Plan agent in Phase 4.1, append this additional requirement to
637
637
  \`\`\`
638
638
 
639
639
  **Classification rules** the plan agent must apply to each step:
640
- - \`quick\`: mechanical edits — LSP rename, extract variable, inline, simple move, signature change without call-site logic.
641
- - \`unspecified-low\`: logic-preserving refactors that need reasoning — extract function, restructure conditional, pattern transformation, cross-file API change.
640
+ - \`quick\` - mechanical edits: LSP rename, extract variable, inline, simple move, signature change without call-site logic.
641
+ - \`unspecified-low\` - logic-preserving refactors that need reasoning: extract function, restructure conditional, pattern transformation, cross-file API change.
642
642
  - Recommend \`team\` path when \`file_independent_steps >= 3\`; recommend \`legacy\` otherwise.
643
643
 
644
644
  ## Phase 5 override: Dispatch path selection
@@ -647,7 +647,7 @@ Read the Team Staffing Recommendation from Phase 4. If any required field is mis
647
647
 
648
648
  Then choose the path:
649
649
 
650
- - **Team path (5.1-T)**: when the plan recommends \`team\` AND \`file_independent_steps >= 3\`. Members execute in parallel, Lead orchestrates, a \`deep\` verifier lives outside the team.
650
+ - **Team path (5.1-T)**: when the plan recommends \`team\` AND \`file_independent_steps >= 3\`. Members execute in parallel, Lead orchestrates, a \`deep-high\` verifier lives outside the team.
651
651
  - **Legacy path (5.1-L)**: otherwise. Use the original 5.1 / 5.2 / 5.3 flow from above.
652
652
 
653
653
  Record the chosen path in the TodoWrite list.
@@ -670,7 +670,7 @@ Record the chosen path in the TodoWrite list.
670
670
  {
671
671
  "kind": "category",
672
672
  "category": "quick",
673
- "prompt": "You handle mechanical refactoring steps (LSP rename, extract variable, inline, simple move, signature change). Use LSP tools for correctness. Apply the task description's per-step instructions verbatim — no scope expansion. After edits, run lsp_diagnostics on touched files. Report via team_send_message(teamRunId=<id>, to=\"lead\", summary=<files touched>, body=<lsp status + diff summary>) + team_task_update(status=completed). Never run tests — the external verifier handles that. Never git add, never --continue."
673
+ "prompt": "You handle mechanical refactoring steps (LSP rename, extract variable, inline, simple move, signature change). Use LSP tools for correctness. Apply the task description's per-step instructions verbatim: no scope expansion. After edits, run lsp_diagnostics on touched files. Report via team_send_message(teamRunId=<id>, to=\"lead\", summary=<files touched>, body=<lsp status + diff summary>) + team_task_update(status=completed). Never run tests: the external verifier handles that. Never git add, never --continue."
674
674
  },
675
675
  { "kind": "category", "category": "quick", "prompt": "Same contract as peer quick worker." },
676
676
  {
@@ -685,8 +685,8 @@ Record the chosen path in the TodoWrite list.
685
685
 
686
686
  Rationale for this composition:
687
687
  - **4 workers = team mode's parallel cap.** 5+ just queues.
688
- - **No verifier team member.** Verification needs \`deep-high\` reasoning (or \`unspecified-high\` fallback). In-team category routing downcasts to the category worker, which is weaker than required — the verifier runs OUTSIDE the team as a \`task(category="deep-high")\`.
689
- - **quick × 2** for mechanical edits, **unspecified-low × 2** for reasoning edits — mirrors the plan's split.
688
+ - **No verifier team member.** Verification needs \`deep-high\` reasoning (or \`unspecified-high\` fallback). In-team category routing downcasts to the category worker, which is weaker than required: the verifier runs OUTSIDE the team as a \`task(category="deep-high")\`.
689
+ - **quick × 2** for mechanical edits, **unspecified-low × 2** for reasoning edits: mirrors the plan's split.
690
690
 
691
691
  **Team lifecycle** (one team, reused until Phase 6 cleanup):
692
692
 
@@ -714,7 +714,7 @@ Rationale for this composition:
714
714
  While any team task is \`pending | claimed | in_progress\`:
715
715
 
716
716
  - Wait for \`<system-reminder>\` or member messages. Avoid tight polling; a single \`team_status\` check is acceptable if no notification arrives within roughly 10 seconds of expected completion.
717
- - On a worker completion report, immediately dispatch an **external verifier** — verification runs OUTSIDE the team because team-member category routing downcasts to the category worker:
717
+ - On a worker completion report, immediately dispatch an **external verifier** (verification runs OUTSIDE the team because team-member category routing downcasts to the category worker):
718
718
  \`\`\`
719
719
  task(
720
720
  category="deep-high",
@@ -735,7 +735,7 @@ Proceed to Phase 6 only when every team task is \`completed\` AND every paired v
735
735
 
736
736
  ## Phase 6 override: Team cleanup before summary
737
737
 
738
- If Phase 5 used the team path, dismantle \`refactor-squad\` BEFORE producing the 6.6 summary. Every exit path — success, escalation, abort — must cleanup; orphan teams poison the next session's precondition check.
738
+ If Phase 5 used the team path, dismantle \`refactor-squad\` BEFORE producing the 6.6 summary. Every exit path (success, escalation, abort) must clean up; orphan teams poison the next session's precondition check.
739
739
 
740
740
  1. \`team_shutdown_request\` for each member, then \`team_approve_shutdown\` if members do not self-approve within a reasonable window.
741
741
  2. \`team_delete(teamRunId=<id>)\`.
@@ -747,9 +747,9 @@ Append to the 6.6 summary a "Dispatch path" line and, when team path was used, t
747
747
 
748
748
  ## MUST NOT (team mode)
749
749
 
750
- - Lead never edits files directly — orchestrate only.
751
- - Do not inline the Intent Card or verify-spec into task descriptions — rely on the broadcasts.
750
+ - Lead never edits files directly: orchestrate only.
751
+ - Do not inline the Intent Card or verify-spec into task descriptions: rely on the broadcasts.
752
752
  - Do not recreate the team mid-session.
753
- - Do not run tests from Lead — the external verifier owns that lane.
754
- - Do not put \`oracle\` / \`librarian\` / \`deep\` into the team spec — curated read-only agents are team-ineligible, and \`deep\` under category routing downcasts to the category worker. Use them via \`task()\` outside the team when needed.
753
+ - Do not run tests from Lead: the external verifier owns that lane.
754
+ - Do not put \`oracle\` / \`librarian\` / a deep lane into the team spec: oracle/librarian are team-ineligible, and a deep lane under category routing downcasts to the category worker. Use them via \`task()\` outside the team when needed.
755
755
  `
@@ -239,7 +239,7 @@ When all top-level checkboxes in `## TODOs` and `## Final Verification Wave` are
239
239
  - No production change before the tests covering that behavior were read and a bug's reproduction captured; existing tests are green on the unchanged code first, and one that contradicts the intent is a FINDING, never edited green.
240
240
  - No `--dry-run` as completion evidence.
241
241
  - No tests-only completion claim. A Manual-QA artifact is required.
242
- - **NO DIRECT IMPLEMENTATION BY THE ORCHESTRATOR.** Root NEVER edits product files, writes tests, or runs QA itself — a spawned worker does.
242
+ - **NO DIRECT IMPLEMENTATION BY THE ORCHESTRATOR.** Root NEVER edits product files, writes tests, or runs QA itself; a spawned worker does.
243
243
  - No completion claim while an applicable ultraqa adversarial class was never probed. Each applicable class needs a captured observable result; each skipped class needs a one-line not-applicable reason in the ledger.
244
244
  - No implementation, review, or merge in the main checkout; every phase works in its task-owned worktree.
245
245
  - No unprefixed session ids in Boulder state. Sessions are always recorded as `codex:<session_id>`.
@@ -13,12 +13,13 @@ ulw-research/
13
13
  │ ├── deliverable-phase.md # lanes, state, destination defaults, interview, memory episodes, design spec, gates, repair, manifest, command reference
14
14
  │ ├── report-gates.md # one row per defect code: severity, integrity, what it detects, how to fix
15
15
  │ ├── report-visualization.md # which visual fits which finding, render commands (charts, Mermaid, PlotNeuralNet), quality bar, visual QA checklist
16
+ │ ├── fact-ledger-grammar.md # the one definition of a valid fact ledger; its per-kind table is rendered from KIND_RULES
16
17
  │ └── latex-report.md
17
18
  └── scripts/
18
19
  ├── report-tools.mjs # CLI entry + dispatcher (COMMANDS, run, main)
19
20
  ├── report-tools-commands.mjs # one function per subcommand
20
21
  ├── cli-support.mjs / entry-guard.mjs # flags, CliError, exit codes, atomic JSON, symlink-safe entry check
21
- ├── contracts.mjs # frozen vocabulary: DEFECT_CODES (severity lives only here), enums, manifest + repair-state validators
22
+ ├── contracts.mjs # frozen vocabulary: DEFECT_CODES (severity lives only here), FIDELITY_CODES, enums, manifest + repair-state validators
22
23
  ├── outcome.mjs # outcome.json manifest, deliverable state, verify, closing briefing
23
24
  ├── repair-tracker.mjs # bounded repair decisions (attempts, plateau, oscillation, wall clock, integrity codes)
24
25
  ├── html-lite.mjs / entities.mjs # HTML tokenizer, selector paths, prose text
@@ -26,13 +27,18 @@ ulw-research/
26
27
  ├── gates-static.mjs + gates-text.mjs / gates-figures.mjs / gates-structure.mjs # static gates G1-G17
27
28
  ├── layout-probe.mjs / gates-layout.mjs # in-page probe source + layout gates L1-L5 over its output
28
29
  ├── format-extract.mjs / format-extract-css.mjs # design-spec draft from a pointed-at HTML or Markdown document
30
+ ├── fact-ledger.mjs # fact ledger IO and writers (addRow, retractRow, supersedeRow, --view table)
31
+ ├── fact-ledger-schema.mjs # ledger vocabulary, validateLedger, the status machine (transitionError) shared with the writers
32
+ ├── fact-ledger-kinds.mjs # KIND_RULES: every per-kind column rule; drives the validator, renders the grammar table (--render-grammar)
33
+ ├── claims-index.mjs # claim-graph.md index: the claim table plus the verified-claims digest
34
+ ├── fidelity-state.mjs # per-sentence failure counts for the fidelity repair loop
29
35
  ├── *.test.ts # co-located bun tests, one per module (unshipped)
30
36
  └── tests/fixtures/ # good/bad reports, boxes.json, reference docs (unshipped)
31
37
  ```
32
38
 
33
39
  ## SURFACE
34
40
 
35
- `node "$SKILL_DIR/scripts/report-tools.mjs" <command>`: `check`, `layout-probe`, `repair decide`, `outcome init`, `outcome set`, `outcome gate`, `outcome render`, `outcome state`, `outcome verify`, `outcome finish`, `outcome briefing`, `format-extract`, `--help --json`. Exit codes: `0` pass, `1` semantic failure (blockers, a failed verify, a blocked repair), `2` usage or IO. JSON on stdout, one summary line on stderr. Flags per command: `references/deliverable-phase.md` section 10.
41
+ `node "$SKILL_DIR/scripts/report-tools.mjs" <command>`: `check`, `layout-probe`, `repair decide`, `outcome init`, `outcome set`, `outcome gate`, `outcome render`, `outcome state`, `outcome verify`, `outcome finish`, `outcome briefing`, `format-extract`, `--help --json`. Gates recorded by `outcome gate`, in order: `static`, `fidelity`, `layout`, `visual`, `proofread` (`fidelity` is recorded `not_run` until the fidelity verifier ships). Exit codes: `0` pass, `1` semantic failure (blockers, a failed verify, a blocked repair), `2` usage or IO. JSON on stdout, one summary line on stderr. Flags per command: `references/deliverable-phase.md` section 10.
36
42
 
37
43
  ## CONVENTIONS
38
44
 
@@ -41,7 +47,7 @@ ulw-research/
41
47
  - The CLI never launches a browser. The layout probe is printed as one async expression; the orchestrator evaluates it through the browser skill's owned headless engine and passes the result back with `check --layout`.
42
48
  - Time is always injected (`--now`, `startedAt`); no module reads the clock inside a decision.
43
49
  - Tests are co-located given/when/then bun tests; CLI tests spawn `node` with bun removed from `PATH`. Fixtures live only under `scripts/tests/fixtures/`, are depersonalized, and never ship.
44
- - The senpi source dir (`packages/omo-senpi/skills/ulw-research/`) intentionally has no `scripts/`, `references/report-gates.md`, `references/deliverable-phase.md`, or `references/report-visualization.md`: the senpi sync overlays them from here byte-for-byte (`sharedAssets` in `packages/omo-senpi/plugin/scripts/native-skill-sources.mjs`), and both editions' sync suites assert the shipped copies equal these sources.
50
+ - The senpi source dir (`packages/omo-senpi/skills/ulw-research/`) intentionally has no `scripts/`, `references/report-gates.md`, `references/deliverable-phase.md`, `references/report-visualization.md`, or `references/fact-ledger-grammar.md`: the senpi sync overlays them from here byte-for-byte (`sharedAssets` in `packages/omo-senpi/plugin/scripts/native-skill-sources.mjs`), and both editions' sync suites assert the shipped copies equal these sources.
45
51
  - References and scripts carry no Hangul (Korean match strings are `\u` escapes) and never three consecutive newlines (the senpi sync normalizes those and would break byte equality).
46
52
 
47
53
  ## ANTI-PATTERNS