oh-my-opencode 4.19.1 → 4.19.3
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/.agents/command/publish.md +95 -28
- package/.agents/skills/publish/SKILL.md +20 -6
- package/.opencode/command/publish.md +95 -28
- package/README.ja.md +2 -2
- package/README.ko.md +2 -2
- package/README.md +2 -2
- package/README.ru.md +2 -2
- package/README.zh-cn.md +2 -2
- package/THIRD-PARTY-NOTICES.md +7 -7
- package/dist/agents/atlas/agent.d.ts +4 -2
- package/dist/agents/explore.d.ts +4 -2
- package/dist/agents/hephaestus/agent.d.ts +4 -2
- package/dist/agents/librarian.d.ts +4 -2
- package/dist/agents/metis.d.ts +4 -2
- package/dist/agents/momus.d.ts +3 -2
- package/dist/agents/multimodal-looker.d.ts +4 -2
- package/dist/agents/oracle.d.ts +4 -2
- package/dist/agents/sisyphus/claude-opus-5.d.ts +33 -0
- package/dist/agents/sisyphus/index.d.ts +2 -0
- package/dist/agents/sisyphus-agent-factory.d.ts +5 -2
- package/dist/agents/sisyphus-junior/agent.d.ts +4 -1
- package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +1 -1
- package/dist/agents/types.d.ts +2 -2
- package/dist/cli/config-migrate.d.ts +8 -0
- package/dist/cli/doctor/checks/legacy-config-leftovers.d.ts +10 -0
- package/dist/cli/doctor/checks/model-resolution-config.d.ts +1 -1
- package/dist/cli/doctor/checks/tools-lsp.d.ts +1 -1
- package/dist/cli/doctor/framework/constants.d.ts +1 -1
- package/dist/cli/index.js +95391 -88524
- package/dist/cli-node/index.js +95504 -88637
- package/dist/config/schema/agent-names.d.ts +26 -26
- package/dist/config/schema/agent-overrides.d.ts +400 -400
- package/dist/config/schema/browser-automation.d.ts +2 -2
- package/dist/config/schema/categories.d.ts +36 -36
- package/dist/config/schema/commands.d.ts +2 -2
- package/dist/config/schema/dynamic-context-pruning.d.ts +1 -1
- package/dist/config/schema/experimental.d.ts +1 -1
- package/dist/config/schema/fallback-models.d.ts +25 -25
- package/dist/config/schema/hooks.d.ts +43 -43
- package/dist/config/schema/internal/permission.d.ts +9 -9
- package/dist/config/schema/keyword-detector.d.ts +6 -6
- package/dist/config/schema/oh-my-opencode-config.d.ts +402 -402
- package/dist/config/schema/tmux.d.ts +6 -6
- package/dist/config/validate.d.ts +2 -1
- package/dist/config-migration/deep-diff.d.ts +1 -0
- package/dist/config-migration/discovery-paths.d.ts +11 -0
- package/dist/config-migration/discovery-roots.d.ts +7 -0
- package/dist/config-migration/discovery.d.ts +4 -0
- package/dist/config-migration/index.d.ts +9 -0
- package/dist/config-migration/legacy-history.d.ts +3 -0
- package/dist/config-migration/migration-executor.d.ts +4 -0
- package/dist/config-migration/migration-plans.d.ts +14 -0
- package/dist/config-migration/record-values.d.ts +4 -0
- package/dist/config-migration/schema-url.d.ts +1 -0
- package/dist/config-migration/transform-config-jsonc.d.ts +2 -0
- package/dist/config-migration/transform-opencode.d.ts +2 -0
- package/dist/config-migration/transform-types.d.ts +24 -0
- package/dist/config-migration/types.d.ts +39 -0
- package/dist/create-hooks.d.ts +35 -35
- package/dist/features/background-agent/spawner/tmux-callback-invoker.d.ts +11 -0
- package/dist/features/builtin-commands/templates/hyperplan.d.ts +1 -1
- package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
- package/dist/features/claude-tasks/types.d.ts +4 -4
- package/dist/features/team-mode/team-runtime/shutdown-helpers.d.ts +1 -1
- package/dist/features/team-mode/team-runtime/shutdown-test-fixtures.d.ts +4 -4
- package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +42 -42
- package/dist/features/tmux-subagent/environment-eligibility.d.ts +2 -0
- package/dist/features/tmux-subagent/index.d.ts +1 -0
- package/dist/features/tmux-subagent/tracked-session-state.d.ts +1 -0
- package/dist/features/tui-sidebar/snapshot-schema.d.ts +6 -6
- package/dist/help/schema/acp.d.ts +3 -3
- package/dist/help/schema/doctor.d.ts +4 -4
- package/dist/help/schema/status.d.ts +3 -3
- package/dist/hooks/auto-update-checker/constants.d.ts +3 -3
- package/dist/hooks/goal/types.d.ts +5 -5
- package/dist/hooks/non-interactive-env/constants.d.ts +4 -1
- package/dist/hooks/start-work/parse-user-request.d.ts +2 -0
- package/dist/hooks/start-work/worktree-block.d.ts +5 -0
- package/dist/index.js +35450 -28257
- package/dist/mcp/types.d.ts +3 -3
- package/dist/oh-my-opencode.schema.json +1 -1
- package/dist/plugin/chat-message/loop-commands.d.ts +1 -0
- package/dist/plugin/command-execute-before.d.ts +3 -3
- package/dist/plugin/hooks/create-core-hooks.d.ts +25 -25
- package/dist/plugin-config/omo-config-chain.d.ts +14 -0
- package/dist/plugin-config/unknown-key-diagnostics.d.ts +5 -0
- package/dist/plugin-config.d.ts +2 -2
- package/dist/shared/agent-display-names.d.ts +1 -1
- package/dist/shared/jsonc-parser.d.ts +1 -1
- package/dist/shared/migration.d.ts +5 -1
- package/dist/shared/opencode-config-dir-types.d.ts +0 -1
- package/dist/shared/plugin-identity.d.ts +6 -8
- package/dist/shared/project-discovery-dirs.d.ts +0 -1
- package/dist/shared/tmux/tmux-utils/environment.d.ts +1 -1
- package/dist/shared/tmux/tmux-utils.d.ts +1 -1
- package/dist/shared/typescript-native-source-parser.d.ts +7 -0
- package/dist/skills/coding-agent-sessions/SKILL.md +5 -2
- package/dist/skills/coding-agent-sessions/references/all-platforms.md +3 -1
- package/dist/skills/coding-agent-sessions/references/senpi.md +15 -5
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +46 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +19 -10
- package/dist/skills/debugging/SKILL.md +2 -1
- package/dist/skills/debugging/references/methodology/03-flaky-triage.md +47 -0
- package/dist/skills/frontend/ATTRIBUTION.md +7 -0
- package/dist/skills/frontend/SKILL.md +4 -1
- package/dist/skills/frontend/references/design/README.md +8 -0
- package/dist/skills/frontend/references/design/_INDEX.md +14 -1
- package/dist/skills/frontend/references/design/interaction-skill.md +144 -0
- package/dist/skills/programming/SKILL.md +11 -1
- package/dist/skills/programming/references/logging.md +6 -1
- package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.ts +51 -17
- package/dist/skills/start-work/SKILL.md +12 -2
- package/dist/skills/ulw-plan/SKILL.md +1 -1
- package/dist/skills/ulw-plan/references/full-workflow.md +12 -1
- package/dist/skills/ulw-plan/references/intent-clear.md +1 -1
- package/dist/startup-migration.d.ts +28 -0
- package/dist/testing/create-plugin-module.d.ts +4 -0
- package/dist/tools/task/types.d.ts +10 -10
- package/dist/tui.js +31812 -26849
- package/package.json +14 -14
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +21 -5
- package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +11 -2
- package/packages/omo-codex/THIRD-PARTY-NOTICES.md +2 -2
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +8 -4
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +11 -5
- package/packages/omo-codex/plugin/components/codegraph/NOTICE +1 -1
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +10272 -2600
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +7341 -562
- package/packages/omo-codex/plugin/components/codegraph/package.json +2 -2
- package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +33 -0
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +36 -10
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +170 -186
- package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +34 -0
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +22 -5
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +106 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +145 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +21 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +139 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +15 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +32 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +109 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +148 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +126 -186
- package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +9 -4
- package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +160 -0
- package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +12 -110
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +29 -20
- package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +3 -3
- package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +2 -2
- package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +11 -5
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +3 -3
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +2 -1
- package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +50 -5
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +3 -2
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +24 -13
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +70 -13
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +58 -0
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +104 -0
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +4 -2
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +116 -0
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +114 -119
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +31 -14
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +12 -7
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +12 -7
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +12 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +12 -7
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +19 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +42 -41
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/shared/src/config-loader.ts +165 -16
- package/packages/omo-codex/plugin/shared/src/config-migration.ts +162 -0
- package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +196 -18
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +5 -2
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +3 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +15 -5
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +46 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +19 -10
- package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -1
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/03-flaky-triage.md +47 -0
- package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +7 -0
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +4 -1
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +8 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +14 -1
- package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +144 -0
- package/packages/omo-codex/plugin/skills/programming/SKILL.md +11 -1
- package/packages/omo-codex/plugin/skills/programming/references/logging.md +6 -1
- package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +51 -17
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +12 -2
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +12 -7
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +19 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +12 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +1 -1
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +22 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +1 -1
- package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +5 -2
- package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +3 -1
- package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +15 -5
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +46 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +19 -10
- package/packages/shared-skills/skills/debugging/SKILL.md +2 -1
- package/packages/shared-skills/skills/debugging/references/methodology/03-flaky-triage.md +47 -0
- package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +7 -0
- package/packages/shared-skills/skills/frontend/SKILL.md +4 -1
- package/packages/shared-skills/skills/frontend/references/design/README.md +8 -0
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +14 -1
- package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +144 -0
- package/packages/shared-skills/skills/programming/SKILL.md +11 -1
- package/packages/shared-skills/skills/programming/references/logging.md +6 -1
- package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.ts +51 -17
- package/packages/shared-skills/skills/start-work/SKILL.md +12 -2
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +1 -1
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +12 -1
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +1 -1
- package/dist/plugin-config/layered-config-loader.d.ts +0 -2
- package/dist/plugin-config/single-config-loader.d.ts +0 -4
- package/dist/shared/migrate-legacy-config-file.d.ts +0 -1
- package/dist/shared/migration/config-migration.d.ts +0 -1
|
@@ -175,6 +175,12 @@ Triggers: dashboard, settings, mail/inbox, list-detail, command surface, split p
|
|
|
175
175
|
|
|
176
176
|
**Action:** Add `layout-skill.md` on top of whatever style skill you selected in Steps 1-2. It carries scroll-ownership doctrine, the two silently-failing CSS contracts (`min-block-size: 0` scroll shells, `minmax(min(…),100%)` grids), the named-primitive vocabulary, container-vs-viewport routing, and the content-stress matrix. It adds no visual direction — the style skill still owns taste. Skip it for pure scroll-the-document marketing pages, where `taste-skill` layout guidance already fits.
|
|
177
177
|
|
|
178
|
+
### Step 9 — Does the work add or change interaction or motion?
|
|
179
|
+
|
|
180
|
+
Triggers: micro-interactions, animated components, transitions, gestures, hover/press/focus/state feedback, loading/success/error morphs, animated tabs/menus/modals/drawers/toasts — or "make it feel alive", "polish the interactions", "add micro-interactions".
|
|
181
|
+
|
|
182
|
+
**Action:** Add `interaction-skill.md` on top of whatever style skill you selected. It anchors interaction design to the beui.dev catalog: find the nearest pattern, read its real source through the file's curl recipe, extract the mechanism (spring config, layout strategy, enter/exit order, reduced-motion path), and adapt the values to `DESIGN.md`. It owns interaction mechanics only — no visual direction — so it stacks cleanly, like `layout-skill.md`.
|
|
183
|
+
|
|
178
184
|
## Stacking rules (read this once, internalize it)
|
|
179
185
|
|
|
180
186
|
1. **At most one Layer A *style* skill at a time.** A layout cannot be both `minimalist-skill` and `brutalist-skill` simultaneously — they encode opposite spacing and typography philosophies. Pick one.
|
|
@@ -184,6 +190,7 @@ Triggers: dashboard, settings, mail/inbox, list-detail, command surface, split p
|
|
|
184
190
|
5. **`image-to-code-skill.md` pairs with one imagegen skill** for the full flow.
|
|
185
191
|
6. **Layer B (brand DESIGN.md) is orthogonal to Layer A.** You can pair any Layer A skill with any Layer B brand. Use Layer B as the source of color/type/component tokens; let Layer A drive the execution discipline.
|
|
186
192
|
7. **`layout-skill.md` stacks on top of any style skill** for app-shell / dashboard / split-pane work. It owns spatial structure and scroll ownership only — no visual direction — so it never conflicts with the style skill you picked.
|
|
193
|
+
8. **`interaction-skill.md` stacks on top of any style skill** for interaction/motion work. It owns interaction mechanics — springs, layout morphs, enter/exit orchestration, reduced motion — and no visual direction, so it never conflicts with the style skill either.
|
|
187
194
|
|
|
188
195
|
## Anti-patterns — do not do these
|
|
189
196
|
|
|
@@ -227,6 +234,7 @@ Once references are loaded, before writing any UI code:
|
|
|
227
234
|
| "Also output a DESIGN.md doc" | Add `stitch-skill.md` to current stack |
|
|
228
235
|
| "Build a dashboard / settings / inbox / app shell" | one style skill (usually `taste-skill.md`) + `layout-skill.md` |
|
|
229
236
|
| "Panel won't scroll / footer pushed off-screen / mobile overflow" | Add `layout-skill.md` to current stack |
|
|
237
|
+
| "Add micro-interactions / animate this / make it feel alive" | Add `interaction-skill.md` to current stack |
|
|
230
238
|
|
|
231
239
|
## Phase Final — Design QA (MANDATORY, runs after implementation)
|
|
232
240
|
|
|
@@ -5,7 +5,7 @@ All reference files live flat in this directory. Three layers:
|
|
|
5
5
|
- **Layer A — taste skills** (12 files): how to execute. Discipline, motion, spacing, anti-slop, output completeness.
|
|
6
6
|
- **Layer B — design systems** (70 files): what it should look like. Brand-specific color/type/component tokens.
|
|
7
7
|
|
|
8
|
-
**Phase 0 runs first** (check/create `DESIGN.md`), then most non-trivial tasks load **one Layer A + one Layer B** together. See the routing flow in the sibling `README.md`.
|
|
8
|
+
**Phase 0 runs first** (check/create `DESIGN.md`), then most non-trivial tasks load **one Layer A + one Layer B** together. See the routing flow in the sibling `README.md`. Specialized phases (interaction and motion, app-shell layout, URL clones, real-product screen research) load the matching project-original operating reference — see the final section of this index.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -52,6 +52,19 @@ From [Leonxlnx/taste-skill](https://github.com/Leonxlnx/taste-skill).
|
|
|
52
52
|
|
|
53
53
|
---
|
|
54
54
|
|
|
55
|
+
## Operating references — interaction, layout, and research workflows (project-original)
|
|
56
|
+
|
|
57
|
+
Beyond the 12-file Layer A library, the design ruleset carries project-original operating references for specialized phases. They stack on the routed Layer A + Layer B pair; they never replace a style skill, and they are not counted in the library totals above.
|
|
58
|
+
|
|
59
|
+
| File | Purpose | Load when |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `interaction-skill.md` | Interaction mechanics anchored to the beui.dev catalog: find the nearest pattern, read its real source through the curl recipe, extract the mechanism (spring config, layout strategy, enter/exit order, reduced-motion path), and adapt it to `DESIGN.md` motion tokens. | Any work adding or changing interaction or motion — micro-interactions, animated components, transitions, gestures, hover/press/state feedback, loading/success/error morphs, "make it feel alive". |
|
|
62
|
+
| `layout-skill.md` | Layout mechanics: scroll ownership, the two silent CSS contracts, named primitives, content-stress matrix. Zero visual direction. | App shells, dashboards, split panes, or a layout that breaks under real content. |
|
|
63
|
+
| `lazyweb.md` | Curl-only real-product screen research for design direction. | Greenfield design research lanes. |
|
|
64
|
+
| `clone-from-url.md` | Runtime extraction workflow (browser + `getComputedStyle`) for cloning a named site. | A live site or URL is the visual reference. |
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
55
68
|
## Layer B — Design Systems (70)
|
|
56
69
|
|
|
57
70
|
Most Layer B files are materialized from [VoltAgent/awesome-design-md](https://github.com/VoltAgent/awesome-design-md), based on [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/overview/). Project-original entries such as `aside.md` are listed here only when `ATTRIBUTION.md` and `frontend-refs-manifest.mjs` mark them as original. Each file captures one website's complete visual language: color palette, typography, components, layout principles, depth, do/don't, responsive behavior, and an agent prompt guide.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: interaction-skill
|
|
3
|
+
description: "Layer A interaction-mechanics reference anchored to the beui.dev catalog. Stacks on any style skill whenever work adds or changes motion or interaction — micro-interactions, animated components, transitions, gestures, hover/press/state feedback, loading/success/error morphs, 'make it feel alive'. Mandates reading the mapped beui.dev component source before designing an interaction; owns interaction mechanics and reduced-motion discipline; owns zero visual taste. Load it alongside a style skill; it does not replace one."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Interaction Mechanics — beui.dev-Anchored
|
|
7
|
+
|
|
8
|
+
Style skills decide how a surface looks. This file decides how it *moves and responds* — spring physics, layout morphs, enter/exit orchestration, gesture feel, and reduced-motion discipline. It stacks on top of any Layer A style skill and any Layer B brand, exactly like `layout-skill.md`, and adds ZERO visual direction: color, type, and material still come from the style skill and `DESIGN.md`.
|
|
9
|
+
|
|
10
|
+
Load this whenever the deliverable includes interaction feel: micro-interactions, animated components, transitions, hover/press/focus/state feedback, gestures, loading/success/error morphs, animated tabs/menus/modals/drawers/toasts — or the user says "make it feel alive", "polish the interactions", "add micro-interactions".
|
|
11
|
+
|
|
12
|
+
## 1. The reference contract — never design an interaction from memory
|
|
13
|
+
|
|
14
|
+
[beui.dev](https://beui.dev) is the interaction benchmark: free, open-source animated React components (Motion + Tailwind CSS) where every component ships reduced-motion support and the full TypeScript source is one `curl` away. Improvised interaction design produces slop motion the same way freestyled styling produces generic SaaS slop, and the fix is the same: consult the reference before designing.
|
|
15
|
+
|
|
16
|
+
The contract, in order:
|
|
17
|
+
|
|
18
|
+
1. **Find the nearest pattern** in the catalog (section 3). The live catalog is `https://beui.dev/llms.txt`; refresh from it when a pattern seems missing from the tables below.
|
|
19
|
+
2. **Read its real source** through the recipe (section 2). Never guess spring values, exit orchestration, or gesture thresholds from a preview description.
|
|
20
|
+
3. **Extract the mechanism**, not the pixels: the spring config, the layout strategy (`layoutId` shared layout vs height morph vs clip-path), what animates in what order on enter/exit, where blur crossfades sit, and what the reduced-motion path swaps to.
|
|
21
|
+
4. **Adapt to the project.** Concrete durations, easings, and spring params come from the project `DESIGN.md` Motion & Interaction section. Where beui.dev and `DESIGN.md` disagree, `DESIGN.md` wins. A value that is not in `DESIGN.md` gets added there first, then used.
|
|
22
|
+
5. **No matching pattern?** Compose from the nearest two, or state explicitly that the interaction is novel and record its mechanism in `DESIGN.md` before building it.
|
|
23
|
+
|
|
24
|
+
## 2. Consultation recipe (curl-only, verified 2026-07)
|
|
25
|
+
|
|
26
|
+
All endpoints are public, no auth, no browser:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
curl -s https://beui.dev/llms.txt # full catalog: every component + one-line feel
|
|
30
|
+
curl -s https://beui.dev/r # registry index (JSON): slugs, categories, endpoints
|
|
31
|
+
curl -s https://beui.dev/r/{slug} # component detail (JSON): files, dependencies, dates
|
|
32
|
+
curl -s https://beui.dev/r/{slug}/raw # component source (TypeScript) — the thing to read
|
|
33
|
+
curl -s https://beui.dev/components/{category}/{slug}.md # component doc page as markdown
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Categories are `motion` (primitives) and `blocks` (composed patterns). When the user wants the component itself rather than the mechanism, a shadcn-style item registry exists at `https://beui.dev/r/{slug}.json`. Read source to learn; do not vendor beui.dev files into reference docs, and do not paste whole components into a project when only the mechanism is needed.
|
|
37
|
+
|
|
38
|
+
## 3. Catalog — pattern routing map
|
|
39
|
+
|
|
40
|
+
### Buttons, state feedback, and progress
|
|
41
|
+
|
|
42
|
+
| Pattern (slug) | Mechanism | Reach for it when |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `button` | Spring press; StatefulButton idle → loading → success/error with blur-swap slots and morphing width; MagneticButton cursor pull | Any submit/CTA that has async states — never leave a button state-less |
|
|
45
|
+
| `action-swap` | Text/icon swap with blur motion | Copy → check, send → stop, any label that changes meaning in place |
|
|
46
|
+
| `expanding-arrow-button` | Expanding, hold-to-confirm, and slide CTA interactions | Expressive marketing CTAs, destructive hold-to-confirm |
|
|
47
|
+
| `animated-badge` | Animated state icons, pulse feedback | Connection/status dots, live activity indicators |
|
|
48
|
+
| `loader` | 17 variants incl. terminal-ascii; reduced motion swaps every transform for an opacity pulse | Any loading state; copy its reduced-motion contract even when hand-rolling |
|
|
49
|
+
| `otp-input` | Gliding focus ring, per-slot digit roll, error shake, success check draw | Code entry, verification flows |
|
|
50
|
+
| `file-upload` | Progress rows, retry/remove, reduced-motion-safe state changes | Upload queues, long-running item lists |
|
|
51
|
+
| `feedback-widget` | Trigger morphs into a popup with sending/success/retry states | Corner feedback affordances, inline report flows |
|
|
52
|
+
|
|
53
|
+
### Selection and form controls
|
|
54
|
+
|
|
55
|
+
| Pattern (slug) | Mechanism | Reach for it when |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `switch` | Spring-driven thumb with press feedback | Boolean toggles |
|
|
58
|
+
| `checkbox` | Draw-on checkmark, indeterminate support | Multi-select, tree selection |
|
|
59
|
+
| `radio` | Gliding `layoutId` indicator dot | Single-select groups |
|
|
60
|
+
| `input` | Label, icons, error shake, success check draw | Validated text entry |
|
|
61
|
+
| `select` | Panel bouncily unfolds from the trigger; Morph variant grows the trigger into the panel | Dropdown selection with spatial continuity |
|
|
62
|
+
| `range-slider` | Bouncy vertical-bar thumb gliding between snapped steps | Stepped value entry |
|
|
63
|
+
| `wheel-picker` | iOS-style 3D drum on native momentum scroll with notch snap | Date/time or option drums, mobile-feel pickers |
|
|
64
|
+
| `availability-scheduler` | Per-day spring toggles, blur-slide range add/remove | Schedule/slot editors |
|
|
65
|
+
|
|
66
|
+
### Navigation and wayfinding
|
|
67
|
+
|
|
68
|
+
| Pattern (slug) | Mechanism | Reach for it when |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| `tabs` | Pill/segment/underline with a spring `layoutId` indicator | Tab bars, view-mode selectors |
|
|
71
|
+
| `expandable-tabs` | Active icon tab expands to a labelled pill; panel morphs height, slides direction-aware | Compact tab bars with rich panels |
|
|
72
|
+
| `shared-layout-bg` | Pill glides between hovered items via shared layout, blur enter/exit | Sidebar/menu hover and active states |
|
|
73
|
+
| `dock` | macOS-style grouped actions with a gliding active pill | Toolbars, grouped action rails |
|
|
74
|
+
| `bounce-sidebar` | Active dot jumps between destinations on a curved spring path | Vertical navigation with a playful indicator |
|
|
75
|
+
| `preview-rail` | Compact ticks form a hover pyramid and reveal a floating destination preview | Dense navigation rails, session/thread switchers |
|
|
76
|
+
| `expandable-action-bar` | Icon actions expand into labelled controls on hover/focus | Compact action clusters |
|
|
77
|
+
| `overflow-actions` | Connected pill rail springs open to reveal extra controls | Primary-plus-overflow action groups |
|
|
78
|
+
| `command-palette` | Fuzzy filter with a spring-animated active row | Cmd-K surfaces |
|
|
79
|
+
| `bloom-menu` | Button morphs into a menu blooming iris-out from center with radial stagger | Radial/launcher menus |
|
|
80
|
+
|
|
81
|
+
### Overlays and surfaces
|
|
82
|
+
|
|
83
|
+
| Pattern (slug) | Mechanism | Reach for it when |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| `tooltip` | Blur enter/exit, spring spawn | Hover/focus hints |
|
|
86
|
+
| `popover` | Gooey SVG-filter ooze from the trigger; Morph variant clip-morphs from the trigger corner | Anchored panels that should feel attached to their trigger |
|
|
87
|
+
| `context-menu` | Pointer-origin clip morph, gliding active row, keyboard nav, typeahead, long-press | Right-click and long-press menus |
|
|
88
|
+
| `morphing-modal` | One panel morphs height between inner views, blur cross-fade on content | Multi-step dialogs, settings panes |
|
|
89
|
+
| `center-morph-modal` | Surface unfolds from its exact center toward every edge and folds back | Focused confirm/detail modals |
|
|
90
|
+
| `drawer` | Spring side panel, backdrop blur, body scroll lock, esc-to-close | Side panels, inspector panes |
|
|
91
|
+
| `bottom-sheet` | Draggable sheet with snap points, inertia, glass surface | Mobile-feel sheets on any platform |
|
|
92
|
+
| `dynamic-island` | Pill morphs between live-activity views with bouncy shell resize and blur crossfades | Live status surfaces, compact expanding widgets |
|
|
93
|
+
| `notification-stack` | Cards spring from a stacked summary into a readable list on hover/focus/tap | Notification centers, grouped alerts |
|
|
94
|
+
| `animated-toast-stack` | Status morphs, swipe dismissal, layout-aware stacking | Toast systems — layout-aware stacking is the bar |
|
|
95
|
+
| `theme-toggle` | Full-page clip-path reveal via the View Transition API | Theme switching that should feel like one gesture |
|
|
96
|
+
|
|
97
|
+
### Content, data, and gestures
|
|
98
|
+
|
|
99
|
+
| Pattern (slug) | Mechanism | Reach for it when |
|
|
100
|
+
|---|---|---|
|
|
101
|
+
| `bouncy-accordion` | Single-open accordion with weighted spring layout, reduced-motion-safe reveals | Disclosure groups, expandable rows |
|
|
102
|
+
| `table` | Virtualized 10k+ rows, sortable, resizable, minimal reduced-motion-safe motion | Data grids — proof that restraint is also a motion decision |
|
|
103
|
+
| `infinite-masonry` | Virtualized variable-height masonry with progressive load | Media/card walls |
|
|
104
|
+
| `swipeable-list` | Rows swipe to reveal contextual actions | Mobile-style lists with hidden actions |
|
|
105
|
+
| `pull-to-refresh` | Drag resistance, threshold feedback, async refresh | Refreshable feeds |
|
|
106
|
+
| `marquee` | Infinite horizontal/vertical scroll, pause on hover | Logo walls, tickers |
|
|
107
|
+
| `text-animation` | Spring reveals, chromatic sweeps, shimmer loading, letter-cascade swaps | Hero copy, streaming/loading text |
|
|
108
|
+
| `number` | Count-up values, rolling digit tickers | Metrics, token/cost counters |
|
|
109
|
+
| `cylinder-carousel` | Items line a 3D cylinder with springy glide and snap | Showcase carousels |
|
|
110
|
+
| `knockout-bracket` | Animated tournament fixtures paging through rounds | Bracket/progression views |
|
|
111
|
+
| `prediction-market` / `swap` / `wallet-card` | Trade tickets, morphing swap views, morphing account surfaces | Finance-shaped composite widgets |
|
|
112
|
+
| `not-found` | Five animated 404 styles | Error pages that keep the product's feel |
|
|
113
|
+
|
|
114
|
+
### Ambience and scroll
|
|
115
|
+
|
|
116
|
+
| Pattern (slug) | Mechanism | Reach for it when |
|
|
117
|
+
|---|---|---|
|
|
118
|
+
| `tilt-card` | 3D perspective tilt with cursor-tracked glare | Hero/product cards that should feel physical |
|
|
119
|
+
| `shader-background` | Canvas shader variants (mesh gradient, grain, warp, waves…); reduced motion freezes them | Atmospheric backgrounds with dimension |
|
|
120
|
+
| `scroll-animation` | Lenis smooth-scroll provider plus a reading-progress indicator | Scroll-driven storytelling |
|
|
121
|
+
|
|
122
|
+
## 4. Mechanics rules
|
|
123
|
+
|
|
124
|
+
These sharpen the shared axioms for interaction work; none of them replace the style skill.
|
|
125
|
+
|
|
126
|
+
- **Motion serves meaning.** Every animation maps to a real interaction, state change, or affordance. A hover that changes nothing is slop — beui.dev patterns all animate *state*, never decoration.
|
|
127
|
+
- **Reduced motion is part of the component, not an afterthought.** Every beui.dev component ships a reduced-motion path; match that bar. Web: `prefers-reduced-motion: reduce` disables or replaces every transform-based animation (the `loader` pattern's opacity-pulse swap is the model). React Native: respect the system reduce-motion setting.
|
|
128
|
+
- **GPU-composited properties only** — `transform`, `opacity`, `filter`. Never animate layout properties; morph layout through shared-layout (`layoutId`) or measured height primitives instead.
|
|
129
|
+
- **Springs move things; easings tint things.** Spatial movement (position, scale, layout morphs) wants spring physics so it stays interruptible and retargetable. Color, opacity, and blur want short duration + easing. Do not put a fixed-duration tween on a gesture-driven surface.
|
|
130
|
+
- **Interruptibility is non-negotiable.** A press, hover-out, or route change mid-animation must retarget smoothly, never queue or block input. This is the practical reason beui.dev uses springs — copy that property, not just the bounce.
|
|
131
|
+
- **Motion never regresses input latency or stream rendering.** Measure with the `perfection` ruleset when in doubt; a virtualized list's measurement contract beats a pretty reveal.
|
|
132
|
+
- **Library choice is a project decision, not a default.** beui.dev assumes Motion (motion.dev) + Tailwind. If the project already has a motion stack, adapt the mechanism to it. If it has none: CSS transitions/WAAPI cover micro-interactions; adding a library is justified by shared-layout or spring-physics needs and gets recorded (with bundle cost) in `DESIGN.md`. Check `package.json` before importing anything.
|
|
133
|
+
|
|
134
|
+
## 5. DESIGN.md integration
|
|
135
|
+
|
|
136
|
+
`design-system-architecture.md` defines a Motion & Interaction section in every `DESIGN.md`. This file feeds it:
|
|
137
|
+
|
|
138
|
+
- Extracted spring configs, durations, and easings land there as named tokens before components use them.
|
|
139
|
+
- Each shipped interaction traces to a catalog pattern (or a recorded novel mechanism) plus its reduced-motion behavior.
|
|
140
|
+
- New reusable interaction patterns (used 2+ times) get documented back into `DESIGN.md` Section 5 with their states, like any other primitive.
|
|
141
|
+
|
|
142
|
+
## 6. Verification
|
|
143
|
+
|
|
144
|
+
Interaction work is verified through `/visual-qa` with motion actually driven and inspected — hover, press, open/close, swipe, and theme transitions exercised on the rendered surface, plus a reduced-motion pass (emulate `prefers-reduced-motion: reduce`) proving the fallback exists. Timing-sensitive changes record a short screen capture, not just stills.
|
|
@@ -102,7 +102,7 @@ Mocks are a last resort, not a default. The priority order:
|
|
|
102
102
|
- **Accurate**: the test fails for the bug it names, and only that bug. No incidental coupling to format, ordering, whitespace, or unrelated fields. Assert on the *contract*, not on the dump.
|
|
103
103
|
- **Efficient**: the whole unit suite runs in < 30 seconds on a developer laptop. The whole integration suite in < 5 minutes. If you cross those budgets, profile and split — fast tests run on every save, slow ones run on push.
|
|
104
104
|
- **Deterministic**: no `sleep`, no wall-clock dependence, no order dependence (`-shuffle=on`, pytest-randomly, vitest random seed). Inject a `Clock`. Subscribe to the event, do not poll for it. Time-based flake is a bug, not a test issue.
|
|
105
|
-
- **Isolated**: every test starts from a known fixture and tears down. `t.TempDir()`, `t.Setenv()`, transactional rollback for DB tests. Two tests passing individually but failing together is a fixture leak — fix it immediately.
|
|
105
|
+
- **Isolated**: every test starts from a known fixture and tears down. `t.TempDir()`, `t.Setenv()`, transactional rollback for DB tests. Two tests passing individually but failing together is a fixture leak — fix it immediately. Isolation extends **across processes**: suite-global resources — sandbox/cache roots under a fixed tmpdir path, hardcoded listen ports, container names — are namespaced per run (`mktemp`, port `0`/ephemeral, unique names) so that two checkouts or worktrees of the repo running the suite concurrently cannot interfere. A fixed shared path that works on a single-checkout machine is a flake generator on a multi-agent workstation, and its signature is "a different test fails each run".
|
|
106
106
|
|
|
107
107
|
### Prompt tests: NEVER assert prose
|
|
108
108
|
|
|
@@ -113,6 +113,7 @@ Assert ONLY what a machine consumes:
|
|
|
113
113
|
- the builder's routing decision — `expect(getPromptSource(model)).toBe("gpt-5-6")`, never the sentence that routing produces
|
|
114
114
|
- a structural token the runtime dispatches on — a tool name, a tag like `<agent-identity>`, a parsed frontmatter field
|
|
115
115
|
- the conditional the code enforces — skill loaded → tool present; `verbose=false` → directive absent
|
|
116
|
+
- a routing-bearing trigger fragment inside a parsed frontmatter `description` that a router (code or an LLM skill-picker) dispatches on — pin the *minimal fragment that carries the routing decision*, never the surrounding style prose. Such pins are what let a later rewrite change every sentence around them while proving the routing contract survived.
|
|
116
117
|
|
|
117
118
|
If no machine consumes the text, there is no seam: write NO test and say so in the PR; review guards prose. When you DELEGATE test-writing, hand the child the behavior the test must distinguish ("fails if override precedence breaks"), never a ready-made assertion string, prompt fragment, or marker to copy — a prescribed mechanism that is wrong gets implemented faithfully, and the error ships with a green suite.
|
|
118
119
|
|
|
@@ -234,6 +235,15 @@ Logging is part of the code you ship, and it has iron rules of its own: levels c
|
|
|
234
235
|
|
|
235
236
|
---
|
|
236
237
|
|
|
238
|
+
## DEPENDENCY UPGRADES — CROSS-CUTTING RULES
|
|
239
|
+
|
|
240
|
+
- **`0.x` minor = major.** Semver promises nothing below 1.0: treat `0.N → 0.N+1` as a breaking upgrade — read the changelog, build, and run the full suite before trusting it. A required field appearing in a public options type is a routine `0.x` "minor".
|
|
241
|
+
- **Version literals live outside the manifest.** Before committing a bump, grep the repo for the old version string: Dockerfiles pinning a global CLI, CI workflows, docs, and contract tests all carry copies. A bump that updates only the package manifest ships a split-brain deploy.
|
|
242
|
+
- **Pin-parity contract tests are a pattern, not a nuisance.** A small test asserting the lockfile-resolved version equals the deploy artifact's pin (Dockerfile, image tag) turns silent drift into a red test. If the project has one, update it deliberately; if the bump reveals unguarded drift, add the test with the bump.
|
|
243
|
+
- **Never hand-merge a lockfile.** On conflict, take either side whole and regenerate with the package manager — the resolver owns that file, not you.
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
237
247
|
## MANDATORY POST-WRITE REVIEW LOOP
|
|
238
248
|
|
|
239
249
|
**This runs EVERY time you finish writing or substantively editing code, before you claim the task is done.** No exceptions.
|
|
@@ -56,9 +56,11 @@ Log where the system decides something, not where it does something:
|
|
|
56
56
|
- **Decision points** — retry chosen, fallback engaged, cache bypassed, degraded mode entered.
|
|
57
57
|
- **The one place an error is finally handled.**
|
|
58
58
|
|
|
59
|
-
Never log inside pure functions, utilities, or private helpers — callers with context log outcomes; internals stay silent.
|
|
59
|
+
Never log inside pure functions, utilities, or private helpers — callers with context log outcomes; internals stay silent. The mechanical rules:
|
|
60
60
|
|
|
61
61
|
- **One event, one line.** Log-and-rethrow at every layer turns one incident into five look-alike incidents. Log where the error is handled; layers that only propagate stay silent.
|
|
62
|
+
- **Answering the caller is not logging.** Converting a failure into a response — an HTTP 5xx body, an SSE error event, an error string returned to an LLM as a tool result, a non-zero exit code — satisfies the caller and leaves operations blind. This is the dominant finding when error paths are audited: the caller got an answer, the on-call got nothing. Every path that converts a failure into a caller-facing signal logs that failure exactly once, at the layer that handles it. When conversion layers stack, mark the error as logged at the handling layer (a symbol/flag on the error object) so outer catch-all handlers skip it — one incident, one line.
|
|
63
|
+
- **Expected feedback returned to the caller is not an event.** Validation results delivered as a normal response — including tool output an LLM agent consumes ("string not found", lint findings, a sandbox-boundary notice) — are response content, not anomalies. Log only the genuine I/O and subprocess failures behind them, and security rejections.
|
|
62
64
|
- **Mechanical logging belongs to middleware.** Request/response logging is wired once at the framework layer, never hand-assembled per handler. High-volume zero-signal paths (health probes, metrics scrapes) are excluded there as data — an exclusion set — not as scattered `if` statements.
|
|
63
65
|
|
|
64
66
|
**No speculative logs.** "Might need it later" is not a consumer. A log line earns its place through evidence: a debugging session that burned rounds because this state was invisible (see the debugging bridge below), an incident postmortem, an alert that needs the field.
|
|
@@ -69,6 +71,7 @@ Never log inside pure functions, utilities, or private helpers — callers with
|
|
|
69
71
|
- **Correlation or it did not happen.** Request-scoped lines carry the trace/request id; entity-scoped lines carry the entity id. A line you cannot join to its request is noise during the only moments logs matter.
|
|
70
72
|
- **Name events semantically** (`session.destroy`, `payment.fallback`), never positionally ("Step 3"). Step numbers couple the log stream to today's call structure; the first refactor makes them lie.
|
|
71
73
|
- **No secrets.** Tokens, credentials, session cookies, and PII never enter a log line; URLs are sanitized (strip or redact query params like `token`, `key`) before logging. A leaked log is a leaked credential.
|
|
74
|
+
- **Payload content belongs to the tracing channel, not the log stream.** In LLM/agent systems, user messages, model responses, and tool outputs are captured by the tracing product (turn recorder, trace exporter); a log line carries a hash, a length, and at most a short excerpt for correlation. Dumping conversation content into logs bloats the store and leaks data the log pipeline was never hardened for.
|
|
72
75
|
- **The logging path may not break the program.** If a log call can itself fail (serializing exotic state, a wrapper that touches I/O), that failure is caught, downgraded to a `warn` through a channel that cannot fail, and the operation continues. An empty catch around logging is still an empty catch.
|
|
73
76
|
|
|
74
77
|
## Anti-patterns
|
|
@@ -79,6 +82,8 @@ Never log inside pure functions, utilities, or private helpers — callers with
|
|
|
79
82
|
| Introducing a logging framework to a project that has none | Uninvited behavior change; Rule 0 violation |
|
|
80
83
|
| 4xx logged as `error` | Alert noise buries real pages |
|
|
81
84
|
| Log-and-rethrow at every layer | One incident looks like five |
|
|
85
|
+
| Failure converted to a caller response (5xx body, SSE error, LLM tool-error string, exit code) with no log | The caller got an answer; operations got nothing |
|
|
86
|
+
| Logging expected validation feedback that is returned to the caller | Response content, not an event — buries real failures |
|
|
82
87
|
| Variables interpolated into the message string | Un-aggregatable, un-alertable |
|
|
83
88
|
| "Might need it later" logs | No consumer → pure cost |
|
|
84
89
|
| Debug-time prints promoted to permanent `info` | Narration, not state transitions |
|
package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts
CHANGED
|
@@ -33,21 +33,26 @@ import fs from "node:fs"
|
|
|
33
33
|
import { createRequire } from "node:module"
|
|
34
34
|
import path from "node:path"
|
|
35
35
|
import process from "node:process"
|
|
36
|
-
import type * as tsTypes from "typescript"
|
|
36
|
+
import type * as tsTypes from "typescript/unstable/ast"
|
|
37
37
|
|
|
38
|
-
type
|
|
38
|
+
type TsApiModule = typeof import("typescript/unstable/async")
|
|
39
|
+
type TsAstModule = typeof import("typescript/unstable/ast")
|
|
40
|
+
type TsModule = {
|
|
41
|
+
readonly api: TsApiModule
|
|
42
|
+
readonly ast: TsAstModule
|
|
43
|
+
}
|
|
39
44
|
|
|
40
45
|
function loadTypescriptFromCaller(): TsModule {
|
|
41
|
-
// A static
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
// caller project (cwd) instead. When the caller has no local typescript, Bun
|
|
45
|
-
// falls back to a version-only stub from its global install cache instead of
|
|
46
|
-
// throwing, so the loaded module's API shape is verified as well.
|
|
46
|
+
// A static import resolves from this script's installed skill-cache path
|
|
47
|
+
// instead of the caller project. Resolve each TypeScript 7 API subpath from
|
|
48
|
+
// the caller so the script uses the project it audits.
|
|
47
49
|
const callerRequire = createRequire(path.join(process.cwd(), "no-excuse-anchor.cjs"))
|
|
48
50
|
try {
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
+
const api: Partial<TsApiModule> = callerRequire("typescript/unstable/async")
|
|
52
|
+
const ast: Partial<TsAstModule> = callerRequire("typescript/unstable/ast")
|
|
53
|
+
if (typeof api.API === "function" && typeof ast.isAsExpression === "function") {
|
|
54
|
+
return { api: api as TsApiModule, ast: ast as TsAstModule }
|
|
55
|
+
}
|
|
51
56
|
} catch { // no-excuse-ok: catch
|
|
52
57
|
// fall through to the clear error below
|
|
53
58
|
}
|
|
@@ -58,7 +63,8 @@ function loadTypescriptFromCaller(): TsModule {
|
|
|
58
63
|
process.exit(2)
|
|
59
64
|
}
|
|
60
65
|
|
|
61
|
-
const
|
|
66
|
+
const typescript = loadTypescriptFromCaller()
|
|
67
|
+
const ts = typescript.ast
|
|
62
68
|
|
|
63
69
|
type RuleId =
|
|
64
70
|
| "no-any-assertion"
|
|
@@ -132,9 +138,30 @@ function getLineText(sourceFile: tsTypes.SourceFile, line: number): string {
|
|
|
132
138
|
return sourceFile.text.slice(start, end)
|
|
133
139
|
}
|
|
134
140
|
|
|
135
|
-
function
|
|
141
|
+
async function parseSourceFiles(filePaths: readonly string[]): Promise<ReadonlyMap<string, tsTypes.SourceFile>> {
|
|
142
|
+
const compiler = new typescript.api.API({ cwd: process.cwd() })
|
|
143
|
+
try {
|
|
144
|
+
const snapshot = await compiler.updateSnapshot({ openFiles: [...filePaths] })
|
|
145
|
+
try {
|
|
146
|
+
const sourceFiles = await Promise.all(filePaths.map(async (filePath) => {
|
|
147
|
+
const project = await snapshot.getDefaultProjectForFile(filePath)
|
|
148
|
+
const sourceFile = await project?.program.getSourceFile(filePath)
|
|
149
|
+
if (!sourceFile) {
|
|
150
|
+
throw new Error(`TypeScript did not parse ${filePath}`)
|
|
151
|
+
}
|
|
152
|
+
return [filePath, sourceFile] as const
|
|
153
|
+
}))
|
|
154
|
+
return new Map(sourceFiles)
|
|
155
|
+
} finally {
|
|
156
|
+
await snapshot.dispose()
|
|
157
|
+
}
|
|
158
|
+
} finally {
|
|
159
|
+
await compiler.close()
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function analyzeFile(filePath: string, sourceFile: tsTypes.SourceFile): Violation[] {
|
|
136
164
|
const source = fs.readFileSync(filePath, "utf-8")
|
|
137
|
-
const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true)
|
|
138
165
|
const violations: Violation[] = []
|
|
139
166
|
|
|
140
167
|
function pos(node: tsTypes.Node): { line: number; column: number } {
|
|
@@ -251,7 +278,7 @@ function analyzeFile(filePath: string): Violation[] {
|
|
|
251
278
|
}
|
|
252
279
|
}
|
|
253
280
|
|
|
254
|
-
|
|
281
|
+
node.forEachChild(visit)
|
|
255
282
|
}
|
|
256
283
|
|
|
257
284
|
visit(sourceFile)
|
|
@@ -282,7 +309,7 @@ function formatViolation(v: Violation): string {
|
|
|
282
309
|
return `${v.filePath}:${v.line}:${v.column}: [${v.ruleId}] ${v.message}`
|
|
283
310
|
}
|
|
284
311
|
|
|
285
|
-
function main(): void {
|
|
312
|
+
async function main(): Promise<void> {
|
|
286
313
|
const args = process.argv.slice(2)
|
|
287
314
|
if (args.length === 0) {
|
|
288
315
|
console.error("usage: check-no-excuse-rules.ts <file-or-dir>...")
|
|
@@ -295,7 +322,14 @@ function main(): void {
|
|
|
295
322
|
process.exit(2)
|
|
296
323
|
}
|
|
297
324
|
|
|
298
|
-
const
|
|
325
|
+
const sourceFiles = await parseSourceFiles(files)
|
|
326
|
+
const violations = files.flatMap((filePath) => {
|
|
327
|
+
const sourceFile = sourceFiles.get(filePath)
|
|
328
|
+
if (!sourceFile) {
|
|
329
|
+
throw new Error(`TypeScript did not parse ${filePath}`)
|
|
330
|
+
}
|
|
331
|
+
return analyzeFile(filePath, sourceFile)
|
|
332
|
+
})
|
|
299
333
|
|
|
300
334
|
if (violations.length === 0) {
|
|
301
335
|
console.log(`No violations in ${files.length} file(s).`)
|
|
@@ -309,4 +343,4 @@ function main(): void {
|
|
|
309
343
|
process.exit(1)
|
|
310
344
|
}
|
|
311
345
|
|
|
312
|
-
main()
|
|
346
|
+
await main()
|
|
@@ -45,11 +45,21 @@ Execute a Prometheus work plan until every top-level checkbox is complete. This
|
|
|
45
45
|
## Usage
|
|
46
46
|
|
|
47
47
|
```text
|
|
48
|
-
$start-work [plan-name] [--worktree <absolute-path>]
|
|
48
|
+
$start-work [plan-name] [--worktree <absolute-path>] [--make-pr] [--ship]
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
- `plan-name` (optional): a full or partial file stem under `.omo/plans/`.
|
|
52
52
|
- `--worktree` (required for PR/branch work; otherwise optional): the task-owned git worktree path.
|
|
53
|
+
- `--make-pr` (optional): deliver the work as a pull request. IMPLIES worktree mode: when `--worktree` is absent, create a task-owned worktree (`git worktree add <absolute-path> <base-branch>`) before implementation and record it as `worktree_path`. On completion, push the branch and open a reviewer-readable PR, then hand off with the PR URL - merge only if the user asks.
|
|
54
|
+
- `--ship` (optional): full delivery lifecycle; implies `--make-pr`. After the PR opens, stay on the job until it is MERGED: watch CI and review gates, fix failures and address feedback from the worktree (fresh QA evidence for behavior changes), merge per the repository's merge policy, then remove the worktree and sync `.omo/` state back.
|
|
55
|
+
|
|
56
|
+
## Goal and todo discipline (MANDATORY)
|
|
57
|
+
|
|
58
|
+
Do ALL of this immediately after the plan is selected, BEFORE the first implementation dispatch. Skipping any step is a defect.
|
|
59
|
+
|
|
60
|
+
1. **Set the goal, in detail.** When a goal tool is available (`create_goal`), call it with a DETAILED objective: the plan name and path, the concrete end state, the phase and task counts, the delivery mode (direct, `--make-pr`, or `--ship`), and how completion will be verified. One work session = one goal. No goal tool -> record the same objective as the first ledger entry.
|
|
61
|
+
2. **Register every phase and task as todos.** Mirror the plan into the todo/plan tool of your harness: one phase per plan wave, one todo per column-zero checkbox (including the final verification wave). Register ALL of them up front - never keep tasks in memory only.
|
|
62
|
+
3. **Keep them current at every moment.** Mark a todo in_progress when its work dispatches and done immediately after its verification passes. Never batch-complete at the end, never execute work that is not a registered todo; discovered work is appended as a todo before it runs. The todo list, Boulder state, and plan checkboxes must always tell the same story.
|
|
53
63
|
|
|
54
64
|
## Phase 1: Select the plan
|
|
55
65
|
|
|
@@ -92,7 +102,7 @@ Write `.omo/boulder.json` before implementation starts. Prefix session ids with
|
|
|
92
102
|
}
|
|
93
103
|
```
|
|
94
104
|
|
|
95
|
-
For PR/branch work,
|
|
105
|
+
For PR/branch work, a task-owned worktree is mandatory before implementation starts: pass `--worktree`, or use `--make-pr`/`--ship`, which auto-create one. Verify the path with `git worktree list --porcelain` or create it with `git worktree add <path> <branch-or-HEAD>`, then store the absolute path as `worktree_path`. All edits, commands, tests, and evidence capture must run inside that worktree.
|
|
96
106
|
|
|
97
107
|
## Phase 3: Execute the next checkbox
|
|
98
108
|
|
|
@@ -411,13 +411,18 @@ Procedure (NON-NEGOTIABLE):
|
|
|
411
411
|
2-attempt stop rule below) — do not loop further.
|
|
412
412
|
|
|
413
413
|
# Commits
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
`
|
|
419
|
-
|
|
420
|
-
|
|
414
|
+
Commit frequently: one atomic commit per verified increment (RED→GREEN
|
|
415
|
+
+ its evidence), never one end-of-run omnibus; each commit builds +
|
|
416
|
+
tests green on its own; no WIP on the final branch.
|
|
417
|
+
BEFORE composing each message, read the history and mimic it: run
|
|
418
|
+
`git log --oneline -20` plus `git log -5 -- <touched paths>` and match
|
|
419
|
+
the observed convention — subject shape, scope names, message language,
|
|
420
|
+
body style, and typical commit size. Default to Conventional Commits
|
|
421
|
+
(`<type>(<scope>): <imperative>` — feat / fix / refactor / test / docs /
|
|
422
|
+
chore / build / ci / perf) only where history shows no stronger local
|
|
423
|
+
convention. If a plan file exists, final commit footer:
|
|
424
|
+
`Plan: .omo/plans/<slug>.md`. Skip committing only when the user forbade
|
|
425
|
+
commits this session — then stage + draft the message instead.
|
|
421
426
|
|
|
422
427
|
# Constraints
|
|
423
428
|
- Every behavior change needs a failing-first proof captured BEFORE
|
|
@@ -20,6 +20,7 @@ This skill is intentionally compact. The full workflow lives in `references/full
|
|
|
20
20
|
## Non-Negotiables
|
|
21
21
|
|
|
22
22
|
- Use the ulw-loop CLI state under `.omo/ulw-loop`; do not hand-edit goal state.
|
|
23
|
+
- Register goals up front (`omo ulw-loop create-goals`, then `create_goal` from the printed handoff) and mirror every atomic step into the live `update_plan` checklist: one ultra-granular step per action, exactly one in_progress, transitions marked the instant they happen.
|
|
23
24
|
- After any compaction or context loss, re-read brief + goals + ledger FIRST plus `omo ulw-loop status --json`, then resume; never re-plan from scratch.
|
|
24
25
|
- If `omo ulw-loop create-goals` says the existing aggregate is already complete, start unrelated new work with a fresh `--session-id <new-id>` instead of steering or forcing the completed default state. Use `--force` only to intentionally overwrite completed evidence.
|
|
25
26
|
- Every success criterion needs observable evidence from a real surface: a channel (terminal/TUI via the xterm.js web terminal, HTTP, browser, computer-use) or, for CLI- or data-shaped criteria, an auxiliary surface (CLI stdout, DB diff, parsed config dump).
|
|
@@ -31,7 +32,24 @@ This skill is intentionally compact. The full workflow lives in `references/full
|
|
|
31
32
|
- Track spawned agent names locally. Use `wait_agent` for mailbox signals, not proof of completion. A timeout only means no new mailbox update arrived. Treat a running child as alive.
|
|
32
33
|
- While children run, surface the active subagent count, agent names, and latest `WORKING:` phase.
|
|
33
34
|
- Fallback only when the child is completed without the deliverable, ack-only after `followup_task`, explicitly `BLOCKED:`, or no longer running. Then record inconclusive and respawn a smaller `fork_turns: "none"` task with the missing deliverable.
|
|
34
|
-
- Use `git-master` for git-tracked edits: inspect recent and touched-path commit history, then commit each verified work unit atomically in the repository's observed language, scope, and message style with only that unit's files staged.
|
|
35
|
+
- Use `git-master` for git-tracked edits: inspect recent and touched-path commit history, then commit each verified work unit atomically in the repository's observed language, scope, and message style with only that unit's files staged. Never carry verified units into a later omnibus commit.
|
|
36
|
+
|
|
37
|
+
## Team mode: decide it, do not default to it
|
|
38
|
+
|
|
39
|
+
Solo execution with parallel background `task` workers is the default. A team (`team_create`) adds per-member briefing, shared-state, and relay overhead, so it must be paid for by the work's shape. Decide ONCE, when the plan's work units are known, and record the verdict plus its reason in the notepad.
|
|
40
|
+
|
|
41
|
+
Stand up a team when BOTH hold:
|
|
42
|
+
|
|
43
|
+
1. **The units' scopes overlap in a way you cannot cleanly cut.** They touch the same module, contract, or migration, so one unit's discovery changes what another should do. Fire-and-forget workers cannot exchange that mid-flight; teammates can, because the lead relays it.
|
|
44
|
+
2. **Running them at the same time actually finishes sooner.** The units are each substantial and none is merely waiting on another's output. Two units where the second only consumes the first's result are a sequence, not a team.
|
|
45
|
+
|
|
46
|
+
When the units are genuinely independent — separate files, no shared contract — spawn parallel background `task` workers instead and avoid the team coordination overhead entirely. When the work is one cohesive unit, do it yourself. Overlap alone is not enough: near-identical units that would collide on the same lines are faster done in sequence by one worker.
|
|
47
|
+
|
|
48
|
+
Under team mode, isolate and land per unit:
|
|
49
|
+
|
|
50
|
+
- **One git worktree per member**, never a shared checkout — concurrent members editing one working tree corrupt each other's diffs and evidence. Give each member its own branch off the base and its own worktree path.
|
|
51
|
+
- **Merge per work unit, as each unit is verified.** A member's unit lands when its own evidence is captured and its gates are green; it does not wait for the slowest sibling. Integrate each merged unit back into the base the others branch from, so overlapping members rebase onto real merged work rather than guessing at it.
|
|
52
|
+
- **Conflicts are the lead's job.** When two members' units touch the same lines, the lead decides the order they land and tells the later member what changed; members never resolve a sibling's conflict blind.
|
|
35
53
|
|
|
36
54
|
## Codex Tool Mapping
|
|
37
55
|
|
|
@@ -108,5 +108,5 @@ Roles: `explorer` (internal patterns/conventions/tests), `librarian` (external d
|
|
|
108
108
|
|
|
109
109
|
## Stop rules
|
|
110
110
|
|
|
111
|
-
- Plan file exists, template filled, every todo has references + acceptance + QA + commit, dependency matrix consistent, and any required high-accuracy receipts are recorded: present the
|
|
111
|
+
- Plan file exists, template filled, every todo has references + acceptance + QA + commit, dependency matrix consistent, and any required high-accuracy receipts are recorded: present the handoff explanation (Phase 4 delivery format in `references/full-workflow.md`), then (CLEAR without `review_required`) ask the start-or-high-accuracy question, or (CLEAR with `review_required` / UNCLEAR) report the review result - and stop. **Never begin execution yourself.**
|
|
112
112
|
- Brief presented and `status: awaiting-approval` recorded: wait. Do not re-explore unless the user changes scope.
|
|
@@ -168,6 +168,17 @@ Runs in parallel; ALL must APPROVE; surface results and wait for the user's expl
|
|
|
168
168
|
- CLEAR with `review_required: true`: run the high-accuracy review before delivery, record receipts, then present the plan summary and review result. Do not ask whether to run the review; the user already asked.
|
|
169
169
|
- UNCLEAR: run the high-accuracy review AUTOMATICALLY before presenting (unless Classify=Trivial), then present a brief that LEADS with the derived approach and the adopted defaults; still wait for the user's explicit okay.
|
|
170
170
|
|
|
171
|
+
### Handoff explanation (the mandatory shape of every plan summary)
|
|
172
|
+
|
|
173
|
+
Every "present the plan summary/brief" above delivers THIS structure, in the user's language, derived from the finished plan file (COUNT the rows - never estimate):
|
|
174
|
+
|
|
175
|
+
1. **What this plan drives** - the work it performs, in 1-2 sentences.
|
|
176
|
+
2. **End state** - the concrete things that will exist or behave differently once execution finishes.
|
|
177
|
+
3. **Shape** - how many phases/waves and how many tasks: N implementation todos (`- [ ] N.` rows) + F final-verification tasks (`- [ ] F<n>.` rows).
|
|
178
|
+
4. **Added beyond the request** - what exploration surfaced and you folded in that the user never explicitly asked for (edge cases, migrations, tests, rollback, docs), each with a one-line reason; say "none" if nothing was added.
|
|
179
|
+
5. **Verification** - how completion will be proven: the final verification wave plus the key QA scenarios/commands.
|
|
180
|
+
6. **Execution handoff** - the plan runs in a worker session via `$start-work <plan-name>`; introduce the options: `--worktree <absolute-path>` (task-owned worktree; required for PR/branch work), `--make-pr` (deliver as a PR; auto-creates a task-owned worktree), `--ship` (implies `--make-pr`, keeps working until the PR is reviewed and MERGED).
|
|
181
|
+
|
|
171
182
|
### High-accuracy review (dual review)
|
|
172
183
|
The high-accuracy review is DUAL and both passes must return OKAY before handoff: (1) the native `momus` reviewer subagent, and (2) an independent Codex CLI review on gpt-5.6-sol at xhigh reasoning, run in a disposable isolated workspace and `CODEX_HOME` with the harness's normal approval and sandbox policy. Do not add flags that disable approvals or sandboxing. Momus runs at High and may take substantially longer than other agents. One round = exactly ONE `momus` + ONE independent review, dispatched together against the COMPLETE plan file (todos + TL;DR filled) at the draft's exact recorded `plan_path`. Keep Momus in flight and wait for its terminal result: elapsed time alone never justifies cancelling, duplicating, replacing, or treating it as failed. After both verdicts return, fix every cited issue and resubmit both fresh until each approves. CLEAR: runs when the user opts in or `review_required: true`. UNCLEAR: runs automatically unless Classify=Trivial.
|
|
173
184
|
|
|
@@ -212,6 +223,6 @@ If your tool list has a flat `spawn_agent` with a required `task_name` instead o
|
|
|
212
223
|
Roles: `explorer`, `librarian`, `metis`, `momus`. Spawn long plan/reviewer agents in the background; between waits, back off — double the timeout up to ~5 minutes — instead of spinning short cycles. Require the child to send `WORKING: <task> - <phase>` before long passes and `BLOCKED: <reason>` only when progress stops. A wait timeout only means no new mailbox update arrived; treat a running child as alive. Fall back only when the child completed without the deliverable, is ack-only after followup, explicitly `BLOCKED:`, or no longer running; then respawn a smaller `fork_context: false` job. Close each agent after integrating its result.
|
|
213
224
|
|
|
214
225
|
## Stop rules
|
|
215
|
-
- Plan file exists, template filled, every todo has references + acceptance + QA + commit, dependency matrix consistent, and any required high-accuracy receipts recorded: present the
|
|
226
|
+
- Plan file exists, template filled, every todo has references + acceptance + QA + commit, dependency matrix consistent, and any required high-accuracy receipts recorded: present the handoff explanation (Phase 4 format), then (CLEAR without `review_required`) ask the start-or-high-accuracy question, or (CLEAR with `review_required` / UNCLEAR) report the review result - and stop. Execution belongs to the worker, never to you.
|
|
216
227
|
- Brief presented and `status: awaiting-approval` recorded: wait. Do not re-explore unless the user changes scope.
|
|
217
228
|
- Two research waves with no new useful facts: stop exploring, present the brief.
|
|
@@ -30,7 +30,7 @@ CLEARANCE CHECK after each turn: objective defined? scope IN/OUT explicit? appro
|
|
|
30
30
|
</interview>
|
|
31
31
|
|
|
32
32
|
<approval_and_deliver>
|
|
33
|
-
Run the durable approval gate (mechanics in `full-workflow.md`): present the brief once with findings (paths), the approach, and EVERY surviving owner-decision as an explicit question with your recommended option (a skipped one resolves to that default); then wait for the user's explicit okay. If "start now, or review first?" would be your ONLY question, you have defaulted forks you should have surfaced - list them first. After approval: scaffold the files, run mandatory Metis, APPEND the todos, fill the human TL;DR last. Then either run the dual high-accuracy review if `review_required: true`, or present the
|
|
33
|
+
Run the durable approval gate (mechanics in `full-workflow.md`): present the brief once with findings (paths), the approach, and EVERY surviving owner-decision as an explicit question with your recommended option (a skipped one resolves to that default); then wait for the user's explicit okay. If "start now, or review first?" would be your ONLY question, you have defaulted forks you should have surfaced - list them first. After approval: scaffold the files, run mandatory Metis, APPEND the todos, fill the human TL;DR last. Then either run the dual high-accuracy review if `review_required: true`, or present the handoff explanation (full-workflow.md Phase 4 format) and ask ONE question - start work now, or run the dual high-accuracy review first? Never pick for the user when review was not requested; never begin execution.
|
|
34
34
|
</approval_and_deliver>
|
|
35
35
|
|
|
36
36
|
<worked_example>
|
|
@@ -235,6 +235,28 @@ test("#given synced aggregate Codex skills #when they describe background orches
|
|
|
235
235
|
}
|
|
236
236
|
});
|
|
237
237
|
|
|
238
|
+
test("#given packaged start-work and ulw-plan skills #when inspected #then PR delivery options and the handoff explanation ship", async () => {
|
|
239
|
+
// given
|
|
240
|
+
const startWork = await readSkill("start-work");
|
|
241
|
+
const workflow = await readFile(join(root, "skills", "ulw-plan", "references", "full-workflow.md"), "utf8");
|
|
242
|
+
|
|
243
|
+
// when / then
|
|
244
|
+
assert.match(startWork, /--make-pr/);
|
|
245
|
+
assert.match(startWork, /--ship/);
|
|
246
|
+
assert.match(startWork, /implies `--make-pr`/i);
|
|
247
|
+
assert.match(startWork, /IMPLIES worktree mode/i);
|
|
248
|
+
assert.match(startWork, /Goal and todo discipline/i);
|
|
249
|
+
assert.match(startWork, /create_goal/);
|
|
250
|
+
assert.match(startWork, /one todo per column-zero checkbox/i);
|
|
251
|
+
|
|
252
|
+
assert.match(workflow, /Handoff explanation/i);
|
|
253
|
+
assert.match(workflow, /Added beyond the request/i);
|
|
254
|
+
assert.match(workflow, /\$start-work <plan-name>/);
|
|
255
|
+
assert.match(workflow, /--make-pr/);
|
|
256
|
+
assert.match(workflow, /--ship/);
|
|
257
|
+
assert.match(workflow, /COUNT the rows/i);
|
|
258
|
+
});
|
|
259
|
+
|
|
238
260
|
test("#given start-work skill #when synced for Codex #then the difficulty-tier delegation guidance survives the overlay", async () => {
|
|
239
261
|
const content = await readSkill("start-work");
|
|
240
262
|
|
|
@@ -5903,7 +5903,7 @@ var package_default;
|
|
|
5903
5903
|
var init_package = __esm(() => {
|
|
5904
5904
|
package_default = {
|
|
5905
5905
|
name: "@oh-my-opencode/omo-codex",
|
|
5906
|
-
version: "4.19.
|
|
5906
|
+
version: "4.19.3",
|
|
5907
5907
|
type: "module",
|
|
5908
5908
|
private: true,
|
|
5909
5909
|
description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
|