oh-my-opencode 4.15.0 → 4.16.0

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 (239) hide show
  1. package/dist/cli/doctor/checks/tui-plugin-config.d.ts +4 -4
  2. package/dist/cli/index.js +1149 -1040
  3. package/dist/cli/install-senpi/index.d.ts +1 -0
  4. package/dist/cli/run/poll-for-completion.d.ts +4 -0
  5. package/dist/cli/run/session-resolver.d.ts +1 -0
  6. package/dist/cli/senpi-platform-flag.d.ts +4 -0
  7. package/dist/cli/types.d.ts +2 -1
  8. package/dist/cli-node/index.js +1149 -1040
  9. package/dist/features/background-agent/manager.d.ts +16 -0
  10. package/dist/hooks/anthropic-context-window-limit-recovery/aggressive-truncation-strategy.d.ts +1 -0
  11. package/dist/index.js +1334 -1146
  12. package/dist/skills/debugging/references/methodology/06-fix.md +6 -0
  13. package/dist/skills/frontend/ATTRIBUTION.md +13 -3
  14. package/dist/skills/frontend/SKILL.md +8 -3
  15. package/dist/skills/frontend/references/design/README.md +1 -1
  16. package/dist/skills/frontend/references/design/_INDEX.md +1 -1
  17. package/dist/skills/frontend/references/design/lazyweb.md +77 -0
  18. package/dist/skills/frontend/references/design/stitch-design-example.md +121 -0
  19. package/dist/skills/frontend/references/designpowers/EVIDENCE.md +10 -2
  20. package/dist/skills/frontend/references/designpowers/UPSTREAM.md +1 -1
  21. package/dist/skills/programming/SKILL.md +10 -1
  22. package/dist/skills/programming/references/logging.md +91 -0
  23. package/dist/skills/ulw-plan/SKILL.md +5 -5
  24. package/dist/skills/ulw-plan/references/full-workflow.md +7 -7
  25. package/dist/skills/ulw-plan/references/intent-unclear.md +3 -3
  26. package/dist/skills/ulw-research/ATTRIBUTION.md +2 -2
  27. package/dist/skills/ulw-research/SKILL.md +28 -7
  28. package/dist/tools/skill/description-formatter.d.ts +1 -0
  29. package/dist/tools/skill/description-formatter.test-support.d.ts +9 -0
  30. package/dist/tools/skill/zauc-mocks-skill-tools/test-support.d.ts +25 -0
  31. package/dist/tui.js +121 -419
  32. package/package.json +32 -15
  33. package/packages/git-bash-mcp/dist/cli.js +2 -2
  34. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  35. package/packages/omo-codex/plugin/components/bootstrap/AGENTS.md +55 -0
  36. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +212 -117
  37. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  38. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +51 -0
  39. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +936 -248
  40. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +233 -135
  41. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  42. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +29 -0
  43. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +13 -0
  44. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +25 -0
  45. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +3 -1
  46. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +30 -1
  47. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +16 -2
  48. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +80 -0
  49. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +34 -0
  50. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +107 -0
  51. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +26 -0
  52. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +29 -0
  53. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +8 -21
  54. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +108 -0
  55. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +76 -0
  56. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +17 -111
  57. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +1 -1
  58. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +45 -67
  59. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +56 -0
  60. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  61. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +31 -0
  62. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  63. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +45 -0
  64. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  65. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  66. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +37 -102
  67. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  68. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  69. package/packages/omo-codex/plugin/components/teammode/AGENTS.md +46 -0
  70. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  71. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +6 -0
  72. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +6 -0
  73. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  74. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -2
  75. package/packages/omo-codex/plugin/components/ultrawork/CHANGELOG.md +2 -0
  76. package/packages/omo-codex/plugin/components/ultrawork/README.md +3 -3
  77. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +51 -2
  78. package/packages/omo-codex/plugin/components/ultrawork/package.json +2 -1
  79. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +14 -1
  80. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +380 -0
  81. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +5 -2
  82. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +4 -4
  83. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +2 -2
  84. package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +5 -3
  85. package/packages/omo-codex/plugin/components/ultrawork/src/skill-pointer.ts +56 -0
  86. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +4 -4
  87. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +12 -0
  88. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +1 -0
  89. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +82 -0
  90. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -0
  91. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +56 -5
  92. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.d.ts +1 -0
  93. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +5 -1
  94. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.d.ts +2 -1
  95. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.js +5 -3
  96. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-skill-pointer.d.ts +7 -0
  97. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-skill-pointer.js +46 -0
  98. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  99. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -1
  100. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +5 -1
  101. package/packages/omo-codex/plugin/components/ulw-loop/src/ultrawork-directive.ts +9 -3
  102. package/packages/omo-codex/plugin/components/ulw-loop/src/ultrawork-skill-pointer.ts +55 -0
  103. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +49 -0
  104. package/packages/omo-codex/plugin/package-lock.json +13 -13
  105. package/packages/omo-codex/plugin/package.json +1 -1
  106. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +147 -2
  107. package/packages/omo-codex/plugin/scripts/auto-update-release-notes.mjs +33 -0
  108. package/packages/omo-codex/plugin/scripts/auto-update.mjs +48 -10
  109. package/packages/omo-codex/plugin/scripts/build-components.mjs +63 -17
  110. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +10 -3
  111. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +19 -0
  112. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +18 -0
  113. package/packages/omo-codex/plugin/skills/debugging/references/methodology/06-fix.md +6 -0
  114. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +13 -3
  115. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +8 -3
  116. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +1 -1
  117. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -1
  118. package/packages/omo-codex/plugin/skills/frontend/references/design/lazyweb.md +77 -0
  119. package/packages/omo-codex/plugin/skills/frontend/references/design/stitch-design-example.md +121 -0
  120. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/EVIDENCE.md +10 -2
  121. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/UPSTREAM.md +1 -1
  122. package/packages/omo-codex/plugin/skills/programming/SKILL.md +10 -1
  123. package/packages/omo-codex/plugin/skills/programming/references/logging.md +91 -0
  124. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +380 -0
  125. package/packages/omo-codex/plugin/skills/ultrawork/agents/openai.yaml +2 -0
  126. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -1
  127. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +5 -2
  128. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +4 -4
  129. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +2 -2
  130. package/packages/omo-codex/plugin/skills/ulw-research/ATTRIBUTION.md +2 -2
  131. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +31 -10
  132. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +32 -0
  133. package/packages/omo-codex/plugin/test/auto-update.test.mjs +153 -3
  134. package/packages/omo-codex/plugin/test/install-time-build-runtime.test.mjs +1 -1
  135. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +20 -1
  136. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +39 -10
  137. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +56 -0
  138. package/packages/omo-codex/plugin/test/ulw-research-epistemic-contract.test.mjs +98 -0
  139. package/packages/omo-codex/plugin/test/ulw-research-skill-contract.test.mjs +25 -7
  140. package/packages/omo-codex/scripts/install-dist/install-local.mjs +612 -4193
  141. package/packages/shared-skills/skills/debugging/references/methodology/06-fix.md +6 -0
  142. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +13 -3
  143. package/packages/shared-skills/skills/frontend/SKILL.md +8 -3
  144. package/packages/shared-skills/skills/frontend/references/design/README.md +1 -1
  145. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -1
  146. package/packages/shared-skills/skills/frontend/references/design/lazyweb.md +77 -0
  147. package/packages/shared-skills/skills/frontend/references/design/stitch-design-example.md +121 -0
  148. package/packages/shared-skills/skills/frontend/references/designpowers/EVIDENCE.md +10 -2
  149. package/packages/shared-skills/skills/frontend/references/designpowers/UPSTREAM.md +1 -1
  150. package/packages/shared-skills/skills/programming/SKILL.md +10 -1
  151. package/packages/shared-skills/skills/programming/references/logging.md +91 -0
  152. package/packages/shared-skills/skills/ulw-plan/SKILL.md +5 -5
  153. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +7 -7
  154. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +3 -3
  155. package/packages/shared-skills/skills/ulw-research/ATTRIBUTION.md +2 -2
  156. package/packages/shared-skills/skills/ulw-research/SKILL.md +28 -7
  157. package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +0 -10
  158. package/packages/omo-codex/plugin/skills/ultraresearch/agents/openai.yaml +0 -2
  159. /package/dist/skills/frontend/references/designpowers/vendor/skills/accessible-content/{SKILL.md → reference.md} +0 -0
  160. /package/dist/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/{SKILL.md → reference.md} +0 -0
  161. /package/dist/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/{SKILL.md → reference.md} +0 -0
  162. /package/dist/skills/frontend/references/designpowers/vendor/skills/design-debate/{SKILL.md → reference.md} +0 -0
  163. /package/dist/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/{SKILL.md → reference.md} +0 -0
  164. /package/dist/skills/frontend/references/designpowers/vendor/skills/design-handoff/{SKILL.md → reference.md} +0 -0
  165. /package/dist/skills/frontend/references/designpowers/vendor/skills/design-md/{SKILL.md → reference.md} +0 -0
  166. /package/dist/skills/frontend/references/designpowers/vendor/skills/design-retrospective/{SKILL.md → reference.md} +0 -0
  167. /package/dist/skills/frontend/references/designpowers/vendor/skills/design-review/{SKILL.md → reference.md} +0 -0
  168. /package/dist/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/{SKILL.md → reference.md} +0 -0
  169. /package/dist/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/{SKILL.md → reference.md} +0 -0
  170. /package/dist/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/{SKILL.md → reference.md} +0 -0
  171. /package/dist/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/{SKILL.md → reference.md} +0 -0
  172. /package/dist/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/{SKILL.md → reference.md} +0 -0
  173. /package/dist/skills/frontend/references/designpowers/vendor/skills/interaction-design/{SKILL.md → reference.md} +0 -0
  174. /package/dist/skills/frontend/references/designpowers/vendor/skills/motion-choreography/{SKILL.md → reference.md} +0 -0
  175. /package/dist/skills/frontend/references/designpowers/vendor/skills/research-planning/{SKILL.md → reference.md} +0 -0
  176. /package/dist/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/{SKILL.md → reference.md} +0 -0
  177. /package/dist/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/{SKILL.md → reference.md} +0 -0
  178. /package/dist/skills/frontend/references/designpowers/vendor/skills/taste-feedback/{SKILL.md → reference.md} +0 -0
  179. /package/dist/skills/frontend/references/designpowers/vendor/skills/taste-report/{SKILL.md → reference.md} +0 -0
  180. /package/dist/skills/frontend/references/designpowers/vendor/skills/token-architecture/{SKILL.md → reference.md} +0 -0
  181. /package/dist/skills/frontend/references/designpowers/vendor/skills/ui-composition/{SKILL.md → reference.md} +0 -0
  182. /package/dist/skills/frontend/references/designpowers/vendor/skills/usability-testing/{SKILL.md → reference.md} +0 -0
  183. /package/dist/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/{SKILL.md → reference.md} +0 -0
  184. /package/dist/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/{SKILL.md → reference.md} +0 -0
  185. /package/dist/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/{SKILL.md → reference.md} +0 -0
  186. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/accessible-content/{SKILL.md → reference.md} +0 -0
  187. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/{SKILL.md → reference.md} +0 -0
  188. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/{SKILL.md → reference.md} +0 -0
  189. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-debate/{SKILL.md → reference.md} +0 -0
  190. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/{SKILL.md → reference.md} +0 -0
  191. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-handoff/{SKILL.md → reference.md} +0 -0
  192. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-md/{SKILL.md → reference.md} +0 -0
  193. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-retrospective/{SKILL.md → reference.md} +0 -0
  194. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-review/{SKILL.md → reference.md} +0 -0
  195. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/{SKILL.md → reference.md} +0 -0
  196. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/{SKILL.md → reference.md} +0 -0
  197. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/{SKILL.md → reference.md} +0 -0
  198. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/{SKILL.md → reference.md} +0 -0
  199. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/{SKILL.md → reference.md} +0 -0
  200. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/interaction-design/{SKILL.md → reference.md} +0 -0
  201. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/motion-choreography/{SKILL.md → reference.md} +0 -0
  202. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/research-planning/{SKILL.md → reference.md} +0 -0
  203. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/{SKILL.md → reference.md} +0 -0
  204. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/{SKILL.md → reference.md} +0 -0
  205. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/taste-feedback/{SKILL.md → reference.md} +0 -0
  206. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/taste-report/{SKILL.md → reference.md} +0 -0
  207. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/token-architecture/{SKILL.md → reference.md} +0 -0
  208. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/ui-composition/{SKILL.md → reference.md} +0 -0
  209. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/usability-testing/{SKILL.md → reference.md} +0 -0
  210. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/{SKILL.md → reference.md} +0 -0
  211. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/{SKILL.md → reference.md} +0 -0
  212. /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/{SKILL.md → reference.md} +0 -0
  213. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/accessible-content/{SKILL.md → reference.md} +0 -0
  214. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/{SKILL.md → reference.md} +0 -0
  215. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/{SKILL.md → reference.md} +0 -0
  216. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-debate/{SKILL.md → reference.md} +0 -0
  217. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/{SKILL.md → reference.md} +0 -0
  218. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-handoff/{SKILL.md → reference.md} +0 -0
  219. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-md/{SKILL.md → reference.md} +0 -0
  220. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-retrospective/{SKILL.md → reference.md} +0 -0
  221. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-review/{SKILL.md → reference.md} +0 -0
  222. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/{SKILL.md → reference.md} +0 -0
  223. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/{SKILL.md → reference.md} +0 -0
  224. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/{SKILL.md → reference.md} +0 -0
  225. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/{SKILL.md → reference.md} +0 -0
  226. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/{SKILL.md → reference.md} +0 -0
  227. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/interaction-design/{SKILL.md → reference.md} +0 -0
  228. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/motion-choreography/{SKILL.md → reference.md} +0 -0
  229. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/research-planning/{SKILL.md → reference.md} +0 -0
  230. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/{SKILL.md → reference.md} +0 -0
  231. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/{SKILL.md → reference.md} +0 -0
  232. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/taste-feedback/{SKILL.md → reference.md} +0 -0
  233. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/taste-report/{SKILL.md → reference.md} +0 -0
  234. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/token-architecture/{SKILL.md → reference.md} +0 -0
  235. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/ui-composition/{SKILL.md → reference.md} +0 -0
  236. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/usability-testing/{SKILL.md → reference.md} +0 -0
  237. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/{SKILL.md → reference.md} +0 -0
  238. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/{SKILL.md → reference.md} +0 -0
  239. /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/{SKILL.md → reference.md} +0 -0
@@ -1,6 +1,7 @@
1
1
  import { spawn, spawnSync } from "node:child_process";
2
- import { readFileSync } from "node:fs";
3
- import { dirname, join } from "node:path";
2
+ import { existsSync, lstatSync, readFileSync, readdirSync, readlinkSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
4
5
  import { fileURLToPath } from "node:url";
5
6
 
6
7
  import { detectInstallFlow, resolveInstallSnapshotPath } from "./install-flow.mjs";
@@ -9,6 +10,23 @@ import { resolveSpawnInvocation } from "./spawn-command.mjs";
9
10
  const DEFAULT_UPDATE_COMMAND = "npx";
10
11
  const DEFAULT_UPDATE_ARGS = ["--yes", "lazycodex-ai@latest", "install", "--no-tui", "--codex-autonomous"];
11
12
  const DEFAULT_LATEST_VERSION_TIMEOUT_MS = 1_500;
13
+ const SISYPHUS_MARKETPLACE_NAME = "sisyphuslabs";
14
+ const OMO_PLUGIN_NAME = "omo";
15
+ const COMMAND_SHIM_MARKER = ":: generated by oh-my-openagent Codex installer";
16
+ const MANAGED_COMPONENT_BIN_NAMES = new Set([
17
+ "lazycodex-executor-verify",
18
+ "omo-codegraph",
19
+ "omo-comment-checker",
20
+ "omo-git-bash-hook",
21
+ "omo-lsp",
22
+ "omo-rules",
23
+ "omo-start-work-continuation",
24
+ "omo-telemetry",
25
+ "omo-ultrawork",
26
+ "omo-ulw-loop",
27
+ "ulw",
28
+ "ulw-loop",
29
+ ]);
12
30
 
13
31
  export function resolveLazyCodexUpdatePlan({ currentVersion, latestVersion, command = DEFAULT_UPDATE_COMMAND, args = DEFAULT_UPDATE_ARGS } = {}) {
14
32
  const current = parseVersion(currentVersion);
@@ -38,6 +56,16 @@ export function detectAutoUpdateInstallFlow(env) {
38
56
  return detectInstallFlow({ pluginRoot: resolveAutoUpdatePluginRoot(env), env });
39
57
  }
40
58
 
59
+ export function detectMarketplaceLocalRepair(env = {}) {
60
+ const codexHome = resolveCodexHome(env);
61
+ const marketplaceRoot = join(codexHome, "plugins", "cache", SISYPHUS_MARKETPLACE_NAME);
62
+ const reasons = [
63
+ ...missingCachedMarketplaceSources(marketplaceRoot),
64
+ ...missingManagedBinTargets({ env, marketplaceRoot }),
65
+ ];
66
+ return { needsRepair: reasons.length > 0, reasons };
67
+ }
68
+
41
69
  export function resolveCurrentVersion(env) {
42
70
  if (env.LAZYCODEX_CURRENT_VERSION?.trim()) return env.LAZYCODEX_CURRENT_VERSION.trim();
43
71
  const pluginRoot = dirname(dirname(fileURLToPath(import.meta.url)));
@@ -120,6 +148,109 @@ function resolveAutoUpdatePluginRoot(env) {
120
148
  return dirname(dirname(fileURLToPath(import.meta.url)));
121
149
  }
122
150
 
151
+ function resolveCodexHome(env) {
152
+ return resolve(env.CODEX_HOME?.trim() || join(resolveHome(env), ".codex"));
153
+ }
154
+
155
+ function resolveHome(env) {
156
+ return env.HOME?.trim() || homedir();
157
+ }
158
+
159
+ function resolveInstallerBinDir(env, codexHome) {
160
+ if (env.CODEX_LOCAL_BIN_DIR?.trim()) return resolve(env.CODEX_LOCAL_BIN_DIR.trim());
161
+ const home = resolveHome(env);
162
+ const defaultCodexHome = resolve(home, ".codex");
163
+ const resolvedCodexHome = resolve(codexHome);
164
+ return resolvedCodexHome === defaultCodexHome ? resolve(home, ".local", "bin") : join(resolvedCodexHome, "bin");
165
+ }
166
+
167
+ function missingCachedMarketplaceSources(marketplaceRoot) {
168
+ const manifest = readJsonObject(join(marketplaceRoot, ".agents", "plugins", "marketplace.json"));
169
+ if (manifest === undefined || !Array.isArray(manifest.plugins)) return [];
170
+ const reasons = [];
171
+ for (const plugin of manifest.plugins) {
172
+ if (!isPlainRecord(plugin) || plugin.name !== OMO_PLUGIN_NAME) continue;
173
+ const localPath = localMarketplaceSourcePath(plugin.source);
174
+ if (localPath === undefined) continue;
175
+ const resolvedPath = resolve(marketplaceRoot, localPath);
176
+ if (!isPathInside(resolvedPath, marketplaceRoot)) {
177
+ reasons.push({ kind: "invalid-marketplace-payload" });
178
+ continue;
179
+ }
180
+ if (!existsSync(resolvedPath)) {
181
+ reasons.push({ kind: "missing-marketplace-payload" });
182
+ }
183
+ }
184
+ return reasons;
185
+ }
186
+
187
+ function missingManagedBinTargets({ env, marketplaceRoot }) {
188
+ const binDir = resolveInstallerBinDir(env, resolveCodexHome(env));
189
+ let names;
190
+ try {
191
+ names = readdirSync(binDir);
192
+ } catch (error) {
193
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return [];
194
+ throw error;
195
+ }
196
+ const reasons = [];
197
+ for (const name of names) {
198
+ const binName = managedBinNameForEntry(name);
199
+ if (binName === undefined) continue;
200
+ const linkPath = join(binDir, name);
201
+ let target;
202
+ try {
203
+ target = readManagedBinTarget(linkPath);
204
+ } catch (error) {
205
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") continue;
206
+ throw error;
207
+ }
208
+ if (target === undefined) continue;
209
+ if (!isManagedCachedComponentTarget(target, marketplaceRoot) || existsSync(target)) continue;
210
+ reasons.push({ kind: "dangling-managed-bin", binName });
211
+ }
212
+ return reasons;
213
+ }
214
+
215
+ function managedBinNameForEntry(name) {
216
+ const candidate = name.endsWith(".cmd") ? name.slice(0, -4) : name;
217
+ return MANAGED_COMPONENT_BIN_NAMES.has(candidate) ? candidate : undefined;
218
+ }
219
+
220
+ function readManagedBinTarget(linkPath) {
221
+ const linkStat = lstatSync(linkPath);
222
+ if (linkStat.isSymbolicLink()) {
223
+ const linkTarget = readlinkSync(linkPath);
224
+ return isAbsolute(linkTarget) ? linkTarget : resolve(dirname(linkPath), linkTarget);
225
+ }
226
+ if (!linkStat.isFile()) return undefined;
227
+ const content = readFileSync(linkPath, "utf8");
228
+ if (!content.includes(COMMAND_SHIM_MARKER)) return undefined;
229
+ return extractCommandShimTarget(content);
230
+ }
231
+
232
+ function extractCommandShimTarget(content) {
233
+ const match = /"([^"\r\n]+components[\\/][^"\r\n]+[\\/]dist[\\/]cli\.js)" %\*/.exec(content);
234
+ return match?.[1];
235
+ }
236
+
237
+ function localMarketplaceSourcePath(source) {
238
+ if (!isPlainRecord(source)) return undefined;
239
+ return source.source === "local" && typeof source.path === "string" ? source.path : undefined;
240
+ }
241
+
242
+ function isManagedCachedComponentTarget(target, marketplaceRoot) {
243
+ if (!isPathInside(target, marketplaceRoot)) return false;
244
+ const parts = target.split(/[\\/]+/);
245
+ const suffix = parts.slice(-4);
246
+ return suffix[0] === "components" && suffix[2] === "dist" && suffix[3] === "cli.js";
247
+ }
248
+
249
+ function isPathInside(path, root) {
250
+ const relativePath = relative(resolve(root), resolve(path));
251
+ return relativePath === "" || (!relativePath.startsWith("..") && !isAbsolute(relativePath));
252
+ }
253
+
123
254
  function readVersionManifest(path) {
124
255
  try {
125
256
  const parsed = JSON.parse(readFileSync(path, "utf8"));
@@ -131,3 +262,17 @@ function readVersionManifest(path) {
131
262
  throw error;
132
263
  }
133
264
  }
265
+
266
+ function readJsonObject(path) {
267
+ try {
268
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
269
+ return isPlainRecord(parsed) ? parsed : undefined;
270
+ } catch (error) {
271
+ if (error instanceof Error) return undefined;
272
+ throw error;
273
+ }
274
+ }
275
+
276
+ function isPlainRecord(value) {
277
+ return typeof value === "object" && value !== null && !Array.isArray(value);
278
+ }
@@ -25,6 +25,35 @@ export function formatMarketplaceFlowNotice({ updateContext, releaseNotes }) {
25
25
  ].join(" ");
26
26
  }
27
27
 
28
+ export function formatMarketplaceRepairStartedNotice({ pendingNotice, releaseNotes, repairReasons = [] }) {
29
+ const reasons = formatRepairReasons(repairReasons);
30
+ return [
31
+ `[LazyCodex] Auto-update repair started in the background: v${pendingNotice.fromVersion} -> v${pendingNotice.toVersion}.`,
32
+ `Detected stale local LazyCodex cache/bin state: ${reasons}.`,
33
+ "LazyCodex started its bundled reinstall repair. Tell the user, in the user's preferred tone, that LazyCodex found a broken local cache or command link and started a repair; recommend starting a new Codex session after it completes.",
34
+ formatReleaseNotesForNotice({ version: pendingNotice.toVersion, releaseNotes }),
35
+ ].join(" ");
36
+ }
37
+
38
+ function formatRepairReasons(repairReasons) {
39
+ if (repairReasons.length === 0) return "stale local cache state was detected";
40
+ return [...new Set(repairReasons.map(formatRepairReason))].join("; ");
41
+ }
42
+
43
+ function formatRepairReason(reason) {
44
+ if (!isPlainRecord(reason)) return "stale local cache state";
45
+ if (reason.kind === "missing-marketplace-payload") return "missing marketplace payload";
46
+ if (reason.kind === "invalid-marketplace-payload") return "invalid marketplace payload";
47
+ if (reason.kind === "dangling-managed-bin" && typeof reason.binName === "string") {
48
+ return `dangling managed command link: ${sanitizeBinName(reason.binName)}`;
49
+ }
50
+ return "stale local cache state";
51
+ }
52
+
53
+ function sanitizeBinName(binName) {
54
+ return /^[a-z0-9][a-z0-9._-]{0,80}$/i.test(binName) ? binName : "managed command";
55
+ }
56
+
28
57
  export async function resolveReleaseNotes({ env, latestVersion }) {
29
58
  const override = env.LAZYCODEX_RELEASE_NOTES?.trim();
30
59
  if (override) return truncateReleaseNotes(override);
@@ -133,3 +162,7 @@ function parsePositiveInteger(value, fallback) {
133
162
  const parsed = Number.parseInt(value, 10);
134
163
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
135
164
  }
165
+
166
+ function isPlainRecord(value) {
167
+ return typeof value === "object" && value !== null && !Array.isArray(value);
168
+ }
@@ -14,6 +14,7 @@ import {
14
14
  import {
15
15
  compareVersions,
16
16
  defaultRunCommandForManualUpdate,
17
+ detectMarketplaceLocalRepair,
17
18
  detectAutoUpdateInstallFlow,
18
19
  parsePositiveInteger,
19
20
  parseVersion,
@@ -23,7 +24,12 @@ import {
23
24
  resolveLatestVersion,
24
25
  resolveLazyCodexUpdatePlan,
25
26
  } from "./auto-update-plan.mjs";
26
- import { formatMarketplaceFlowNotice, formatUpdateStartedNotice, resolveReleaseNotes } from "./auto-update-release-notes.mjs";
27
+ import {
28
+ formatMarketplaceFlowNotice,
29
+ formatMarketplaceRepairStartedNotice,
30
+ formatUpdateStartedNotice,
31
+ resolveReleaseNotes,
32
+ } from "./auto-update-release-notes.mjs";
27
33
  import { migrateCodexConfig } from "./migrate-codex-config.mjs";
28
34
  import { migrateOmoSotConfig } from "./migrate-omo-sot.mjs";
29
35
  import { resolveSpawnInvocation } from "./spawn-command.mjs";
@@ -38,9 +44,11 @@ export function resolveAutoUpdatePlan({ env = process.env, now = Date.now(), las
38
44
  return { shouldRun: false, reason: "disabled" };
39
45
  }
40
46
 
47
+ const flow = installFlow ?? detectAutoUpdateInstallFlow(env).flow;
48
+ const marketplaceRepair = flow === "marketplace" ? detectMarketplaceLocalRepair(env) : undefined;
41
49
  const intervalMs = parsePositiveInteger(env.LAZYCODEX_AUTO_UPDATE_INTERVAL_MS, DEFAULT_INTERVAL_MS);
42
50
  const successStatus = lastStatus === undefined || lastStatus === "success";
43
- if (successStatus && typeof lastCheckedAt === "number" && intervalMs > 0 && now - lastCheckedAt < intervalMs) {
51
+ if (marketplaceRepair?.needsRepair !== true && successStatus && typeof lastCheckedAt === "number" && intervalMs > 0 && now - lastCheckedAt < intervalMs) {
44
52
  return { shouldRun: false, reason: "throttled" };
45
53
  }
46
54
  const retryIntervalMs = parsePositiveInteger(env.LAZYCODEX_AUTO_UPDATE_RETRY_INTERVAL_MS, DEFAULT_RETRY_INTERVAL_MS);
@@ -48,8 +56,26 @@ export function resolveAutoUpdatePlan({ env = process.env, now = Date.now(), las
48
56
  return { shouldRun: false, reason: "retry-throttled" };
49
57
  }
50
58
 
51
- const flow = installFlow ?? detectAutoUpdateInstallFlow(env).flow;
52
- if (flow === "marketplace") return { shouldRun: false, reason: "marketplace-flow" };
59
+ if (flow === "marketplace") {
60
+ const repair = marketplaceRepair ?? detectMarketplaceLocalRepair(env);
61
+ if (!repair.needsRepair) return { shouldRun: false, reason: "marketplace-flow" };
62
+ const currentVersion = resolveCurrentVersion(env) ?? "unknown";
63
+ const latestVersion = resolveLatestVersion(env) ?? currentVersion ?? "latest";
64
+ return {
65
+ shouldRun: true,
66
+ kind: "marketplace-local-repair",
67
+ repairReasons: repair.reasons,
68
+ command: resolveCommand(env),
69
+ args: resolveArgs(env),
70
+ currentVersion,
71
+ latestVersion,
72
+ env: {
73
+ ...env,
74
+ LAZYCODEX_AUTO_UPDATE_DISABLED: "1",
75
+ OMO_CODEX_AUTO_UPDATE_DISABLED: "1",
76
+ },
77
+ };
78
+ }
53
79
 
54
80
  const currentVersion = resolveCurrentVersion(env);
55
81
  const latestVersion = resolveLatestVersion(env);
@@ -142,7 +168,13 @@ export async function runAutoUpdateCheck({ env = process.env, now = Date.now() }
142
168
  return { started: false, reason: "locked", notices };
143
169
  }
144
170
  try {
145
- await appendUpdateLog(env, now, "started", { command: plan.command, args: plan.args });
171
+ await appendUpdateLog(env, now, "started", plan.kind === "marketplace-local-repair"
172
+ ? { kind: plan.kind, repairReasons: plan.repairReasons ?? [] }
173
+ : {
174
+ command: plan.command,
175
+ args: plan.args,
176
+ ...(plan.kind === undefined ? {} : { kind: plan.kind }),
177
+ });
146
178
  const pendingNotice = { fromVersion: plan.currentVersion, toVersion: plan.latestVersion, startedAt: now };
147
179
  const releaseNotes = await resolveReleaseNotes({ env, latestVersion: plan.latestVersion });
148
180
  if (env.LAZYCODEX_AUTO_UPDATE_WAIT === "1") {
@@ -155,7 +187,7 @@ export async function runAutoUpdateCheck({ env = process.env, now = Date.now() }
155
187
  await appendUpdateLog(env, now, "finished", { status });
156
188
  if (status === 0) {
157
189
  await writeState(statePath, { lastCheckedAt: now, lastAttemptedAt: now, lastStatus: "success", pendingNotice });
158
- await recordUpdateStartedNotice({ env, now, notices, pendingNotice, releaseNotes });
190
+ await recordUpdateStartedNotice({ env, now, notices, pendingNotice, releaseNotes, plan });
159
191
  } else {
160
192
  await writeState(statePath, { lastAttemptedAt: now, lastStatus: "failed" });
161
193
  }
@@ -169,7 +201,7 @@ export async function runAutoUpdateCheck({ env = process.env, now = Date.now() }
169
201
  detached: true,
170
202
  });
171
203
  await writeState(statePath, { lastAttemptedAt: now, lastStatus: "started", pendingNotice });
172
- await recordUpdateStartedNotice({ env, now, notices, pendingNotice, releaseNotes });
204
+ await recordUpdateStartedNotice({ env, now, notices, pendingNotice, releaseNotes, plan });
173
205
  child.unref();
174
206
  return { started: true, notices };
175
207
  } finally {
@@ -197,10 +229,16 @@ async function settlePendingNotice({ env, now, statePath, state, notices }) {
197
229
  return nextState;
198
230
  }
199
231
 
200
- async function recordUpdateStartedNotice({ env, now, notices, pendingNotice, releaseNotes }) {
201
- notices.push(formatUpdateStartedNotice({ pendingNotice, releaseNotes }));
232
+ async function recordUpdateStartedNotice({ env, now, notices, pendingNotice, releaseNotes, plan }) {
233
+ notices.push(plan.kind === "marketplace-local-repair"
234
+ ? formatMarketplaceRepairStartedNotice({
235
+ pendingNotice,
236
+ releaseNotes,
237
+ repairReasons: plan.repairReasons ?? [],
238
+ })
239
+ : formatUpdateStartedNotice({ pendingNotice, releaseNotes }));
202
240
  await appendUpdateLog(env, now, "notified", {
203
- kind: "update-started",
241
+ kind: plan.kind === "marketplace-local-repair" ? "marketplace-local-repair-started" : "update-started",
204
242
  fromVersion: pendingNotice.fromVersion,
205
243
  toVersion: pendingNotice.toVersion,
206
244
  });
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { spawnSync } from "node:child_process";
2
+ import { spawn } from "node:child_process";
3
+ import { availableParallelism } from "node:os";
3
4
  import { readdir, readFile, writeFile } from "node:fs/promises";
4
5
  import { builtinModules } from "node:module";
5
6
  import { dirname, join } from "node:path";
@@ -11,22 +12,50 @@ const workspaces = Array.isArray(packageJson.workspaces) ? packageJson.workspace
11
12
  const workspaceSet = new Set(workspaces);
12
13
  const builtinModuleNames = new Set(builtinModules.filter((moduleName) => !moduleName.startsWith("_")));
13
14
 
15
+ const workspaceComponents = [];
14
16
  for (const workspace of workspaces) {
15
17
  if (typeof workspace !== "string" || !workspace.startsWith("components/")) continue;
16
18
  if (!(await hasBuildScript(workspace))) continue;
17
-
18
- console.log(`Building ${workspace}`);
19
- run("npm", ["run", "--workspace", workspace, "build"], root);
20
- await bundleCli(workspace);
19
+ workspaceComponents.push({
20
+ componentPath: workspace,
21
+ buildCommand: "npm",
22
+ buildArgs: ["run", "--workspace", workspace, "build"],
23
+ buildCwd: root,
24
+ });
21
25
  }
22
26
 
27
+ const standaloneComponents = [];
23
28
  for (const componentName of await readStandaloneComponentNames()) {
24
29
  const componentPath = `components/${componentName}`;
25
30
  if (!(await hasBuildScript(componentPath))) continue;
31
+ standaloneComponents.push({
32
+ componentPath,
33
+ buildCommand: "npm",
34
+ buildArgs: ["run", "build"],
35
+ buildCwd: join(root, componentPath),
36
+ });
37
+ }
38
+
39
+ const tasks = [...workspaceComponents, ...standaloneComponents];
40
+ const concurrency = Math.max(1, Math.min(tasks.length, availableParallelism()));
41
+ await runTasksWithConcurrency(tasks, concurrency);
42
+
43
+ async function runTasksWithConcurrency(items, limit) {
44
+ let nextIndex = 0;
45
+ const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
46
+ while (true) {
47
+ const index = nextIndex;
48
+ nextIndex += 1;
49
+ if (index >= items.length) return;
50
+ await buildComponent(items[index]);
51
+ }
52
+ });
53
+ await Promise.all(workers);
54
+ }
26
55
 
27
- console.log(`Building ${componentPath} (standalone)`);
28
- run("npm", ["run", "build"], join(root, componentPath));
29
- await bundleCli(componentPath);
56
+ async function buildComponent(task) {
57
+ await runCaptured(task.buildCommand, task.buildArgs, task.buildCwd, `Building ${task.componentPath}`);
58
+ await bundleCli(task.componentPath);
30
59
  }
31
60
 
32
61
  async function readStandaloneComponentNames() {
@@ -51,19 +80,36 @@ async function hasBuildScript(relativePath) {
51
80
  async function bundleCli(workspace) {
52
81
  const entry = join(root, workspace, "src", "cli.ts");
53
82
  const output = join(root, workspace, "dist", "cli.js");
54
- console.log(`Bundling ${workspace}/dist/cli.js`);
55
- run("bun", ["build", entry, "--target", "node", "--format", "esm", "--outfile", output], root);
83
+ await runCaptured("bun", ["build", entry, "--target", "node", "--format", "esm", "--outfile", output], root, `Bundling ${workspace}/dist/cli.js`);
56
84
  await normalizeBuiltinImports(output);
57
85
  }
58
86
 
59
- function run(command, args, cwd) {
60
- const result = spawnSync(command, args, {
61
- cwd,
62
- shell: process.platform === "win32",
63
- stdio: "inherit",
87
+ // Buffers each child's stdout/stderr and flushes it as one contiguous block so
88
+ // concurrent builds never interleave, keeping a failing component's output readable.
89
+ function runCaptured(command, args, cwd, label) {
90
+ return new Promise((resolve, reject) => {
91
+ const child = spawn(command, args, {
92
+ cwd,
93
+ shell: process.platform === "win32",
94
+ stdio: ["ignore", "pipe", "pipe"],
95
+ });
96
+ const chunks = [];
97
+ child.stdout.on("data", (chunk) => chunks.push(chunk));
98
+ child.stderr.on("data", (chunk) => chunks.push(chunk));
99
+ child.on("error", (error) => reject(error));
100
+ child.on("close", (status, signal) => {
101
+ const output = Buffer.concat(chunks).toString("utf8");
102
+ process.stdout.write(`${label}\n${output}`);
103
+ if (status === 0) {
104
+ resolve();
105
+ return;
106
+ }
107
+ const reason = signal ? `signal ${signal}` : `exit code ${status}`;
108
+ const error = new Error(`${label} failed with ${reason}`);
109
+ error.exitCode = status ?? 1;
110
+ reject(error);
111
+ });
64
112
  });
65
- if (result.error !== undefined) throw result.error;
66
- if (result.status !== 0) process.exit(result.status ?? 1);
67
113
  }
68
114
 
69
115
  async function normalizeBuiltinImports(output) {
@@ -36,7 +36,14 @@ export async function materializeSharedUpstreams({ strict }) {
36
36
  }
37
37
 
38
38
  if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
39
- const strict = process.env.OMO_MATERIALIZE_STRICT === "1" || process.argv.includes("--strict");
40
- const result = await materializeSharedUpstreams({ strict });
41
- if (result.skipped && strict) process.exit(1);
39
+ // The root build materializes once up front and sets this so downstream codex-plugin
40
+ // builds in the same run do not re-run it; concurrent runs would contend on git's
41
+ // submodule index.lock and race writes into packages/shared-skills/skills.
42
+ if (process.env.OMO_SKIP_MATERIALIZE === "1") {
43
+ process.stdout.write("[materialize] skipped (OMO_SKIP_MATERIALIZE=1)\n");
44
+ } else {
45
+ const strict = process.env.OMO_MATERIALIZE_STRICT === "1" || process.argv.includes("--strict");
46
+ const result = await materializeSharedUpstreams({ strict });
47
+ if (result.skipped && strict) process.exit(1);
48
+ }
42
49
  }
@@ -17,8 +17,10 @@ const skillSources = [
17
17
  ["teammode", "components/teammode/skills/teammode"],
18
18
  ["ulw-loop", "components/ulw-loop/skills/ulw-loop"],
19
19
  ["ulw-plan", "components/ultrawork/skills/ulw-plan"],
20
+ ["ultrawork", "components/ultrawork/skills/ultrawork"],
20
21
  ];
21
22
  const componentSkillNames = new Set(skillSources.map(([name]) => name));
23
+ const codexHiddenSharedSkillNames = new Set(["ultraresearch"]);
22
24
  const skillDisplayPrefix = "(OmO) ";
23
25
 
24
26
  function shouldCopySkillSource(source) {
@@ -164,6 +166,22 @@ prefixes when identity is needed.
164
166
  `;
165
167
 
166
168
  function applyCodexSkillOverlays(skillName, content) {
169
+ if (skillName === "ulw-research") {
170
+ return content
171
+ .replace(
172
+ ", the legacy alias 'ultraresearch', any 'ulw' research wording,",
173
+ ", any 'ulw' research wording,",
174
+ )
175
+ .replace(
176
+ 'the legacy alias "ultraresearch" (also `/ultraresearch`, `$ultraresearch`), ',
177
+ "",
178
+ )
179
+ .replace(
180
+ "answer those normally, and mention that `ulw-research` is available (legacy alias: `ultraresearch`) when a question would clearly benefit from it.",
181
+ "answer those normally, and mention that `ulw-research` is available when a question would clearly benefit from it.",
182
+ )
183
+ .replace("# Ultraresearch Synthesis: <query>", "# ULW-Research Synthesis: <query>");
184
+ }
167
185
  if (skillName === "start-work") {
168
186
  return content
169
187
  .replace(startWorkOriginalCompletion, startWorkCodexCompletion)
@@ -236,6 +254,7 @@ async function syncSkills() {
236
254
 
237
255
  for (const skillName of sharedSkillNames) {
238
256
  if (componentSkillNames.has(skillName)) continue;
257
+ if (codexHiddenSharedSkillNames.has(skillName)) continue;
239
258
  await cp(join(sharedSkillsRoot, skillName), join(skillsRoot, skillName), {
240
259
  filter: shouldCopySkillSource,
241
260
  recursive: true,
@@ -67,6 +67,24 @@ describe("getCodexOmoConfig", () => {
67
67
  expect(result.trustedCodegraphInstallDir).toBe("/global-codegraph")
68
68
  })
69
69
 
70
+ it("#given codex SOT sets CodeGraph excluded roots #when loading config #then roots are returned to hooks", () => {
71
+ // given
72
+ const homeDir = createTemporaryDirectory("omo-codex-shared-excluded-home-")
73
+ const cwd = createTemporaryDirectory("omo-codex-shared-excluded-project-")
74
+ writeOmoConfig(
75
+ homeDir,
76
+ JSON.stringify({
77
+ "[codex]": { codegraph: { excluded_roots: ["/tmp/omo-research", "/private/tmp/omo-research"] } },
78
+ }),
79
+ )
80
+
81
+ // when
82
+ const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
83
+
84
+ // then
85
+ expect(result.codegraph?.excluded_roots).toEqual(["/tmp/omo-research", "/private/tmp/omo-research"])
86
+ })
87
+
70
88
  it("#given legacy env override and SOT value #when loading config #then env wins over the SOT", () => {
71
89
  // given
72
90
  const homeDir = createTemporaryDirectory("omo-codex-shared-env-")
@@ -98,6 +98,12 @@ Run the full test suite for the affected package (not just the one new test). Ex
98
98
 
99
99
  If they don't, your "fix" broke something else. Back to Phase 6 with the new failure as evidence — usually it means the mechanism you thought you fixed was load-bearing for some other code path you didn't know about, and the "broken" test is actually pointing at a better understanding of the system.
100
100
 
101
+ ### 5. Close the observability gap
102
+
103
+ If diagnosis burned extra rounds *because state was invisible* — no log line told you which branch ran, what the value was, whether the fallback engaged — that invisibility is a defect adjacent to the bug, and this is the one moment where adding a log line is NOT "just in case": this session is the evidence that the line earns its place. Ship the fix WITH that line, written to the standard of the `programming` skill's `references/logging.md` — level chosen by consumer, placed at the decision point, data in fields not interpolation, through the project's designated logger. If the project deliberately does not log, respect that and skip this step.
104
+
105
+ This does not soften the artifact rule: every temporary `print` / `dbg!` / `console.log` planted *during* diagnosis stays journaled and gets scrubbed in Phase 9. The triage is the consumer test — a line whose ongoing consumer you can name is part of the fix; a line that only served today's session is an artifact.
106
+
101
107
  ### Update the journal
102
108
 
103
109
  ```markdown
@@ -68,12 +68,15 @@ The taste-skill files and image-generation skills under `frontend/references/des
68
68
  `imagegen-brandkit.md`) are path-mapped copies of the per-skill `SKILL.md` files from the
69
69
  taste-skill project (each `skills/<name>/SKILL.md` is renamed to
70
70
  `references/design/<name>.md`; `imagegen-brandkit.md` maps from `skills/brandkit/SKILL.md`).
71
+ `stitch-design-example.md` is a path-mapped verbatim copy of `skills/stitch-skill/DESIGN.md`,
72
+ the worked example of the design-system document that the stitch skill exports.
71
73
  They are not committed here; the build materializes them from the pinned submodule under
72
74
  `packages/shared-skills/upstreams/taste-skill`. Only the allowed frontmatter description
73
75
  quoting normalization described above may alter these materialized `SKILL.md` files.
74
76
 
75
77
  - Source: https://github.com/Leonxlnx/taste-skill
76
- - Pinned upstream commit: 06d6028b5c623016c59ce8536f578e5a1127b499
78
+ - Official site: https://www.tasteskill.dev/
79
+ - Pinned upstream commit: b17742737e796305d829b3ad39eda3add0d79060
77
80
 
78
81
  ```
79
82
  MIT License
@@ -150,10 +153,11 @@ path-mapped from the designpowers project. It is not committed here; the build
150
153
  materializes the selected files from the pinned submodule under
151
154
  `packages/shared-skills/upstreams/designpowers`. The materialized set includes the
152
155
  upstream `LICENSE`, ten `agents/*.md` role-reference files, and selected
153
- `skills/*/SKILL.md` files. Bridge/state/router integration skills are intentionally
156
+ `skills/*/SKILL.md` files renamed to `vendor/skills/*/reference.md` so they remain
157
+ reference documents instead of nested skill entrypoints. Bridge/state/router integration skills are intentionally
154
158
  excluded; see `frontend/references/designpowers/UPSTREAM.md` for the allowlist and
155
159
  exclusion list. Only the allowed frontmatter description quoting normalization described
156
- above may alter these materialized `SKILL.md` files.
160
+ above may alter these materialized `reference.md` files.
157
161
 
158
162
  - Source: https://github.com/Owl-Listener/designpowers
159
163
  - Pinned upstream commit: cb00757da9d554591fa78d27aa1854d60a05c4f7
@@ -200,6 +204,12 @@ capture evidence and a local reconnaissance run following the MIT-licensed
200
204
  template. Aside names, trademarks, product text, and visual assets remain the property of
201
205
  their respective owners and are referenced only for descriptive design-analysis purposes.
202
206
 
207
+ `frontend/references/design/lazyweb.md` is a project-original, curl-only operating guide
208
+ for the Lazyweb (lazyweb.com) design-research API, written from live endpoint verification;
209
+ no Lazyweb source, documentation text, or screenshot content is vendored. Lazyweb names
210
+ remain the property of their owner, and the guide grants no license to ship, trace, or
211
+ commit reference screenshots harvested through it.
212
+
203
213
  `frontend/references/design/clone-from-url.md` is a project-original runtime-extraction
204
214
  workflow guide. Its browser + `getComputedStyle` clone approach follows the same
205
215
  MIT-licensed `JCodesMore/ai-website-cloner-template` clone-website workflow that `aside.md`
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: frontend
3
- description: "MUST USE for frontend/web UI/UX/visual work: building, styling, redesigning pages/components, React setup, performance audits, visual QA, taste, and polish. Routes four rulesets: design taste router and brand references; perfection for Playwright/Chromium Lighthouse/Core Web Vitals; ui-ux-db palettes/fonts/guidelines; designpowers personas/accessibility/critique/handoff. Triggers: frontend, UI, UX, design, redesign, styling, layout, animation, motion, premium, luxury, minimal, brutalist, Awwwards, DESIGN.md, mockup, React, Lighthouse, accessibility, WCAG, Core Web Vitals, looks generic, make it pretty, like X brand."
3
+ description: "MUST USE for frontend/web UI/UX/visual work: building, styling, redesigning pages/components, React setup, performance audits, visual QA, taste, and polish. Routes four rulesets: design taste router and brand references; perfection for Playwright/Chromium Lighthouse/Core Web Vitals; ui-ux-db palettes/fonts/guidelines; designpowers personas/accessibility/critique/handoff; plus curl-only lazyweb real-app-screen research for design direction. Triggers: frontend, UI, UX, design, redesign, styling, layout, animation, motion, premium, luxury, minimal, brutalist, Awwwards, DESIGN.md, mockup, React, Lighthouse, accessibility, WCAG, Core Web Vitals, looks generic, make it pretty, like X brand, lazyweb, design research."
4
4
  ---
5
5
 
6
6
  # Frontend
@@ -28,7 +28,11 @@ Every implementation must choose one of these branches before UI code changes:
28
28
  - **Static visual reference** (screenshot, generated mockup, Stitch/Imagen output, Figma export, overview, or annotated packet): load `references/design/image-to-code-skill.md` plus the relevant design/perfection files, extract the reference's exact tokens, layout geometry, copy, spacing, states, and responsive intent into `DESIGN.md`, then implement reusable primitives against that contract.
29
29
  - **Live site or URL reference** (the user names a site to clone or gives a URL): load `references/design/clone-from-url.md`. Drive a real browser and extract the runtime truth via `getComputedStyle` — tokens, layout geometry, default/hover/focus/active states, transitions and keyframes, and downloaded assets — into `DESIGN.md`, then clone-code reusable primitives against that contract.
30
30
  Final QA for both runs `/visual-qa` in reference-fidelity mode: compare the actual UI against the reference pixel-by-pixel and verify the code is an extensible design-system implementation, not a screenshot-matched one-off.
31
- 2. **Greenfield or fresh setup:** if the user gave no concrete visual reference, use `references/design/_INDEX.md` to shortlist 2-3 plausible Layer B references, then deeply load exactly one Layer A style skill and one Layer B brand/design-system reference; use `open-design` only when the curated set has no fit. Treat those references as source material, not mood labels: extract tokens, layout grammar, component anatomy, interaction states, motion, and taste decisions into `DESIGN.md`, then recombine them into project-specific primitives never freestyle past the selected references, never copy logos or brand-specific copy. For an expressive brief (glossy, premium, wow, brand-grade), default to generating 2-3 imagen concept drafts, each seeded with the loaded Layer A + Layer B tokens (palette, type, material); pick the strongest and treat the chosen draft as the reference-fidelity contract. Define Section 5 primitives and their default/hover/active/focus/disabled/loading/empty/error states before code, and pass each through mobile/tablet/desktop visual QA before product screens.
31
+ 2. **Greenfield or fresh setup:** if the user gave no concrete visual reference, design direction is a research deliverable, not a vibe. Fire every available research lane IN PARALLEL before `DESIGN.md` is written; skip a lane only when its tool or network is genuinely unavailable, and name the skip in `DESIGN.md`:
32
+ - **Embedded references:** use `references/design/_INDEX.md` to shortlist 2-3 plausible Layer B references, then deeply load exactly one Layer A style skill and one Layer B brand/design-system reference; use `open-design` only when the curated set has no fit; add `ui-ux-db` lookups for palette/type/domain questions.
33
+ - **Lazyweb real-product screens:** run the curl-only recipe in `references/design/lazyweb.md` to see how shipped products in the target domain actually look; harvest layout grammar and component patterns, never pixel copies.
34
+ - **Imagen concept drafts:** generate 2-3 imagen concept drafts, each seeded with the loaded Layer A + Layer B tokens (palette, type, material); pick the strongest and treat the chosen draft as the reference-fidelity contract.
35
+ Synthesize every lane into `DESIGN.md`. Treat sources as source material, not mood labels: extract tokens, layout grammar, component anatomy, interaction states, motion, and taste decisions, then recombine them into project-specific primitives. Never freestyle past the selected references, never copy logos or brand-specific copy. Define Section 5 primitives and their default/hover/active/focus/disabled/loading/empty/error states before code, and pass each through mobile/tablet/desktop visual QA before product screens.
32
36
  3. **Existing project with `DESIGN.md` or a component system:** read it, follow it, and update it before implementation only when the requested work needs a new token, primitive, state, motion rule, accessibility constraint, accepted debt, or reference-fidelity requirement.
33
37
  4. **Existing project with UI but no `DESIGN.md` and no reusable component layer:** STOP and ask the user one focused question: should you preserve the current look with copy-nearby styling, or extract a real `DESIGN.md` plus reusable components before continuing? Do not silently choose.
34
38
 
@@ -56,7 +60,7 @@ The reference library has one architecture file, 12 taste skills (Layer A — *h
56
60
  | `redesign-skill.md` | Improving EXISTING UI — "this looks bad", "fix the design". Audit-first workflow; never use on greenfield. |
57
61
  | `image-to-code-skill.md` | "Generate the design first, then code it." Pair with one imagegen file below. |
58
62
  | `output-skill.md` | Stacks on any style skill when output is incomplete — placeholders, `// TODO`, half-done components. |
59
- | `stitch-skill.md` | Stacks on any style skill for Google Stitch compatibility or a `DESIGN.md` doc export. |
63
+ | `stitch-skill.md` | Stacks on any style skill for Google Stitch compatibility or a `DESIGN.md` doc export. A complete worked export ships as `stitch-design-example.md`. |
60
64
  | `imagegen-frontend-web.md` / `imagegen-frontend-mobile.md` / `imagegen-brandkit.md` | Image-only output (mockup, app-screen concepts, brand board). These NEVER write code — switch to `image-to-code-skill.md` if code is wanted. |
61
65
 
62
66
  ### Layer B — brand design systems (orthogonal to Layer A; stack freely)
@@ -113,6 +117,7 @@ Domains: `product` `style` `typography` `color` `landing` `chart` `ux` `react` `
113
117
  | "Audit my site" / "make this page faster" | `perfection/README.md` (+ `perfection/react-perf-tooling.md` if React) |
114
118
  | "Mockup image of a fintech app" — no code | `design/imagegen-frontend-mobile.md` (+ a Layer B brand if named) |
115
119
  | "What palette/fonts fit a wellness brand?" | `ui-ux-db/README.md` → search CLI |
120
+ | "What do shipped apps in this space look like?" / design-direction research | `design/lazyweb.md` (curl-only) + `design/_INDEX.md` shortlist |
116
121
  | "Set up this React project" | `design/README.md` + `design/react-dev-tooling-skill.md` |
117
122
  | "Use designpowers", "make the design workflow stronger", "add personas/accessibility/debt/handoff" | `design/README.md` + `designpowers/README.md` (+ `perfection/README.md` if implementation or audit follows) |
118
123
 
@@ -157,7 +157,7 @@ Triggers: "generate a mockup image", "create a brand kit board", "design referen
157
157
 
158
158
  Triggers: "Google Stitch", "compatible with Stitch", "also write a DESIGN.md", "give me the design as a doc".
159
159
 
160
- **Action:** Add `stitch-skill.md` on top of whatever you loaded in Steps 1–4.
160
+ **Action:** Add `stitch-skill.md` on top of whatever you loaded in Steps 1–4. For the shape of a finished export, see the worked example in `stitch-design-example.md`.
161
161
 
162
162
  ### Step 7 — The agent has been lazy
163
163