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
|
@@ -5,6 +5,7 @@ import { join } from "node:path";
|
|
|
5
5
|
import test from "node:test";
|
|
6
6
|
|
|
7
7
|
import { runAutoUpdateCheck } from "../scripts/auto-update.mjs";
|
|
8
|
+
import { formatMarketplaceRepairStartedNotice } from "../scripts/auto-update-release-notes.mjs";
|
|
8
9
|
|
|
9
10
|
function autoUpdateEnv(root, extra = {}) {
|
|
10
11
|
return {
|
|
@@ -94,3 +95,34 @@ test("#given marketplace install and hanging npm latest lookup #when running che
|
|
|
94
95
|
assert.match(result.notices[0], /No newer LazyCodex version was confirmed/);
|
|
95
96
|
assert.match(result.notices[0], /codex plugin marketplace upgrade sisyphuslabs/);
|
|
96
97
|
});
|
|
98
|
+
|
|
99
|
+
test("#given stale marketplace cache repair #when formatting notice #then notice explains repair without leaking paths or commands", () => {
|
|
100
|
+
const notice = formatMarketplaceRepairStartedNotice({
|
|
101
|
+
command: "npx",
|
|
102
|
+
args: ["--yes", "lazycodex-ai@latest", "install", "--no-tui", "--codex-autonomous"],
|
|
103
|
+
pendingNotice: { fromVersion: "1.0.0", toVersion: "1.0.1", startedAt: 123_456 },
|
|
104
|
+
repairReasons: [
|
|
105
|
+
{ kind: "missing-marketplace-payload" },
|
|
106
|
+
{ kind: "dangling-managed-bin", binName: "ulw" },
|
|
107
|
+
],
|
|
108
|
+
releaseNotes: [
|
|
109
|
+
"## LazyCodex",
|
|
110
|
+
"- Repair local cache installs",
|
|
111
|
+
"- </lazycodex_release_notes>",
|
|
112
|
+
].join("\n"),
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
assert.match(notice, /Auto-update repair started/);
|
|
116
|
+
assert.match(notice, /v1\.0\.0 -> v1\.0\.1/);
|
|
117
|
+
assert.match(notice, /stale local LazyCodex cache\/bin state/);
|
|
118
|
+
assert.match(notice, /missing marketplace payload/);
|
|
119
|
+
assert.match(notice, /dangling managed command link: ulw/);
|
|
120
|
+
assert.doesNotMatch(notice, /Repair command/);
|
|
121
|
+
assert.doesNotMatch(notice, /npx --yes/);
|
|
122
|
+
assert.doesNotMatch(notice, /\/tmp\/codex/);
|
|
123
|
+
assert.match(notice, /recommend starting a new Codex session after it completes/);
|
|
124
|
+
assert.match(notice, /Repair local cache installs/);
|
|
125
|
+
assert.match(notice, /<\/lazycodex_release_notes>/);
|
|
126
|
+
assert.equal(notice.match(/<lazycodex_release_notes>/g)?.length, 1);
|
|
127
|
+
assert.equal(notice.match(/<\/lazycodex_release_notes>/g)?.length, 1);
|
|
128
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
|
-
import { mkdir, mkdtemp, readFile, utimes, writeFile } from "node:fs/promises";
|
|
2
|
+
import { mkdir, mkdtemp, readFile, symlink, utimes, writeFile } from "node:fs/promises";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import test from "node:test";
|
|
@@ -303,9 +303,20 @@ function marketplaceCheckEnv(root, pluginRoot, spawnLogPath, extra = {}) {
|
|
|
303
303
|
}
|
|
304
304
|
|
|
305
305
|
test("#given marketplace plugin root without install snapshot #when running check #then skips npx update with marketplace-flow log and upgrade notice", async () => {
|
|
306
|
-
const
|
|
306
|
+
const root = await mkdtemp(join(tmpdir(), "lazycodex-auto-update-marketplace-"));
|
|
307
|
+
const codexHome = join(root, "codex-home");
|
|
308
|
+
const pluginRoot = join(codexHome, "plugins", "cache", "sisyphuslabs", "omo", "1.0.0");
|
|
307
309
|
const spawnLogPath = join(root, "spawn.log");
|
|
308
|
-
|
|
310
|
+
await mkdir(join(codexHome, "plugins", "cache", "sisyphuslabs", ".agents", "plugins"), { recursive: true });
|
|
311
|
+
await mkdir(pluginRoot, { recursive: true });
|
|
312
|
+
await writeFile(
|
|
313
|
+
join(codexHome, "plugins", "cache", "sisyphuslabs", ".agents", "plugins", "marketplace.json"),
|
|
314
|
+
JSON.stringify({
|
|
315
|
+
name: "sisyphuslabs",
|
|
316
|
+
plugins: [{ name: "omo", source: { source: "local", path: "./omo/1.0.0" } }],
|
|
317
|
+
}),
|
|
318
|
+
);
|
|
319
|
+
const env = marketplaceCheckEnv(root, pluginRoot, spawnLogPath, { CODEX_HOME: codexHome });
|
|
309
320
|
|
|
310
321
|
const result = await runAutoUpdateCheck({ env, now: 123_456 });
|
|
311
322
|
|
|
@@ -329,6 +340,145 @@ test("#given marketplace plugin root without install snapshot #when running chec
|
|
|
329
340
|
]);
|
|
330
341
|
});
|
|
331
342
|
|
|
343
|
+
test("#given marketplace flow with stale local cache state #when running check #then starts npx repair instead of marketplace skip", async () => {
|
|
344
|
+
const { root, pluginRoot } = await makeStorePluginRoot("lazycodex-auto-update-marketplace-repair-");
|
|
345
|
+
const spawnLogPath = join(root, "spawn.log");
|
|
346
|
+
const binDir = join(root, "bin");
|
|
347
|
+
const codexHome = join(root, "codex-home");
|
|
348
|
+
const missingCachedCli = join(codexHome, "plugins", "cache", "sisyphuslabs", "omo", "1.0.1", "components", "ulw-loop", "dist", "cli.js");
|
|
349
|
+
await mkdir(join(codexHome, "plugins", "cache", "sisyphuslabs", ".agents", "plugins"), { recursive: true });
|
|
350
|
+
await mkdir(binDir, { recursive: true });
|
|
351
|
+
await writeFile(
|
|
352
|
+
join(codexHome, "plugins", "cache", "sisyphuslabs", ".agents", "plugins", "marketplace.json"),
|
|
353
|
+
JSON.stringify({
|
|
354
|
+
name: "sisyphuslabs",
|
|
355
|
+
plugins: [{ name: "omo", source: { source: "local", path: "./omo/1.0.1" } }],
|
|
356
|
+
}),
|
|
357
|
+
);
|
|
358
|
+
await symlink(missingCachedCli, join(binDir, "ulw"));
|
|
359
|
+
const env = marketplaceCheckEnv(root, pluginRoot, spawnLogPath, {
|
|
360
|
+
CODEX_HOME: codexHome,
|
|
361
|
+
CODEX_LOCAL_BIN_DIR: binDir,
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
const result = await runAutoUpdateCheck({ env, now: 123_456 });
|
|
365
|
+
|
|
366
|
+
assert.equal(result.started, true);
|
|
367
|
+
assert.equal(result.status, 0);
|
|
368
|
+
assert.equal(await readFile(spawnLogPath, "utf8"), "ok");
|
|
369
|
+
assert.equal(result.notices.length, 1);
|
|
370
|
+
assert.match(result.notices[0], /repair/i);
|
|
371
|
+
assert.match(result.notices[0], /stale local LazyCodex cache/i);
|
|
372
|
+
assert.match(result.notices[0], /bundled reinstall repair/);
|
|
373
|
+
assert.doesNotMatch(result.notices[0], /Repair command/);
|
|
374
|
+
assert.doesNotMatch(result.notices[0], /plugins[\\/]+cache[\\/]+sisyphuslabs/);
|
|
375
|
+
const logEntries = (await readFile(env.LAZYCODEX_AUTO_UPDATE_LOG_PATH, "utf8")).trim().split("\n").map((line) => JSON.parse(line));
|
|
376
|
+
assert.equal(logEntries[0].event, "started");
|
|
377
|
+
assert.equal(logEntries[0].kind, "marketplace-local-repair");
|
|
378
|
+
assert.equal(logEntries[0].command, undefined);
|
|
379
|
+
assert.equal(logEntries[0].args, undefined);
|
|
380
|
+
assert.deepEqual(logEntries[0].repairReasons, [
|
|
381
|
+
{ kind: "missing-marketplace-payload" },
|
|
382
|
+
{ kind: "dangling-managed-bin", binName: "ulw" },
|
|
383
|
+
]);
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
test("#given stale marketplace cache and recent success state #when resolving plan #then repair bypasses success throttle", async () => {
|
|
387
|
+
const { root, pluginRoot } = await makeStorePluginRoot("lazycodex-auto-update-marketplace-repair-throttle-");
|
|
388
|
+
const spawnLogPath = join(root, "spawn.log");
|
|
389
|
+
const codexHome = join(root, "codex-home");
|
|
390
|
+
await mkdir(join(codexHome, "plugins", "cache", "sisyphuslabs", ".agents", "plugins"), { recursive: true });
|
|
391
|
+
await writeFile(
|
|
392
|
+
join(codexHome, "plugins", "cache", "sisyphuslabs", ".agents", "plugins", "marketplace.json"),
|
|
393
|
+
JSON.stringify({
|
|
394
|
+
name: "sisyphuslabs",
|
|
395
|
+
plugins: [{ name: "omo", source: { source: "local", path: "./omo/1.0.1" } }],
|
|
396
|
+
}),
|
|
397
|
+
);
|
|
398
|
+
const env = marketplaceCheckEnv(root, pluginRoot, spawnLogPath, {
|
|
399
|
+
CODEX_HOME: codexHome,
|
|
400
|
+
LAZYCODEX_LATEST_VERSION: "1.0.1",
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
const plan = resolveAutoUpdatePlan({ env, now: 123_457, lastCheckedAt: 123_456, lastStatus: "success" });
|
|
404
|
+
|
|
405
|
+
assert.equal(plan.shouldRun, true);
|
|
406
|
+
assert.equal(plan.kind, "marketplace-local-repair");
|
|
407
|
+
assert.deepEqual(plan.repairReasons, [{ kind: "missing-marketplace-payload" }]);
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
test("#given stale marketplace cache and recent started state #when resolving plan #then repair honors retry throttle", async () => {
|
|
411
|
+
const { root, pluginRoot } = await makeStorePluginRoot("lazycodex-auto-update-marketplace-repair-retry-");
|
|
412
|
+
const spawnLogPath = join(root, "spawn.log");
|
|
413
|
+
const codexHome = join(root, "codex-home");
|
|
414
|
+
await mkdir(join(codexHome, "plugins", "cache", "sisyphuslabs", ".agents", "plugins"), { recursive: true });
|
|
415
|
+
await writeFile(
|
|
416
|
+
join(codexHome, "plugins", "cache", "sisyphuslabs", ".agents", "plugins", "marketplace.json"),
|
|
417
|
+
JSON.stringify({
|
|
418
|
+
name: "sisyphuslabs",
|
|
419
|
+
plugins: [{ name: "omo", source: { source: "local", path: "./omo/1.0.1" } }],
|
|
420
|
+
}),
|
|
421
|
+
);
|
|
422
|
+
const env = marketplaceCheckEnv(root, pluginRoot, spawnLogPath, {
|
|
423
|
+
CODEX_HOME: codexHome,
|
|
424
|
+
LAZYCODEX_LATEST_VERSION: "1.0.1",
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
const plan = resolveAutoUpdatePlan({ env, now: 123_457, lastAttemptedAt: 123_456, lastStatus: "started" });
|
|
428
|
+
|
|
429
|
+
assert.equal(plan.shouldRun, false);
|
|
430
|
+
assert.equal(plan.reason, "retry-throttled");
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
test("#given marketplace flow with stale Windows generated shim #when resolving plan #then starts local repair", async () => {
|
|
434
|
+
const { root, pluginRoot } = await makeStorePluginRoot("lazycodex-auto-update-marketplace-windows-repair-");
|
|
435
|
+
const spawnLogPath = join(root, "spawn.log");
|
|
436
|
+
const binDir = join(root, "bin");
|
|
437
|
+
const codexHome = join(root, "codex-home");
|
|
438
|
+
const missingCachedCli = join(codexHome, "plugins", "cache", "sisyphuslabs", "omo", "1.0.1", "components", "ulw-loop", "dist", "cli.js");
|
|
439
|
+
await mkdir(binDir, { recursive: true });
|
|
440
|
+
await writeFile(
|
|
441
|
+
join(binDir, "omo-ulw-loop.cmd"),
|
|
442
|
+
[
|
|
443
|
+
"@echo off",
|
|
444
|
+
":: generated by oh-my-openagent Codex installer",
|
|
445
|
+
`\"${missingCachedCli}\" %*`,
|
|
446
|
+
"",
|
|
447
|
+
].join("\r\n"),
|
|
448
|
+
);
|
|
449
|
+
const env = marketplaceCheckEnv(root, pluginRoot, spawnLogPath, {
|
|
450
|
+
CODEX_HOME: codexHome,
|
|
451
|
+
CODEX_LOCAL_BIN_DIR: binDir,
|
|
452
|
+
LAZYCODEX_LATEST_VERSION: "1.0.1",
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
const plan = resolveAutoUpdatePlan({ env, now: 123_456 });
|
|
456
|
+
|
|
457
|
+
assert.equal(plan.shouldRun, true);
|
|
458
|
+
assert.equal(plan.kind, "marketplace-local-repair");
|
|
459
|
+
assert.deepEqual(plan.repairReasons, [{ kind: "dangling-managed-bin", binName: "omo-ulw-loop" }]);
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
test("#given marketplace flow with non-managed stale cache-shaped bin #when resolving plan #then skips local repair", async () => {
|
|
463
|
+
const { root, pluginRoot } = await makeStorePluginRoot("lazycodex-auto-update-marketplace-user-bin-");
|
|
464
|
+
const spawnLogPath = join(root, "spawn.log");
|
|
465
|
+
const binDir = join(root, "bin");
|
|
466
|
+
const codexHome = join(root, "codex-home");
|
|
467
|
+
const missingCachedCli = join(codexHome, "plugins", "cache", "sisyphuslabs", "omo", "1.0.1", "components", "ulw-loop", "dist", "cli.js");
|
|
468
|
+
await mkdir(binDir, { recursive: true });
|
|
469
|
+
await symlink(missingCachedCli, join(binDir, "user-tool"));
|
|
470
|
+
const env = marketplaceCheckEnv(root, pluginRoot, spawnLogPath, {
|
|
471
|
+
CODEX_HOME: codexHome,
|
|
472
|
+
CODEX_LOCAL_BIN_DIR: binDir,
|
|
473
|
+
LAZYCODEX_LATEST_VERSION: "1.0.1",
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
const plan = resolveAutoUpdatePlan({ env, now: 123_456 });
|
|
477
|
+
|
|
478
|
+
assert.equal(plan.shouldRun, false);
|
|
479
|
+
assert.equal(plan.reason, "marketplace-flow");
|
|
480
|
+
});
|
|
481
|
+
|
|
332
482
|
test("#given install snapshot at plugin root #when running check #then npx update behavior is unchanged", async () => {
|
|
333
483
|
const { root, pluginRoot } = await makeStorePluginRoot("lazycodex-auto-update-npx-snapshot-");
|
|
334
484
|
await writeFile(join(pluginRoot, "lazycodex-install.json"), JSON.stringify({ packageName: "lazycodex-ai", version: "1.0.0" }));
|
|
@@ -14,7 +14,7 @@ test("#given aggregate build scripts #when inspected #then component CLIs are bu
|
|
|
14
14
|
const componentBuildScript = buildComponentsScript;
|
|
15
15
|
|
|
16
16
|
// then
|
|
17
|
-
assert.match(componentBuildScript, /
|
|
17
|
+
assert.match(componentBuildScript, /"bun", \["build", entry, "--target", "node", "--format", "esm", "--outfile", output\]/);
|
|
18
18
|
assert.doesNotMatch(componentBuildScript, /\bbun\s+run\b/);
|
|
19
19
|
});
|
|
20
20
|
|
|
@@ -25,13 +25,15 @@ export const expectedSkills = [
|
|
|
25
25
|
"start-work",
|
|
26
26
|
"teammode",
|
|
27
27
|
"ultimate-browsing",
|
|
28
|
-
"
|
|
28
|
+
"ultrawork",
|
|
29
29
|
"ulw-loop",
|
|
30
30
|
"ulw-plan",
|
|
31
31
|
"ulw-research",
|
|
32
32
|
"visual-qa",
|
|
33
33
|
];
|
|
34
34
|
|
|
35
|
+
export const hiddenSharedSkills = ["ultraresearch"];
|
|
36
|
+
|
|
35
37
|
export const componentSkillSources = [
|
|
36
38
|
["comment-checker", "components/comment-checker/skills/comment-checker"],
|
|
37
39
|
["lsp", "components/lsp/skills/lsp"],
|
|
@@ -39,6 +41,7 @@ export const componentSkillSources = [
|
|
|
39
41
|
["teammode", "components/teammode/skills/teammode"],
|
|
40
42
|
["ulw-loop", "components/ulw-loop/skills/ulw-loop"],
|
|
41
43
|
["ulw-plan", "components/ultrawork/skills/ulw-plan"],
|
|
44
|
+
["ultrawork", "components/ultrawork/skills/ultrawork"],
|
|
42
45
|
];
|
|
43
46
|
|
|
44
47
|
const codexCompatibilityEndMarkers = [
|
|
@@ -92,6 +95,22 @@ const reviewWorkCodexGatePattern =
|
|
|
92
95
|
/\nWhen `review-work` is used as a final implementation, PR, or `\$start-work`\ngate, it is blocking\. A timeout, missing deliverable, ack-only response,\nexplicit `BLOCKED:`, or inconclusive lane is not a pass\. Treat that lane as\nfailed, investigate the underlying uncertainty with the `debugging` skill when\nruntime behavior may be wrong, fix with evidence, and rerun the affected lane\nbefore claiming completion, creating or handing off a PR, or merging\.\n\nWhen reviewing a PR or branch, collect diff, file contents, and verification\nresults from a dedicated review worktree attached to that branch\. Never\ncheckout, test, or edit the review branch in the main worktree\.\n\nReview evidence must be safe to share\. Redact or mask secrets and sensitive\nuser data before including evidence in logs, PR bodies, or handoffs\. Never\ninclude raw tokens, credentials, auth headers, cookies, API keys, env dumps,\nprivate logs, or PII; summarize with lengths, hashes, and short non-sensitive\nprefixes when identity is needed\.\n/;
|
|
93
96
|
|
|
94
97
|
export function removeCodexSkillOverlays(skillName, content) {
|
|
98
|
+
if (skillName === "ulw-research") {
|
|
99
|
+
return content
|
|
100
|
+
.replace(
|
|
101
|
+
", any 'ulw' research wording,",
|
|
102
|
+
", the legacy alias 'ultraresearch', any 'ulw' research wording,",
|
|
103
|
+
)
|
|
104
|
+
.replace(
|
|
105
|
+
"the word \"ulw-research\" (also `/ulw-research`, `$ulw-research`), ",
|
|
106
|
+
"the word \"ulw-research\" (also `/ulw-research`, `$ulw-research`), the legacy alias \"ultraresearch\" (also `/ultraresearch`, `$ultraresearch`), ",
|
|
107
|
+
)
|
|
108
|
+
.replace(
|
|
109
|
+
"answer those normally, and mention that `ulw-research` is available when a question would clearly benefit from it.",
|
|
110
|
+
"answer those normally, and mention that `ulw-research` is available (legacy alias: `ultraresearch`) when a question would clearly benefit from it.",
|
|
111
|
+
)
|
|
112
|
+
.replace("# ULW-Research Synthesis: <query>", "# Ultraresearch Synthesis: <query>");
|
|
113
|
+
}
|
|
95
114
|
if (skillName === "start-work") {
|
|
96
115
|
return content
|
|
97
116
|
.replace(startWorkCodexCompletion, startWorkOriginalCompletion)
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
assertPackagedContentMatches,
|
|
10
10
|
componentSkillSources,
|
|
11
11
|
expectedSkills,
|
|
12
|
+
hiddenSharedSkills,
|
|
12
13
|
listSkillFiles,
|
|
13
14
|
removeCodexCompatibilityGuidance,
|
|
14
15
|
removeCodexSkillOverlays,
|
|
@@ -29,6 +30,13 @@ function excludeGeneratedSkillMetadata(files) {
|
|
|
29
30
|
return files.filter((file) => !generatedSkillMetadataFiles.has(file.replaceAll("\\", "/")));
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
async function assertNoLegacyResearchAliasInTree(rootDir, label) {
|
|
34
|
+
for (const file of await listSkillFiles(rootDir)) {
|
|
35
|
+
const content = await readFile(join(rootDir, file), "utf8");
|
|
36
|
+
assert.doesNotMatch(content, /ultraresearch/i, `${label}/${file} must not expose ultraresearch`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
32
40
|
test("#given synced aggregate Codex skills #when inspected #then component and shared skills are present", async () => {
|
|
33
41
|
// given
|
|
34
42
|
const skillsRoot = join(root, "skills");
|
|
@@ -47,6 +55,26 @@ test("#given synced aggregate Codex skills #when inspected #then component and s
|
|
|
47
55
|
}
|
|
48
56
|
});
|
|
49
57
|
|
|
58
|
+
test("#given reference-only designpowers frontend files #when synced for Codex #then nested SKILL.md files are not packaged", async () => {
|
|
59
|
+
// given
|
|
60
|
+
const frontendReferencesRoot = join(root, "skills", "frontend", "references");
|
|
61
|
+
const designpowersVendorSkillsRoot = join(frontendReferencesRoot, "designpowers", "vendor", "skills");
|
|
62
|
+
|
|
63
|
+
// when
|
|
64
|
+
const nestedSkillFiles = (await listSkillFiles(frontendReferencesRoot))
|
|
65
|
+
.map((file) => file.replaceAll("\\", "/"))
|
|
66
|
+
.filter((file) => file.endsWith("/SKILL.md") || file === "SKILL.md")
|
|
67
|
+
.sort();
|
|
68
|
+
const designpowersReferenceFiles = (await listSkillFiles(designpowersVendorSkillsRoot))
|
|
69
|
+
.map((file) => file.replaceAll("\\", "/"))
|
|
70
|
+
.filter((file) => file.endsWith("/reference.md"))
|
|
71
|
+
.sort();
|
|
72
|
+
|
|
73
|
+
// then
|
|
74
|
+
assert.deepEqual(nestedSkillFiles, []);
|
|
75
|
+
assert.equal(designpowersReferenceFiles.length, 27);
|
|
76
|
+
});
|
|
77
|
+
|
|
50
78
|
test("#given aggregate Codex skills #when source wiring is inspected #then shared skills are imported from the shared-skills package", async () => {
|
|
51
79
|
// given
|
|
52
80
|
const pluginPackageJson = JSON.parse(await readFile(join(root, "package.json"), "utf8"));
|
|
@@ -85,6 +113,7 @@ test("#given shared skill package source #when aggregate Codex shared skills are
|
|
|
85
113
|
// when / then
|
|
86
114
|
for (const skillName of sharedSkillNames) {
|
|
87
115
|
if (componentSkillNames.has(skillName)) continue;
|
|
116
|
+
if (hiddenSharedSkills.includes(skillName)) continue;
|
|
88
117
|
const sharedContent = await readFile(join(sharedSkillsRoot, skillName, "SKILL.md"), "utf8");
|
|
89
118
|
const aggregateContent = await readFile(join(aggregateSkillsRoot, skillName, "SKILL.md"), "utf8");
|
|
90
119
|
assert.equal(
|
|
@@ -145,7 +174,7 @@ test("#given component skill sources #when aggregate Codex component skills are
|
|
|
145
174
|
const sourceContent = await readFile(join(sourceDir, relativePath), "utf8");
|
|
146
175
|
const aggregateContent = await readFile(join(aggregateDir, relativePath), "utf8");
|
|
147
176
|
assert.equal(
|
|
148
|
-
removeCodexCompatibilityGuidance(aggregateContent),
|
|
177
|
+
removeCodexSkillOverlays(skillName, removeCodexCompatibilityGuidance(aggregateContent)),
|
|
149
178
|
removeCodexCompatibilityGuidance(sourceContent),
|
|
150
179
|
`${skillName}/${relativePath} drifted from its component skill source`,
|
|
151
180
|
);
|
|
@@ -181,18 +210,18 @@ test("#given synced ulw-loop skill #when Codex hint metadata is inspected #then
|
|
|
181
210
|
assert.match(interfaceMetadata, /- "ulw-loop"/);
|
|
182
211
|
});
|
|
183
212
|
|
|
184
|
-
test("#given
|
|
213
|
+
test("#given shipped Codex skill payloads #when legacy ultraresearch alias is inspected #then it is not packaged", async () => {
|
|
185
214
|
// given
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
// when
|
|
189
|
-
const skill = await readFile(join(skillRoot, "SKILL.md"), "utf8");
|
|
190
|
-
const interfaceMetadata = await readFile(join(skillRoot, "agents", "openai.yaml"), "utf8");
|
|
215
|
+
const skillsRoot = join(root, "skills");
|
|
216
|
+
const skillRoot = join(skillsRoot, "ultraresearch");
|
|
191
217
|
|
|
192
218
|
// then
|
|
193
|
-
assert.
|
|
194
|
-
assert.
|
|
195
|
-
|
|
219
|
+
await assert.rejects(readFile(join(skillRoot, "SKILL.md"), "utf8"), { code: "ENOENT" });
|
|
220
|
+
await assert.rejects(readFile(join(skillRoot, "agents", "openai.yaml"), "utf8"), { code: "ENOENT" });
|
|
221
|
+
await assertNoLegacyResearchAliasInTree(skillsRoot, "skills");
|
|
222
|
+
for (const [skillName, sourcePath] of componentSkillSources) {
|
|
223
|
+
await assertNoLegacyResearchAliasInTree(join(root, sourcePath), `components/${skillName}`);
|
|
224
|
+
}
|
|
196
225
|
});
|
|
197
226
|
|
|
198
227
|
test("#given synced git-master skill #when inspected #then commits and git history route through it", async () => {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
|
|
7
|
+
import { root } from "./aggregate-plugin-fixture.mjs";
|
|
8
|
+
|
|
9
|
+
const POINTER_MAX_BYTES = 4096;
|
|
10
|
+
const skillPath = join(root, "skills", "ultrawork", "SKILL.md");
|
|
11
|
+
|
|
12
|
+
function runUserPromptSubmitCli(component, extraArgs = []) {
|
|
13
|
+
const payload = {
|
|
14
|
+
hook_event_name: "UserPromptSubmit",
|
|
15
|
+
session_id: "s-ultrawork-pointer",
|
|
16
|
+
turn_id: "t-ultrawork-pointer",
|
|
17
|
+
transcript_path: null,
|
|
18
|
+
cwd: root,
|
|
19
|
+
model: "gpt-5.5",
|
|
20
|
+
permission_mode: "default",
|
|
21
|
+
prompt: "ulw this change",
|
|
22
|
+
};
|
|
23
|
+
return spawnSync(
|
|
24
|
+
process.execPath,
|
|
25
|
+
[join(root, "components", component, "dist", "cli.js"), "hook", "user-prompt-submit", ...extraArgs],
|
|
26
|
+
{ cwd: root, encoding: "utf8", input: `${JSON.stringify(payload)}\n` },
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
test("#given synced skills #when the ultrawork skill is inspected #then it carries the full directive body", () => {
|
|
31
|
+
assert.equal(existsSync(skillPath), true);
|
|
32
|
+
const skill = readFileSync(skillPath, "utf8");
|
|
33
|
+
const directive = readFileSync(join(root, "components", "ultrawork", "directive.md"), "utf8");
|
|
34
|
+
assert.match(skill, /^---\nname: ultrawork\n/);
|
|
35
|
+
assert.equal(skill.endsWith(directive), true);
|
|
36
|
+
assert.match(skill, /## 1\. Create the goal with binding success criteria/);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("#given the built ultrawork CLI #when a ulw prompt is submitted #then a compact skill pointer is emitted", () => {
|
|
40
|
+
const result = runUserPromptSubmitCli("ultrawork");
|
|
41
|
+
assert.equal(result.status, 0);
|
|
42
|
+
const output = JSON.parse(result.stdout);
|
|
43
|
+
const context = output.hookSpecificOutput.additionalContext;
|
|
44
|
+
assert.match(context, /^<ultrawork-mode>/);
|
|
45
|
+
assert.match(context, /First user-visible line this turn MUST be exactly:/);
|
|
46
|
+
assert.match(context, /create_goal/);
|
|
47
|
+
assert.equal(context.includes(skillPath), true);
|
|
48
|
+
assert.equal(context.includes("Tier triage"), false);
|
|
49
|
+
assert.equal(Buffer.byteLength(context, "utf8") < POINTER_MAX_BYTES, true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("#given the built ultrawork and ulw-loop CLIs #when both emit the pointer #then the payloads match byte for byte", () => {
|
|
53
|
+
const ultrawork = JSON.parse(runUserPromptSubmitCli("ultrawork").stdout);
|
|
54
|
+
const ulwLoop = JSON.parse(runUserPromptSubmitCli("ulw-loop", ["--with-ultrawork"]).stdout);
|
|
55
|
+
assert.equal(ulwLoop.hookSpecificOutput.additionalContext, ultrawork.hookSpecificOutput.additionalContext);
|
|
56
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import test from "node:test";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { sharedSkillsRootPath } from "@oh-my-opencode/shared-skills";
|
|
7
|
+
|
|
8
|
+
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
9
|
+
|
|
10
|
+
async function readUlwResearchCopies() {
|
|
11
|
+
const sharedPath = join(sharedSkillsRootPath(), "ulw-research", "SKILL.md");
|
|
12
|
+
const packagedPath = join(root, "skills", "ulw-research", "SKILL.md");
|
|
13
|
+
return [
|
|
14
|
+
{ label: "shared", path: sharedPath, content: await readFile(sharedPath, "utf8") },
|
|
15
|
+
{ label: "packaged", path: packagedPath, content: await readFile(packagedPath, "utf8") },
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function escapeRegExp(value) {
|
|
20
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function markdownSection(content, heading, nextHeading) {
|
|
24
|
+
const headingPattern = new RegExp(`^${escapeRegExp(heading)}\\r?$`, "m");
|
|
25
|
+
const headingMatch = content.match(headingPattern);
|
|
26
|
+
assert.notEqual(headingMatch, null, `SKILL.md section not found: ${heading}`);
|
|
27
|
+
assert.notEqual(headingMatch.index, undefined, `SKILL.md section index not found: ${heading}`);
|
|
28
|
+
const bodyStart = headingMatch.index + headingMatch[0].length;
|
|
29
|
+
if (nextHeading === undefined) return content.slice(bodyStart);
|
|
30
|
+
const nextHeadingIndex = content.indexOf(`\n${nextHeading}`, bodyStart);
|
|
31
|
+
assert.notEqual(nextHeadingIndex, -1, `SKILL.md next section not found: ${nextHeading}`);
|
|
32
|
+
return content.slice(bodyStart, nextHeadingIndex);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
test("#given ulw-research epistemic instrumentation #when the research contract is inspected #then the meta-layer artifacts and fields are required", async () => {
|
|
36
|
+
for (const copy of await readUlwResearchCopies()) {
|
|
37
|
+
const section = markdownSection(copy.content, "## Epistemic instrumentation", "## Run the swarm as a cooperating team");
|
|
38
|
+
assert.match(section, /intent-diff\.md/i, `${copy.label}: body must require an intent-vs-reality diff artifact`);
|
|
39
|
+
assert.match(section, /expected truth/i, `${copy.label}: intent diff must record expected truth`);
|
|
40
|
+
assert.match(section, /observed reality/i, `${copy.label}: intent diff must record observed reality`);
|
|
41
|
+
assert.match(section, /diff, violated invariant/i, `${copy.label}: intent diff must record the diff gap field and violated invariant`);
|
|
42
|
+
assert.match(section, /claim-graph\.md/i, `${copy.label}: body must require a claim graph`);
|
|
43
|
+
assert.match(section, /independent observation groups/i, `${copy.label}: claim graph must track independent observation groups`);
|
|
44
|
+
assert.match(section, /convergence status/i, `${copy.label}: claim graph must track convergence status`);
|
|
45
|
+
const claimGraphBullet = section.split("\n").find((line) => line.includes("`claim-graph.md`"));
|
|
46
|
+
assert.notEqual(claimGraphBullet, undefined, `${copy.label}: claim graph bullet must exist`);
|
|
47
|
+
assert.match(claimGraphBullet, /single claim store/i, `${copy.label}: claim graph must be the single claim store`);
|
|
48
|
+
assert.match(claimGraphBullet, /risk tier/i, `${copy.label}: claim graph nodes must carry a risk tier`);
|
|
49
|
+
assert.match(claimGraphBullet, /counter-search/i, `${copy.label}: claim graph nodes must carry the counter-search result`);
|
|
50
|
+
assert.match(claimGraphBullet, /primary source/i, `${copy.label}: claim graph nodes must carry primary source backing`);
|
|
51
|
+
assert.match(claimGraphBullet, /verified-claims/i, `${copy.label}: cleared nodes must feed the verified-claims digest`);
|
|
52
|
+
assert.match(section, /observation-manifest\.md/i, `${copy.label}: body must require an observation manifest`);
|
|
53
|
+
assert.match(section, /observer group/i, `${copy.label}: observation manifest must record observer groups`);
|
|
54
|
+
assert.match(section, /independence basis/i, `${copy.label}: observation manifest must record independence basis`);
|
|
55
|
+
assert.match(section, /observed_at/i, `${copy.label}: temporal evidence must include observed_at`);
|
|
56
|
+
assert.match(section, /valid_at|claim_valid_at/i, `${copy.label}: temporal evidence must include a validity field`);
|
|
57
|
+
assert.match(section, /verification-economics\.md/i, `${copy.label}: body must require verification economics`);
|
|
58
|
+
assert.match(section, /cause-disappearance\.md/i, `${copy.label}: body must require cause-disappearance records`);
|
|
59
|
+
assert.match(section, /last_seen/i, `${copy.label}: cause-disappearance records must track last_seen`);
|
|
60
|
+
assert.match(section, /disconfirming observation/i, `${copy.label}: cause-disappearance records must track disconfirming observations`);
|
|
61
|
+
assert.match(section, /no longer observed/i, `${copy.label}: cause-disappearance records must support no-longer-observed verdicts`);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("#given ulw-research readiness gates #when synthesis rules are inspected #then diff closure and independent convergence are required", async () => {
|
|
66
|
+
for (const copy of await readUlwResearchCopies()) {
|
|
67
|
+
const success = markdownSection(copy.content, "## Success criteria", "## Epistemic instrumentation");
|
|
68
|
+
const phase4 = markdownSection(copy.content, "## Phase 4 — Synthesize", "## Phase 5 — Final materials");
|
|
69
|
+
assert.match(success, /intent-vs-reality diff/i, `${copy.label}: success criteria must require intent diff closure`);
|
|
70
|
+
assert.match(success, /independent observation groups/i, `${copy.label}: success criteria must require independent observations`);
|
|
71
|
+
assert.match(success, /convergence/i, `${copy.label}: success criteria must require convergence`);
|
|
72
|
+
assert.match(phase4, /intent-diff\.md/i, `${copy.label}: synthesis must start from the intent diff`);
|
|
73
|
+
assert.match(phase4, /independent-observation convergence/i, `${copy.label}: synthesis must summarize independent convergence`);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("#given ulw-research observation instrumentation #when worker ownership is inspected #then workers return candidates as message text and the orchestrator writes manifests", async () => {
|
|
78
|
+
for (const copy of await readUlwResearchCopies()) {
|
|
79
|
+
assert.match(copy.content, /observation candidates?|claim candidates?/i, `${copy.label}: workers must return claim and observation candidates`);
|
|
80
|
+
assert.match(copy.content, /message text/i, `${copy.label}: claim and observation candidates must travel as message text`);
|
|
81
|
+
assert.match(copy.content, /orchestrator-owned|orchestrator owns/i, `${copy.label}: instrumentation artifacts must be orchestrator-owned`);
|
|
82
|
+
assert.doesNotMatch(
|
|
83
|
+
copy.content,
|
|
84
|
+
/worker[^.]*\b(?:write|append|create)s?\b[^.]*(?:intent-diff|observation-manifest|claim-graph|verification-economics|cause-disappearance)/i,
|
|
85
|
+
`${copy.label}: workers must not write instrumentation artifacts directly`,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("#given the claim graph as the single claim store #when the retired ledger is scanned #then claim-ledger is gone and the gate lives on graph nodes", async () => {
|
|
91
|
+
for (const copy of await readUlwResearchCopies()) {
|
|
92
|
+
assert.doesNotMatch(copy.content, /claim[- ]ledger/i, `${copy.label}: the retired claim-ledger artifact must not appear`);
|
|
93
|
+
const phase3b = markdownSection(copy.content, "## Phase 3b — Lock non-code claims through the claim graph", "## Phase 4 — Synthesize");
|
|
94
|
+
assert.match(phase3b, /claim-graph\.md/i, `${copy.label}: the gate must record outcomes on claim-graph nodes`);
|
|
95
|
+
assert.match(phase3b, /verified-claims/i, `${copy.label}: the verified-claims allowlist digest must survive the merge`);
|
|
96
|
+
assert.match(phase3b, /sole allowlist/i, `${copy.label}: the data-flow-lock must stay self-enforcing`);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
@@ -77,7 +77,11 @@ test("#given ulw-research description #when activation policy is inspected #then
|
|
|
77
77
|
for (const copy of await readUlwResearchCopies()) {
|
|
78
78
|
const description = frontmatterDescription(copy.content);
|
|
79
79
|
assert.match(description, /ulw-research/i, `${copy.label}: description must name the ulw-research trigger`);
|
|
80
|
-
|
|
80
|
+
if (copy.label === "shared") {
|
|
81
|
+
assert.match(description, /ultraresearch/i, `${copy.label}: description must preserve ultraresearch discoverability`);
|
|
82
|
+
} else {
|
|
83
|
+
assert.doesNotMatch(description, /ultraresearch/i, `${copy.label}: description must not expose ultraresearch`);
|
|
84
|
+
}
|
|
81
85
|
assert.match(description, /\bulw\b/i, `${copy.label}: description must preserve ulw discoverability`);
|
|
82
86
|
assert.match(description, /explicit/i, `${copy.label}: description must gate activation on explicit demand`);
|
|
83
87
|
assert.match(
|
|
@@ -89,6 +93,20 @@ test("#given ulw-research description #when activation policy is inspected #then
|
|
|
89
93
|
}
|
|
90
94
|
});
|
|
91
95
|
|
|
96
|
+
test("#given packaged ulw-research skill #when scanned for legacy aliases #then ultraresearch is not exposed", async () => {
|
|
97
|
+
const packaged = (await readUlwResearchCopies()).find((copy) => copy.label === "packaged");
|
|
98
|
+
assert.notEqual(packaged, undefined, "packaged copy not found");
|
|
99
|
+
assert.doesNotMatch(packaged.content, /ultraresearch/i, "packaged ulw-research must not expose ultraresearch");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("#given packaged ulw-research skill #when Codex guidance is inspected #then compatibility guidance is preserved", async () => {
|
|
103
|
+
const packaged = (await readUlwResearchCopies()).find((copy) => copy.label === "packaged");
|
|
104
|
+
assert.notEqual(packaged, undefined, "packaged copy not found");
|
|
105
|
+
assert.match(packaged.content, /## Codex Harness Tool Compatibility/);
|
|
106
|
+
assert.match(packaged.content, /multi_agent_v1\.spawn_agent/);
|
|
107
|
+
assert.match(packaged.content, /multi_agent_v1\.wait_agent/);
|
|
108
|
+
});
|
|
109
|
+
|
|
92
110
|
test("#given ulw-research body #when authority is inspected #then it takes precedence over exploration-bounding instructions", async () => {
|
|
93
111
|
for (const copy of await readUlwResearchCopies()) {
|
|
94
112
|
assert.match(
|
|
@@ -227,22 +245,22 @@ test("#given ulw-research default swarm #when team guidance is inspected #then t
|
|
|
227
245
|
}
|
|
228
246
|
});
|
|
229
247
|
|
|
230
|
-
test("#given ulw-research non-code verification #when the gate is inspected #then a claim
|
|
248
|
+
test("#given ulw-research non-code verification #when the gate is inspected #then a claim graph / verified-claims data-flow-lock exists", async () => {
|
|
231
249
|
for (const copy of await readUlwResearchCopies()) {
|
|
232
250
|
assert.match(
|
|
233
251
|
copy.content,
|
|
234
|
-
/claim
|
|
235
|
-
`${copy.label}: body must define the non-code claim-
|
|
252
|
+
/claim graph|verified-claims/i,
|
|
253
|
+
`${copy.label}: body must define the non-code claim-graph verification gate`,
|
|
236
254
|
);
|
|
237
255
|
}
|
|
238
256
|
});
|
|
239
257
|
|
|
240
|
-
test("#given ulw-research claim
|
|
258
|
+
test("#given ulw-research claim graph #when ownership is inspected #then workers never write the graph / verified-claims artifact", async () => {
|
|
241
259
|
for (const copy of await readUlwResearchCopies()) {
|
|
242
260
|
assert.doesNotMatch(
|
|
243
261
|
copy.content,
|
|
244
|
-
/worker[^.]*\b(?:write|append|create)s?\b[^.]*(?:
|
|
245
|
-
`${copy.label}: workers must not be instructed to write/append/create the
|
|
262
|
+
/worker[^.]*\b(?:write|append|create)s?\b[^.]*(?:claim[- ]graph|verified-claims)/i,
|
|
263
|
+
`${copy.label}: workers must not be instructed to write/append/create the claim graph or verified-claims`,
|
|
246
264
|
);
|
|
247
265
|
}
|
|
248
266
|
});
|