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.
- package/dist/cli/doctor/checks/tui-plugin-config.d.ts +4 -4
- package/dist/cli/index.js +1149 -1040
- package/dist/cli/install-senpi/index.d.ts +1 -0
- package/dist/cli/run/poll-for-completion.d.ts +4 -0
- package/dist/cli/run/session-resolver.d.ts +1 -0
- package/dist/cli/senpi-platform-flag.d.ts +4 -0
- package/dist/cli/types.d.ts +2 -1
- package/dist/cli-node/index.js +1149 -1040
- package/dist/features/background-agent/manager.d.ts +16 -0
- package/dist/hooks/anthropic-context-window-limit-recovery/aggressive-truncation-strategy.d.ts +1 -0
- package/dist/index.js +1334 -1146
- package/dist/skills/debugging/references/methodology/06-fix.md +6 -0
- package/dist/skills/frontend/ATTRIBUTION.md +13 -3
- package/dist/skills/frontend/SKILL.md +8 -3
- package/dist/skills/frontend/references/design/README.md +1 -1
- package/dist/skills/frontend/references/design/_INDEX.md +1 -1
- package/dist/skills/frontend/references/design/lazyweb.md +77 -0
- package/dist/skills/frontend/references/design/stitch-design-example.md +121 -0
- package/dist/skills/frontend/references/designpowers/EVIDENCE.md +10 -2
- package/dist/skills/frontend/references/designpowers/UPSTREAM.md +1 -1
- package/dist/skills/programming/SKILL.md +10 -1
- package/dist/skills/programming/references/logging.md +91 -0
- package/dist/skills/ulw-plan/SKILL.md +5 -5
- package/dist/skills/ulw-plan/references/full-workflow.md +7 -7
- package/dist/skills/ulw-plan/references/intent-unclear.md +3 -3
- package/dist/skills/ulw-research/ATTRIBUTION.md +2 -2
- package/dist/skills/ulw-research/SKILL.md +28 -7
- package/dist/tools/skill/description-formatter.d.ts +1 -0
- package/dist/tools/skill/description-formatter.test-support.d.ts +9 -0
- package/dist/tools/skill/zauc-mocks-skill-tools/test-support.d.ts +25 -0
- package/dist/tui.js +121 -419
- package/package.json +32 -15
- package/packages/git-bash-mcp/dist/cli.js +2 -2
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/AGENTS.md +55 -0
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +212 -117
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +51 -0
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +936 -248
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +233 -135
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +29 -0
- package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +13 -0
- package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +25 -0
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +3 -1
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +30 -1
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +16 -2
- package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +80 -0
- package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +34 -0
- package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +107 -0
- package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +26 -0
- package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +29 -0
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +8 -21
- package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +108 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +76 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +17 -111
- package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +1 -1
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +45 -67
- package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +56 -0
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +31 -0
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +45 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +37 -102
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/AGENTS.md +46 -0
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +6 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +6 -0
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -2
- package/packages/omo-codex/plugin/components/ultrawork/CHANGELOG.md +2 -0
- package/packages/omo-codex/plugin/components/ultrawork/README.md +3 -3
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +51 -2
- package/packages/omo-codex/plugin/components/ultrawork/package.json +2 -1
- package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +14 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +380 -0
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +5 -2
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +4 -4
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +5 -3
- package/packages/omo-codex/plugin/components/ultrawork/src/skill-pointer.ts +56 -0
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +4 -4
- package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +12 -0
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +1 -0
- package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +82 -0
- package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +56 -5
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +5 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.d.ts +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.js +5 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-skill-pointer.d.ts +7 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-skill-pointer.js +46 -0
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +5 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/ultrawork-directive.ts +9 -3
- package/packages/omo-codex/plugin/components/ulw-loop/src/ultrawork-skill-pointer.ts +55 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +49 -0
- package/packages/omo-codex/plugin/package-lock.json +13 -13
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +147 -2
- package/packages/omo-codex/plugin/scripts/auto-update-release-notes.mjs +33 -0
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +48 -10
- package/packages/omo-codex/plugin/scripts/build-components.mjs +63 -17
- package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +10 -3
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +19 -0
- package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +18 -0
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/06-fix.md +6 -0
- package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +13 -3
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +8 -3
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/references/design/lazyweb.md +77 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/stitch-design-example.md +121 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/EVIDENCE.md +10 -2
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/UPSTREAM.md +1 -1
- package/packages/omo-codex/plugin/skills/programming/SKILL.md +10 -1
- package/packages/omo-codex/plugin/skills/programming/references/logging.md +91 -0
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +380 -0
- package/packages/omo-codex/plugin/skills/ultrawork/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +5 -2
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +4 -4
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +2 -2
- package/packages/omo-codex/plugin/skills/ulw-research/ATTRIBUTION.md +2 -2
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +31 -10
- package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +32 -0
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +153 -3
- package/packages/omo-codex/plugin/test/install-time-build-runtime.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +20 -1
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +39 -10
- package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +56 -0
- package/packages/omo-codex/plugin/test/ulw-research-epistemic-contract.test.mjs +98 -0
- package/packages/omo-codex/plugin/test/ulw-research-skill-contract.test.mjs +25 -7
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +612 -4193
- package/packages/shared-skills/skills/debugging/references/methodology/06-fix.md +6 -0
- package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +13 -3
- package/packages/shared-skills/skills/frontend/SKILL.md +8 -3
- package/packages/shared-skills/skills/frontend/references/design/README.md +1 -1
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -1
- package/packages/shared-skills/skills/frontend/references/design/lazyweb.md +77 -0
- package/packages/shared-skills/skills/frontend/references/design/stitch-design-example.md +121 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/EVIDENCE.md +10 -2
- package/packages/shared-skills/skills/frontend/references/designpowers/UPSTREAM.md +1 -1
- package/packages/shared-skills/skills/programming/SKILL.md +10 -1
- package/packages/shared-skills/skills/programming/references/logging.md +91 -0
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +5 -5
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +7 -7
- package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +3 -3
- package/packages/shared-skills/skills/ulw-research/ATTRIBUTION.md +2 -2
- package/packages/shared-skills/skills/ulw-research/SKILL.md +28 -7
- package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +0 -10
- package/packages/omo-codex/plugin/skills/ultraresearch/agents/openai.yaml +0 -2
- /package/dist/skills/frontend/references/designpowers/vendor/skills/accessible-content/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/design-debate/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/design-handoff/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/design-md/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/design-retrospective/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/design-review/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/interaction-design/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/motion-choreography/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/research-planning/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/taste-feedback/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/taste-report/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/token-architecture/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/ui-composition/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/usability-testing/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/{SKILL.md → reference.md} +0 -0
- /package/dist/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/accessible-content/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-debate/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-handoff/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-md/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-retrospective/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-review/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/interaction-design/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/motion-choreography/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/research-planning/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/taste-feedback/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/taste-report/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/token-architecture/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/ui-composition/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/usability-testing/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/{SKILL.md → reference.md} +0 -0
- /package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/accessible-content/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-debate/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-handoff/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-md/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-retrospective/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-review/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/interaction-design/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/motion-choreography/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/research-planning/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/taste-feedback/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/taste-report/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/token-architecture/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/ui-composition/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/usability-testing/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/{SKILL.md → reference.md} +0 -0
- /package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/{SKILL.md → reference.md} +0 -0
- /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 {
|
|
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 {
|
|
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
|
-
|
|
52
|
-
|
|
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",
|
|
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(
|
|
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 {
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
28
|
-
|
|
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
|
-
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
-
|
|
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
|
|
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 `
|
|
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,
|
|
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
|
|