oh-my-opencode 4.19.4 → 5.0.0-beta.10
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 +44 -16
- package/.agents/skills/publish/SKILL.md +44 -16
- package/.agents/skills/work-with-pr/SKILL.md +37 -23
- package/.opencode/command/publish.md +44 -16
- package/.opencode/skills/work-with-pr/SKILL.md +37 -23
- package/README.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +18 -6
- package/README.ru.md +1 -1
- package/README.zh-cn.md +1 -1
- package/bin/oh-my-opencode.js +14 -1
- package/bin/oh-my-opencode.test.ts +21 -0
- package/dist/agents/atlas/agent.d.ts +0 -1
- package/dist/agents/sisyphus/grok-4.d.ts +20 -0
- package/dist/agents/sisyphus/index.d.ts +2 -0
- package/dist/agents/sisyphus-agent-config.d.ts +6 -0
- package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
- package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
- package/dist/agents/types.d.ts +2 -2
- package/dist/cli/index.js +1888 -807
- package/dist/cli/run/on-complete-hook.d.ts +2 -0
- package/dist/cli-node/index.js +1888 -807
- package/dist/config/schema/agent-overrides.d.ts +528 -0
- package/dist/config/schema/oh-my-opencode-config.d.ts +495 -0
- package/dist/features/monitor/batcher.d.ts +3 -1
- package/dist/features/monitor/manager-internals.d.ts +1 -0
- package/dist/features/monitor/output-injector-types.d.ts +2 -0
- package/dist/features/monitor/output-injector.d.ts +6 -0
- package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
- package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
- package/dist/hooks/todo-continuation-enforcer/unrecoverable-request-error.d.ts +9 -0
- package/dist/hooks/tool-pair-validator/hook.test-support.d.ts +29 -0
- package/dist/hooks/tool-pair-validator/tool-part-ids.d.ts +14 -5
- package/dist/hooks/tool-pair-validator/tool-result-repair.d.ts +4 -3
- package/dist/hooks/tool-pair-validator/types.d.ts +5 -22
- package/dist/index.js +3139 -2232
- package/dist/mcp/lsp.d.ts +1 -0
- package/dist/oh-my-opencode.schema.json +1466 -131
- package/dist/shared/normalize-sdk-response.d.ts +1 -0
- package/dist/shared/shell-env.d.ts +1 -1
- package/dist/shared/tmux/constants.d.ts +1 -1
- package/dist/skills/ast-grep/SOURCE +1 -1
- package/dist/skills/ast-grep/install.ps1 +2 -2
- package/dist/skills/ast-grep/install.sh +1 -1
- package/dist/skills/ast-grep/references/install.md +2 -2
- package/dist/skills/ast-grep/tests/smoke.sh +1 -1
- package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
- package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/dist/skills/frontend/SKILL.md +10 -7
- package/dist/skills/frontend/references/design/_INDEX.md +1 -0
- package/dist/skills/frontend/references/design/stylegallery.md +80 -0
- package/dist/skills/start-work/SKILL.md +54 -9
- package/dist/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
- package/dist/skills/ultimate-browsing/SKILL.md +2 -2
- package/dist/skills/ultimate-browsing/engine/AGENTS.md +179 -0
- package/dist/skills/ultimate-browsing/engine/__main__.py +8 -1
- package/dist/skills/ultimate-browsing/engine/bias_check.py +11 -0
- package/dist/skills/ultimate-browsing/engine/fetch_chain.py +90 -52
- package/dist/skills/ultimate-browsing/engine/result_schema.py +10 -1
- package/dist/skills/ultimate-browsing/engine/surrogate.py +214 -0
- package/dist/skills/ultimate-browsing/engine/surrogates.yaml +60 -0
- package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/dist/skills/ultimate-browsing/engine/tests/fixtures/amp_redirect_stub.html +7 -0
- package/dist/skills/ultimate-browsing/engine/tests/fixtures/search_interstitial.html +19 -0
- package/dist/skills/ultimate-browsing/engine/tests/fixtures/wayback_available.json +1 -0
- package/dist/skills/ultimate-browsing/engine/tests/fixtures/wayback_snapshot.html +1128 -0
- package/dist/skills/ultimate-browsing/engine/tests/test_surrogate.py +252 -0
- package/dist/skills/ultimate-browsing/engine/tests/test_surrogate_validators.py +78 -0
- package/dist/skills/ultimate-browsing/engine/validators.py +46 -0
- package/dist/skills/ultimate-browsing/engine/waf_detector.py +1 -1
- package/dist/skills/ultimate-browsing/engine/waf_profiles.yaml +10 -5
- package/dist/skills/ultimate-browsing/references/agent-reach/social.md +1 -1
- package/dist/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
- package/dist/skills/ultimate-browsing/references/insane-search/README.md +4 -4
- package/dist/skills/ultimate-browsing/references/insane-search/cache-archive.md +51 -50
- package/dist/skills/ultimate-browsing/references/insane-search/fallback.md +1 -1
- package/dist/skills/ultimate-browsing/references/insane-search/jina.md +8 -2
- package/dist/skills/ultimate-browsing/references/insane-search/naver.md +1 -1
- package/dist/skills/ultimate-browsing/references/insane-search/twitter.md +3 -3
- package/dist/skills/ulw-plan/SKILL.md +3 -3
- package/dist/skills/ulw-plan/references/full-workflow.md +30 -6
- package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
- package/dist/skills/ulw-plan/references/intent-unclear.md +3 -3
- package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
- package/dist/skills/ulw-research/SKILL.md +15 -10
- package/dist/tui.js +477 -36
- package/docs/reference/web-terminal-visual-qa.md +1 -1
- package/package.json +34 -24
- package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +0 -28
- package/packages/lsp-core/src/lsp/client-wrapper.test.ts +60 -7
- package/packages/lsp-core/src/lsp/client-wrapper.ts +69 -16
- package/packages/lsp-core/src/lsp/connection.ts +1 -1
- package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
- package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
- package/packages/lsp-core/src/tools/navigation.ts +4 -2
- package/packages/lsp-core/src/tools/rename.ts +4 -2
- package/packages/lsp-core/src/tools/symbols.ts +1 -1
- package/packages/lsp-daemon/dist/cli.js +108 -40
- package/packages/lsp-daemon/dist/client.js +123 -55
- package/packages/lsp-daemon/dist/ensure-daemon.d.ts +1 -0
- package/packages/lsp-daemon/dist/ensure-daemon.js +18 -5
- package/packages/lsp-daemon/dist/index.js +111 -43
- package/packages/lsp-tools-mcp/dist/cli.js +77 -23
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +1 -1
- package/packages/lsp-tools-mcp/dist/mcp.js +77 -23
- package/packages/lsp-tools-mcp/dist/tools.js +77 -23
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +268 -92
- 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/bootstrap/src/setup.ts +7 -7
- package/packages/omo-codex/plugin/components/bootstrap/src/worker.ts +3 -0
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +220 -10
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +220 -10
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- 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/lazycodex-executor-verify/test/codex-hook.test.ts +3 -17
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +135 -67
- 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/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
- package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +16 -23
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
- package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
- package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +37 -69
- package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
- package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +1 -15
- package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +4 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/README.md +5 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +2 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +18 -0
- 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/start-work-continuation/src/codex-hook.ts +21 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +0 -3
- package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +107 -16
- 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/teammode/test/thread-title-hook.test.ts +3 -9
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +24 -12
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +24 -12
- 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/CHANGELOG.md +2 -0
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-low.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +9 -2
- 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 +9 -2
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +3 -3
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +30 -6
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +3 -3
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
- package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
- package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +11 -11
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +9 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +9 -9
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +66 -66
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +2 -2
- 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 +5 -4
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +23 -25
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +9 -9
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-helpers.test.ts +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-kind-guidance.test.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +2 -5
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +7 -40
- package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +4 -5
- 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 +20 -20
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +4 -4
- package/packages/omo-codex/plugin/skills/ast-grep/SOURCE +1 -1
- package/packages/omo-codex/plugin/skills/ast-grep/install.ps1 +2 -2
- package/packages/omo-codex/plugin/skills/ast-grep/install.sh +1 -1
- package/packages/omo-codex/plugin/skills/ast-grep/references/install.md +2 -2
- package/packages/omo-codex/plugin/skills/ast-grep/tests/smoke.sh +1 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +10 -7
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +54 -9
- package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
- package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -2
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +179 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/__main__.py +8 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/bias_check.py +11 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/fetch_chain.py +90 -52
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/result_schema.py +10 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/surrogate.py +214 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/surrogates.yaml +60 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/amp_redirect_stub.html +7 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/search_interstitial.html +19 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_available.json +1 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_snapshot.html +1128 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate.py +252 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate_validators.py +78 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/validators.py +46 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/waf_detector.py +1 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/waf_profiles.yaml +10 -5
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/social.md +1 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +4 -4
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/cache-archive.md +51 -50
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/fallback.md +1 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/jina.md +8 -2
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/naver.md +1 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/twitter.md +3 -3
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +9 -2
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +5 -4
- package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +23 -25
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +3 -3
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +30 -6
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +3 -3
- package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +15 -10
- package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +4 -24
- package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
- package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
- package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
- package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +12 -12
- package/packages/omo-codex/plugin/test/bootstrap-orchestration.test.mjs +36 -4
- package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
- package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
- package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +4 -4
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +1 -119
- package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
- package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
- package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
- package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
- package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
- package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +0 -3
- package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
- package/packages/omo-codex/scripts/install-bin-links.test.mjs +56 -2
- package/packages/omo-codex/scripts/install-delegated-command.test.mjs +6 -6
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +170 -78
- package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
- package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +4 -4
- package/packages/omo-codex/scripts/install-local.test.mjs +5 -2
- package/packages/shared-skills/index.mjs +19 -1
- package/packages/shared-skills/skills/ast-grep/SOURCE +1 -1
- package/packages/shared-skills/skills/ast-grep/install.ps1 +2 -2
- package/packages/shared-skills/skills/ast-grep/install.sh +1 -1
- package/packages/shared-skills/skills/ast-grep/references/install.md +2 -2
- package/packages/shared-skills/skills/ast-grep/tests/smoke.sh +1 -1
- package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
- package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
- package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
- package/packages/shared-skills/skills/frontend/SKILL.md +10 -7
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
- package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
- package/packages/shared-skills/skills/start-work/SKILL.md +54 -9
- package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
- package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -2
- package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +179 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/__main__.py +8 -1
- package/packages/shared-skills/skills/ultimate-browsing/engine/bias_check.py +11 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/fetch_chain.py +90 -52
- package/packages/shared-skills/skills/ultimate-browsing/engine/result_schema.py +10 -1
- package/packages/shared-skills/skills/ultimate-browsing/engine/surrogate.py +214 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/surrogates.yaml +60 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
- package/packages/shared-skills/skills/ultimate-browsing/engine/tests/fixtures/amp_redirect_stub.html +7 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/tests/fixtures/search_interstitial.html +19 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/tests/fixtures/wayback_available.json +1 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/tests/fixtures/wayback_snapshot.html +1128 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_surrogate.py +252 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_surrogate_validators.py +78 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/validators.py +46 -0
- package/packages/shared-skills/skills/ultimate-browsing/engine/waf_detector.py +1 -1
- package/packages/shared-skills/skills/ultimate-browsing/engine/waf_profiles.yaml +10 -5
- package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/social.md +1 -1
- package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +4 -4
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/cache-archive.md +51 -50
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/fallback.md +1 -1
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/jina.md +8 -2
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/naver.md +1 -1
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/twitter.md +3 -3
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +3 -3
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +30 -6
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
- package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +3 -3
- package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
- package/packages/shared-skills/skills/ulw-research/SKILL.md +15 -10
- package/postinstall.mjs +6 -0
- package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
- package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
- package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
|
@@ -5,14 +5,14 @@ import { formatAdditionalContextOutput } from "../src/hook-output.js";
|
|
|
5
5
|
describe("formatAdditionalContextOutput", () => {
|
|
6
6
|
it("#given context with outer whitespace and CRLF #when serializing hook JSON #then additional context is newline-normalized", () => {
|
|
7
7
|
// given
|
|
8
|
-
const context = "\r\n\r\
|
|
8
|
+
const context = "\r\n\r\nA1\r\nB2\rC3\r\n";
|
|
9
9
|
|
|
10
10
|
// when
|
|
11
11
|
const output = formatAdditionalContextOutput("PostToolUse", context);
|
|
12
12
|
const parsed: unknown = JSON.parse(output);
|
|
13
13
|
|
|
14
14
|
// then
|
|
15
|
-
expect(readAdditionalContext(parsed)).toBe("
|
|
15
|
+
expect(readAdditionalContext(parsed)).toBe("A1\nB2\nC3");
|
|
16
16
|
expect(output.endsWith("\n")).toBe(true);
|
|
17
17
|
});
|
|
18
18
|
|
|
@@ -40,7 +40,6 @@ describe("formatAdditionalContextOutput", () => {
|
|
|
40
40
|
expect(additionalContext.length).toBeLessThanOrEqual(32_000);
|
|
41
41
|
expect(additionalContext).toContain("first");
|
|
42
42
|
expect(additionalContext).not.toContain("last");
|
|
43
|
-
expect(additionalContext).toContain("[Truncated hook additional context to 32000 chars");
|
|
44
43
|
});
|
|
45
44
|
});
|
|
46
45
|
|
package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts
CHANGED
|
@@ -71,25 +71,11 @@ describe("Windows Git Bash bundled rule content", () => {
|
|
|
71
71
|
expect(body).toContain("alwaysApply: true");
|
|
72
72
|
});
|
|
73
73
|
|
|
74
|
-
it(
|
|
75
|
-
const body = readWindowsRuleBody();
|
|
76
|
-
|
|
77
|
-
expect(body).not.toContain('shell: "bash"');
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it("#given the bundled rule #when read #then it warns that bare bash often resolves to WSL System32", () => {
|
|
81
|
-
const body = readWindowsRuleBody();
|
|
82
|
-
|
|
83
|
-
expect(body).toMatch(/WSL/i);
|
|
84
|
-
expect(body).toMatch(/System32/i);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("#given the bundled rule #when read #then it prefers the git_bash MCP and the absolute Git Bash path", () => {
|
|
74
|
+
it("#given the bundled rule #when read #then it names the Git Bash runtime identifiers", () => {
|
|
88
75
|
const body = readWindowsRuleBody();
|
|
89
76
|
|
|
90
77
|
expect(body).toContain("git_bash");
|
|
91
78
|
expect(body).toContain("OMO_CODEX_GIT_BASH_PATH");
|
|
92
|
-
expect(body).toContain("C:\\Program Files\\Git\\bin\\bash.exe");
|
|
93
79
|
});
|
|
94
80
|
});
|
|
95
81
|
|
|
@@ -31,9 +31,10 @@ Conventions for human contributors and AI agents working on this repository.
|
|
|
31
31
|
|
|
32
32
|
## Layout
|
|
33
33
|
|
|
34
|
-
- `src/boulder-reader.ts`: reads `.omo/boulder.json`, resolves the active work for the session, re-exports `getPlanChecklist`/`PlanChecklist` from `plan-checklist.ts`. `readContinuationState` returns null
|
|
34
|
+
- `src/boulder-reader.ts`: reads `.omo/boulder.json`, resolves the active work for the session, re-exports `getPlanChecklist`/`PlanChecklist` from `plan-checklist.ts`. `readContinuationState` returns null in four cases: `boulder.json` is missing or unparseable, no work matches the session, the work status is not continuable (only `active` and `paused` continue - `completed`/`abandoned` stop), or `checklist.total === 0`.
|
|
35
35
|
- `src/plan-checklist.ts`: `PlanChecklist` (`completed`/`remaining`/`total`/`nextTaskLabel`) and `getPlanChecklist`/`parsePlanChecklist`. Counts structured `## TODOs` rows (`N. <title>`) and `## Final Verification Wave` rows (`F<number>. <title>`); falls back to simple top-level `- [ ]`/`- [x]` checkboxes. Skips fenced blocks and respects `#`/`##` section boundaries.
|
|
36
|
-
- `src/codex-hook.ts`: Stop/SubagentStop hook; fills `REMAINING_COUNT
|
|
36
|
+
- `src/codex-hook.ts`: Stop/SubagentStop hook; fills nine placeholders into `directive.md` - `PLAN_NAME`, `PLAN_PATH`, `BOULDER_PATH`, `REMAINING_COUNT`, `TOTAL_COUNT`, `NEXT_TASK_LABEL`, `WORKTREE_BLOCK`, `LEDGER_PATH`, `SESSION_ID`. `WORKTREE_BLOCK` renders empty when the work has no worktree. When `remaining === 0`, `nextTaskLabel` is null and renders as "none (final gate pending)".
|
|
37
|
+
- **Context-pressure suppression:** the hook reads `input.transcript_path` through the injected `ReadonlyFileSystem` and returns `""` (no continuation) when the transcript carries any context-pressure marker (`context compacted`, `context_length_exceeded`, `context_too_large`, `codex ran out of room in the model's context window`, and related phrasings). This is the safety valve against an infinite continuation loop once the context window is exhausted; it is pinned by a `#given context-window pressure` test.
|
|
37
38
|
- `directive.md`: directive template with placeholders, applied per invocation.
|
|
38
39
|
|
|
39
40
|
## Build and Hooks
|
|
@@ -48,4 +49,5 @@ Conventions for human contributors and AI agents working on this repository.
|
|
|
48
49
|
- Never make a network call from the hook.
|
|
49
50
|
- Keep the directive in `directive.md`. Do not inline it into TypeScript files.
|
|
50
51
|
- The hook only continues sessions listed in `.omo/boulder.json` as `codex:<session_id>`.
|
|
52
|
+
- The hook yields no output when `last_assistant_message` starts with `<start-work-blocked-external>`, or when that marker is the second line immediately after the mandatory `ULTRAWORK MODE ENABLED!` opener, so a conclusive external blocker can end the turn. Reject the marker everywhere else.
|
|
51
53
|
- The hook continues while the plan has a readable top-level checklist (`total > 0`). A fully-checked plan still blocks Stop until the final gate runs and the Boulder work is marked completed; an unreadable or empty checklist yields no output.
|
|
@@ -8,7 +8,11 @@ It reads `.omo/boulder.json` in the hook payload `cwd`, resolves the active work
|
|
|
8
8
|
{"decision":"block","reason":"<directive>"}
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
The `reason` is loaded from `directive.md` on every invocation and filled with current plan state. The hook returns no output when `stop_hook_active` is `true`, when no active Boulder work exists, when the work is completed, when the active work is not tied to `codex:<session_id>`, or when the plan has no readable top-level checklist. An active plan whose checklist is fully checked still blocks Stop until the final gate runs and Boulder is marked completed.
|
|
11
|
+
The `reason` is loaded from `directive.md` on every invocation and filled with current plan state. The hook returns no output when `stop_hook_active` is `true`, when `last_assistant_message` starts with `<start-work-blocked-external>` (or places it immediately after the mandatory `ULTRAWORK MODE ENABLED!` opener), when no active Boulder work exists, when the work is completed, when the active work is not tied to `codex:<session_id>`, or when the plan has no readable top-level checklist. An active plan whose checklist is fully checked still blocks Stop until the final gate runs and Boulder is marked completed.
|
|
12
|
+
|
|
13
|
+
## External blocker escape hatch
|
|
14
|
+
|
|
15
|
+
A plan can stall on something no amount of retrying fixes: a missing credential, missing hardware, a revoked authorization, an unavailable third-party service. `directive.md` instructs the agent to write `<start-work-blocked-external>` as the entire first line of its answer in that case, or as the entire second line when ultrawork's mandatory opener occupies the first. The hook recognizes those structural forms and lets the turn end so the user can act, instead of continuing the same unchanged external-state check forever. Merely discussing the marker later in an answer still continues the plan.
|
|
12
16
|
|
|
13
17
|
This pairs with the `start-work` skill at `plugin/skills/start-work/SKILL.md`. That skill writes `.omo/boulder.json` with Codex session ids prefixed as `codex:` so the hook can continue only its own active Codex session.
|
|
14
18
|
|
|
@@ -45,7 +45,8 @@ Before completion, satisfy all five `review-work` lanes and a `debugging` runtim
|
|
|
45
45
|
# Stop conditions for THIS turn
|
|
46
46
|
|
|
47
47
|
- A top-level checkbox flipped to `- [x]` after the 5-phase QA gate (Phase 1 read, Phase 2 automated, Phase 3 channel scenario, Phase 4 adversarial-class probing, Phase 5 gate decision). Then the Stop hook will re-evaluate; if more checkboxes remain you will be continued again.
|
|
48
|
-
-
|
|
48
|
+
- A conclusive external blocker only the user or external state can clear (missing hardware, credential, authorization, or an unavailable service) → after ONE authoritative check, stop retrying and stop reviewer dispatch. Write `<start-work-blocked-external>` as the entire first line of your answer, then state the exact blocker and the observable condition that resumes the work. If ultrawork requires `ULTRAWORK MODE ENABLED!` as the first line, put the blocker marker alone on the second line instead. The Stop hook recognizes both forms and lets this turn end.
|
|
49
|
+
- 3 same-failure cycles on one agent-controllable sub-task → escalate via `multi_agent_v1.spawn_agent({"message":"TASK: act as a rigorous reviewer. DELIVERABLE: diagnose the repeated sub-task failure and recommend the next safe action. VERIFY: cite the failing evidence.","fork_context":false})` and stop dispatch.
|
|
49
50
|
- Safety boundary (destructive command, secret exfiltration, production write) → stop and surface a safe substitute.
|
|
50
51
|
- All top-level checkboxes `- [x]` AND the Global Review and Debugging Gate passed → print the ORCHESTRATION COMPLETE block and end.
|
|
51
52
|
|
|
@@ -307,6 +307,8 @@ function runStopHook(input, fs) {
|
|
|
307
307
|
return "";
|
|
308
308
|
if (input.stop_hook_active)
|
|
309
309
|
return "";
|
|
310
|
+
if (hasAllowedExternalBlockerMarker(input.last_assistant_message))
|
|
311
|
+
return "";
|
|
310
312
|
if (transcriptHasContextPressureMarker(input.transcript_path, fs))
|
|
311
313
|
return "";
|
|
312
314
|
const state = readContinuationState(input.cwd, input.session_id);
|
|
@@ -337,6 +339,22 @@ function renderDirective(state, sessionId) {
|
|
|
337
339
|
}
|
|
338
340
|
return rendered;
|
|
339
341
|
}
|
|
342
|
+
var EXTERNAL_BLOCKER_MARKER = "<start-work-blocked-external>";
|
|
343
|
+
var ULTRAWORK_OPENER = "ULTRAWORK MODE ENABLED!";
|
|
344
|
+
function hasAllowedExternalBlockerMarker(lastAssistantMessage) {
|
|
345
|
+
if (lastAssistantMessage === undefined)
|
|
346
|
+
return false;
|
|
347
|
+
const lines = lastAssistantMessage.split(String.fromCharCode(10));
|
|
348
|
+
const [firstLine = "", secondLine = ""] = lines;
|
|
349
|
+
let markerLineIndex = -1;
|
|
350
|
+
if (firstLine.trim() === EXTERNAL_BLOCKER_MARKER)
|
|
351
|
+
markerLineIndex = 0;
|
|
352
|
+
else if (firstLine.trim() === ULTRAWORK_OPENER && secondLine.trim() === EXTERNAL_BLOCKER_MARKER)
|
|
353
|
+
markerLineIndex = 1;
|
|
354
|
+
if (markerLineIndex === -1)
|
|
355
|
+
return false;
|
|
356
|
+
return lines.slice(markerLineIndex + 1).some((line) => line.trim() !== "");
|
|
357
|
+
}
|
|
340
358
|
var CONTEXT_PRESSURE_MARKERS = [
|
|
341
359
|
"context compacted",
|
|
342
360
|
"context_length_exceeded",
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/start-work-continuation/dist/cli.js\" hook stop",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO
|
|
10
|
+
"statusMessage": "(OmO 5.0.0-beta.10) Checking Start-Work Continuation"
|
|
11
11
|
}
|
|
12
12
|
]
|
|
13
13
|
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"type": "command",
|
|
20
20
|
"command": "node \"${PLUGIN_ROOT}/components/start-work-continuation/dist/cli.js\" hook subagent-stop",
|
|
21
21
|
"timeout": 10,
|
|
22
|
-
"statusMessage": "(OmO
|
|
22
|
+
"statusMessage": "(OmO 5.0.0-beta.10) Checking Start-Work Continuation"
|
|
23
23
|
}
|
|
24
24
|
]
|
|
25
25
|
}
|
|
@@ -6,6 +6,7 @@ import type { ReadonlyFileSystem, StopHookEventName, StopHookOutput, StopInput }
|
|
|
6
6
|
export function runStopHook(input: unknown, fs: ReadonlyFileSystem): string {
|
|
7
7
|
if (!isStopInput(input)) return "";
|
|
8
8
|
if (input.stop_hook_active) return "";
|
|
9
|
+
if (hasAllowedExternalBlockerMarker(input.last_assistant_message)) return "";
|
|
9
10
|
if (transcriptHasContextPressureMarker(input.transcript_path, fs)) return "";
|
|
10
11
|
const state = readContinuationState(input.cwd, input.session_id);
|
|
11
12
|
if (state === null) return "";
|
|
@@ -39,6 +40,26 @@ function renderDirective(state: ContinuationState, sessionId: string): string {
|
|
|
39
40
|
return rendered;
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
const EXTERNAL_BLOCKER_MARKER = "<start-work-blocked-external>";
|
|
44
|
+
const ULTRAWORK_OPENER = "ULTRAWORK MODE ENABLED!";
|
|
45
|
+
|
|
46
|
+
// The marker alone is not enough to end the turn. `directive.md` requires the exact blocker and
|
|
47
|
+
// the condition that resumes the work on the following lines, so at least one is required here
|
|
48
|
+
// too. That keeps a bare echo of the marker, whether quoted back from a prompt or produced by
|
|
49
|
+
// untrusted text the agent read, from skipping the continuation guard.
|
|
50
|
+
function hasAllowedExternalBlockerMarker(lastAssistantMessage: string | undefined): boolean {
|
|
51
|
+
if (lastAssistantMessage === undefined) return false;
|
|
52
|
+
const lines = lastAssistantMessage.split(String.fromCharCode(10));
|
|
53
|
+
const [firstLine = "", secondLine = ""] = lines;
|
|
54
|
+
|
|
55
|
+
let markerLineIndex = -1;
|
|
56
|
+
if (firstLine.trim() === EXTERNAL_BLOCKER_MARKER) markerLineIndex = 0;
|
|
57
|
+
else if (firstLine.trim() === ULTRAWORK_OPENER && secondLine.trim() === EXTERNAL_BLOCKER_MARKER) markerLineIndex = 1;
|
|
58
|
+
if (markerLineIndex === -1) return false;
|
|
59
|
+
|
|
60
|
+
return lines.slice(markerLineIndex + 1).some((line) => line.trim() !== "");
|
|
61
|
+
}
|
|
62
|
+
|
|
42
63
|
const CONTEXT_PRESSURE_MARKERS = [
|
|
43
64
|
"context compacted",
|
|
44
65
|
"context_length_exceeded",
|
|
@@ -26,9 +26,6 @@ describe("start-work continuation CLI", () => {
|
|
|
26
26
|
expect(result.status).toBe(0);
|
|
27
27
|
const output = parseStopHookOutput(result.stdout);
|
|
28
28
|
expect(output.decision).toBe("block");
|
|
29
|
-
expect(output.reason).toContain("Remaining top-level checkboxes: `2` of `4`");
|
|
30
|
-
expect(output.reason).toContain("Next incomplete task: `1. Implement checklist parser parity`");
|
|
31
|
-
expect(output.reason).toContain("Your session id in boulder.json: `codex:s1`");
|
|
32
29
|
});
|
|
33
30
|
|
|
34
31
|
it("#given valid SubagentStop stdin #when CLI runs #then stdout contains block JSON", () => {
|
package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts
CHANGED
|
@@ -58,16 +58,112 @@ describe("start-work Stop hook", () => {
|
|
|
58
58
|
const output = runStopHook(createStopInput(workspace), fs);
|
|
59
59
|
|
|
60
60
|
// then
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
expect(parseBlockOutput(output).decision).toBe("block");
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("#given active codex work and an external-blocker marker #when hook runs #then returns empty output", () => {
|
|
65
|
+
// given
|
|
66
|
+
const workspace = createWorkspace({
|
|
67
|
+
boulderJson: createBoulderJson({ sessionIds: ["codex:sess_abc"], status: "active" }),
|
|
68
|
+
planMarkdown: SCAFFOLD_PLAN_MARKDOWN,
|
|
69
|
+
});
|
|
70
|
+
const fs = createMemoryFs();
|
|
71
|
+
const input = {
|
|
72
|
+
...createStopInput(workspace),
|
|
73
|
+
last_assistant_message: [
|
|
74
|
+
"<start-work-blocked-external>",
|
|
75
|
+
"Blocker: the staging deploy credential is missing.",
|
|
76
|
+
"Resume when a valid credential is provisioned.",
|
|
77
|
+
].join("\n"),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// when
|
|
81
|
+
const output = runStopHook(input, fs);
|
|
82
|
+
|
|
83
|
+
// then
|
|
84
|
+
expect(output).toBe("");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("#given ultrawork opener then external-blocker marker #when hook runs #then returns empty output", () => {
|
|
88
|
+
// given
|
|
89
|
+
const workspace = createWorkspace({
|
|
90
|
+
boulderJson: createBoulderJson({ sessionIds: ["codex:sess_abc"], status: "active" }),
|
|
91
|
+
planMarkdown: SCAFFOLD_PLAN_MARKDOWN,
|
|
92
|
+
});
|
|
93
|
+
const fs = createMemoryFs();
|
|
94
|
+
const input = {
|
|
95
|
+
...createStopInput(workspace),
|
|
96
|
+
last_assistant_message: [
|
|
97
|
+
"ULTRAWORK MODE ENABLED!",
|
|
98
|
+
"<start-work-blocked-external>",
|
|
99
|
+
"Blocker: the staging deploy credential is missing.",
|
|
100
|
+
].join("\n"),
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// when
|
|
104
|
+
const output = runStopHook(input, fs);
|
|
105
|
+
|
|
106
|
+
// then
|
|
107
|
+
expect(output).toBe("");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("#given the external-blocker marker with no stated blocker #when hook runs #then still returns block JSON", () => {
|
|
111
|
+
// given: a bare marker, which is what a quoted echo or untrusted text would produce.
|
|
112
|
+
// directive.md requires the blocker and the resume condition, so the marker alone must not
|
|
113
|
+
// skip the continuation guard.
|
|
114
|
+
const workspace = createWorkspace({
|
|
115
|
+
boulderJson: createBoulderJson({ sessionIds: ["codex:sess_abc"], status: "active" }),
|
|
116
|
+
planMarkdown: SCAFFOLD_PLAN_MARKDOWN,
|
|
117
|
+
});
|
|
118
|
+
const fs = createMemoryFs();
|
|
119
|
+
const input = {
|
|
120
|
+
...createStopInput(workspace),
|
|
121
|
+
last_assistant_message: "<start-work-blocked-external>",
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// when
|
|
125
|
+
const output = runStopHook(input, fs);
|
|
126
|
+
|
|
127
|
+
// then
|
|
128
|
+
expect(output).not.toBe("");
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it("#given the ultrawork opener and a bare marker #when hook runs #then still returns block JSON", () => {
|
|
132
|
+
// given
|
|
133
|
+
const workspace = createWorkspace({
|
|
134
|
+
boulderJson: createBoulderJson({ sessionIds: ["codex:sess_abc"], status: "active" }),
|
|
135
|
+
planMarkdown: SCAFFOLD_PLAN_MARKDOWN,
|
|
136
|
+
});
|
|
137
|
+
const fs = createMemoryFs();
|
|
138
|
+
const input = {
|
|
139
|
+
...createStopInput(workspace),
|
|
140
|
+
last_assistant_message: ["ULTRAWORK MODE ENABLED!", "<start-work-blocked-external>", " "].join("\n"),
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// when
|
|
144
|
+
const output = runStopHook(input, fs);
|
|
145
|
+
|
|
146
|
+
// then
|
|
147
|
+
expect(output).not.toBe("");
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("#given the external-blocker marker below the first line #when hook runs #then still returns block JSON", () => {
|
|
151
|
+
// given
|
|
152
|
+
const workspace = createWorkspace({
|
|
153
|
+
boulderJson: createBoulderJson({ sessionIds: ["codex:sess_abc"], status: "active" }),
|
|
154
|
+
planMarkdown: SCAFFOLD_PLAN_MARKDOWN,
|
|
155
|
+
});
|
|
156
|
+
const fs = createMemoryFs();
|
|
157
|
+
const input = {
|
|
158
|
+
...createStopInput(workspace),
|
|
159
|
+
last_assistant_message: ["Next turn I may need to emit", "<start-work-blocked-external>"].join("\n"),
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// when
|
|
163
|
+
const output = runStopHook(input, fs);
|
|
164
|
+
|
|
165
|
+
// then
|
|
166
|
+
expect(parseBlockOutput(output).decision).toBe("block");
|
|
71
167
|
});
|
|
72
168
|
|
|
73
169
|
it("#given active codex work with zero remaining tasks #when hook runs #then blocks for the final gate", () => {
|
|
@@ -82,12 +178,7 @@ describe("start-work Stop hook", () => {
|
|
|
82
178
|
const output = runStopHook(createStopInput(workspace), fs);
|
|
83
179
|
|
|
84
180
|
// then
|
|
85
|
-
|
|
86
|
-
expect(parsed.decision).toBe("block");
|
|
87
|
-
expect(parsed.reason).toContain("- Remaining top-level checkboxes: `0` of `1`");
|
|
88
|
-
expect(parsed.reason).toContain("- Next incomplete task: `none (final gate pending)`");
|
|
89
|
-
expect(parsed.reason).toContain("When the remaining count is `0`, skip checkbox execution");
|
|
90
|
-
expect(parsed.reason).toContain("re-read the ledger record and verify the exact lane/SHA pair");
|
|
181
|
+
expect(parseBlockOutput(output).decision).toBe("block");
|
|
91
182
|
});
|
|
92
183
|
|
|
93
184
|
it("#given context-window pressure in transcript #when hook runs #then it does not inject continuation text", () => {
|
|
@@ -29,9 +29,7 @@ describe("thread title PostToolUse guidance", () => {
|
|
|
29
29
|
expect(isHookOutput(parsed)).toBe(true);
|
|
30
30
|
if (!isHookOutput(parsed)) return;
|
|
31
31
|
expect(parsed.hookSpecificOutput.hookEventName).toBe("PostToolUse");
|
|
32
|
-
expect(parsed.hookSpecificOutput.additionalContext).
|
|
33
|
-
"THREAD ID thread-123: CALL codex_app.set_thread_title NOW. USE THE REAL TASK/ROLE.",
|
|
34
|
-
);
|
|
32
|
+
expect(parsed.hookSpecificOutput.additionalContext).toContain("thread-123");
|
|
35
33
|
});
|
|
36
34
|
|
|
37
35
|
it("#given Codex reports create_thread output as a JSON string #when the hook runs #then it still extracts the thread id", () => {
|
|
@@ -59,9 +57,7 @@ describe("thread title PostToolUse guidance", () => {
|
|
|
59
57
|
// then
|
|
60
58
|
expect(isHookOutput(parsed)).toBe(true);
|
|
61
59
|
if (!isHookOutput(parsed)) return;
|
|
62
|
-
expect(parsed.hookSpecificOutput.additionalContext).
|
|
63
|
-
"THREAD ID 019ef350-ee78-72a3-bd5e-e40cebc3d814: CALL codex_app.set_thread_title NOW. USE THE REAL TASK/ROLE.",
|
|
64
|
-
);
|
|
60
|
+
expect(parsed.hookSpecificOutput.additionalContext).toContain("019ef350-ee78-72a3-bd5e-e40cebc3d814");
|
|
65
61
|
});
|
|
66
62
|
|
|
67
63
|
it("#given an unrelated tool completed #when the hook runs #then it stays silent", () => {
|
|
@@ -141,9 +137,7 @@ describe("thread title PostToolUse guidance", () => {
|
|
|
141
137
|
// then
|
|
142
138
|
expect(isHookOutput(parsed)).toBe(true);
|
|
143
139
|
if (!isHookOutput(parsed)) return;
|
|
144
|
-
expect(parsed.hookSpecificOutput.additionalContext).
|
|
145
|
-
"PENDING WORKTREE ID remote-control:env:test-worktree: WORKTREE THREAD IS NOT READY YET. DO NOT bind-thread OR SEND THE MEMBER BOOTSTRAP UNTIL A REAL THREAD ID EXISTS. THEN CALL codex_app.set_thread_title USING THE REAL TASK/ROLE.",
|
|
146
|
-
);
|
|
140
|
+
expect(parsed.hookSpecificOutput.additionalContext).toContain("remote-control:env:test-worktree");
|
|
147
141
|
});
|
|
148
142
|
});
|
|
149
143
|
|
|
@@ -174,6 +174,7 @@ function writePostHogActivityState(stateDir, nextState, diagnostics) {
|
|
|
174
174
|
// ../../telemetry-core/src/constants.ts
|
|
175
175
|
var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com";
|
|
176
176
|
var DEFAULT_POSTHOG_API_KEY = "phc_CFJhj5HyvA62QPhvyaUCtaq23aUfznnijg5VaaGkNk74";
|
|
177
|
+
var UNCONFIGURED_POSTHOG_API_KEY = "phc_REPLACE_ME_OMO_NATIVE";
|
|
177
178
|
|
|
178
179
|
// ../../telemetry-core/src/diagnostics.ts
|
|
179
180
|
import { appendFileSync, existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
@@ -310,6 +311,9 @@ function shouldDisableTelemetry(input) {
|
|
|
310
311
|
const env = input.env ?? process.env;
|
|
311
312
|
const globalPrefix = input.globalEnvPrefix ?? "OMO";
|
|
312
313
|
const prefixes = Array.from(new Set([globalPrefix, input.productEnvPrefix]));
|
|
314
|
+
if (isDisableFlag(env["DO_NOT_TRACK"])) {
|
|
315
|
+
return true;
|
|
316
|
+
}
|
|
313
317
|
for (const prefix of prefixes) {
|
|
314
318
|
if (isDisableFlag(env[`${prefix}_DISABLE_POSTHOG`])) {
|
|
315
319
|
return true;
|
|
@@ -323,18 +327,15 @@ function shouldDisableTelemetry(input) {
|
|
|
323
327
|
function getTelemetryApiKey(env = process.env, defaultApiKey = DEFAULT_POSTHOG_API_KEY) {
|
|
324
328
|
return env["POSTHOG_API_KEY"]?.trim() ?? defaultApiKey;
|
|
325
329
|
}
|
|
326
|
-
function
|
|
327
|
-
|
|
330
|
+
function isConfiguredTelemetryApiKey(apiKey) {
|
|
331
|
+
const normalized = apiKey.trim();
|
|
332
|
+
return normalized.length > 0 && normalized !== UNCONFIGURED_POSTHOG_API_KEY;
|
|
328
333
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
import { createHash } from "node:crypto";
|
|
332
|
-
import os2 from "node:os";
|
|
333
|
-
function getDefaultTelemetryOsProvider() {
|
|
334
|
-
return os2;
|
|
334
|
+
function hasTelemetryApiKey(env, defaultApiKey) {
|
|
335
|
+
return isConfiguredTelemetryApiKey(getTelemetryApiKey(env, defaultApiKey));
|
|
335
336
|
}
|
|
336
|
-
function
|
|
337
|
-
return
|
|
337
|
+
function getTelemetryHost(env = process.env, defaultHost = DEFAULT_POSTHOG_HOST) {
|
|
338
|
+
return env["POSTHOG_HOST"]?.trim() || defaultHost;
|
|
338
339
|
}
|
|
339
340
|
|
|
340
341
|
// ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
@@ -5504,6 +5505,16 @@ class PostHog extends PostHogBackendClient {
|
|
|
5504
5505
|
}
|
|
5505
5506
|
}
|
|
5506
5507
|
|
|
5508
|
+
// ../../telemetry-core/src/machine-id.ts
|
|
5509
|
+
import { createHash } from "node:crypto";
|
|
5510
|
+
import os2 from "node:os";
|
|
5511
|
+
function getDefaultTelemetryOsProvider() {
|
|
5512
|
+
return os2;
|
|
5513
|
+
}
|
|
5514
|
+
function getTelemetryDistinctId(machineIdPrefix, osProvider = getDefaultTelemetryOsProvider()) {
|
|
5515
|
+
return createHash("sha256").update(`${machineIdPrefix}${osProvider.hostname()}`).digest("hex");
|
|
5516
|
+
}
|
|
5517
|
+
|
|
5507
5518
|
// ../../telemetry-core/src/posthog-client.ts
|
|
5508
5519
|
var NO_OP_CLIENT = {
|
|
5509
5520
|
enabled: false,
|
|
@@ -5538,7 +5549,7 @@ function createDefaultPostHogTransport(apiKey, options) {
|
|
|
5538
5549
|
}
|
|
5539
5550
|
function isTelemetryClientEnabled(input) {
|
|
5540
5551
|
const env = input.env ?? process.env;
|
|
5541
|
-
return !shouldDisableTelemetry({ env, productEnvPrefix: input.product.productEnvPrefix }) &&
|
|
5552
|
+
return !shouldDisableTelemetry({ env, productEnvPrefix: input.product.productEnvPrefix }) && hasTelemetryApiKey(env, input.product.defaultApiKey);
|
|
5542
5553
|
}
|
|
5543
5554
|
function createTelemetryClient(input) {
|
|
5544
5555
|
if (!isTelemetryClientEnabled(input)) {
|
|
@@ -5604,7 +5615,8 @@ function createTransport(input) {
|
|
|
5604
5615
|
flushAt: 1,
|
|
5605
5616
|
flushInterval: 0,
|
|
5606
5617
|
host: getTelemetryHost(env, input.product.defaultHost),
|
|
5607
|
-
disableGeoip: false
|
|
5618
|
+
disableGeoip: input.product.disableGeoip ?? false,
|
|
5619
|
+
...input.product.transportOptions
|
|
5608
5620
|
});
|
|
5609
5621
|
} catch (error) {
|
|
5610
5622
|
input.diagnostics?.({
|
|
@@ -170,6 +170,7 @@ function writePostHogActivityState(stateDir, nextState, diagnostics) {
|
|
|
170
170
|
// ../../../../telemetry-core/src/constants.ts
|
|
171
171
|
var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com";
|
|
172
172
|
var DEFAULT_POSTHOG_API_KEY = "phc_CFJhj5HyvA62QPhvyaUCtaq23aUfznnijg5VaaGkNk74";
|
|
173
|
+
var UNCONFIGURED_POSTHOG_API_KEY = "phc_REPLACE_ME_OMO_NATIVE";
|
|
173
174
|
|
|
174
175
|
// ../../../../telemetry-core/src/diagnostics.ts
|
|
175
176
|
import { appendFileSync, existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
@@ -306,6 +307,9 @@ function shouldDisableTelemetry(input) {
|
|
|
306
307
|
const env = input.env ?? process.env;
|
|
307
308
|
const globalPrefix = input.globalEnvPrefix ?? "OMO";
|
|
308
309
|
const prefixes = Array.from(new Set([globalPrefix, input.productEnvPrefix]));
|
|
310
|
+
if (isDisableFlag(env["DO_NOT_TRACK"])) {
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
309
313
|
for (const prefix of prefixes) {
|
|
310
314
|
if (isDisableFlag(env[`${prefix}_DISABLE_POSTHOG`])) {
|
|
311
315
|
return true;
|
|
@@ -319,18 +323,15 @@ function shouldDisableTelemetry(input) {
|
|
|
319
323
|
function getTelemetryApiKey(env = process.env, defaultApiKey = DEFAULT_POSTHOG_API_KEY) {
|
|
320
324
|
return env["POSTHOG_API_KEY"]?.trim() ?? defaultApiKey;
|
|
321
325
|
}
|
|
322
|
-
function
|
|
323
|
-
|
|
326
|
+
function isConfiguredTelemetryApiKey(apiKey) {
|
|
327
|
+
const normalized = apiKey.trim();
|
|
328
|
+
return normalized.length > 0 && normalized !== UNCONFIGURED_POSTHOG_API_KEY;
|
|
324
329
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
import { createHash } from "node:crypto";
|
|
328
|
-
import os2 from "node:os";
|
|
329
|
-
function getDefaultTelemetryOsProvider() {
|
|
330
|
-
return os2;
|
|
330
|
+
function hasTelemetryApiKey(env, defaultApiKey) {
|
|
331
|
+
return isConfiguredTelemetryApiKey(getTelemetryApiKey(env, defaultApiKey));
|
|
331
332
|
}
|
|
332
|
-
function
|
|
333
|
-
return
|
|
333
|
+
function getTelemetryHost(env = process.env, defaultHost = DEFAULT_POSTHOG_HOST) {
|
|
334
|
+
return env["POSTHOG_HOST"]?.trim() || defaultHost;
|
|
334
335
|
}
|
|
335
336
|
|
|
336
337
|
// ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
@@ -5500,6 +5501,16 @@ class PostHog extends PostHogBackendClient {
|
|
|
5500
5501
|
}
|
|
5501
5502
|
}
|
|
5502
5503
|
|
|
5504
|
+
// ../../../../telemetry-core/src/machine-id.ts
|
|
5505
|
+
import { createHash } from "node:crypto";
|
|
5506
|
+
import os2 from "node:os";
|
|
5507
|
+
function getDefaultTelemetryOsProvider() {
|
|
5508
|
+
return os2;
|
|
5509
|
+
}
|
|
5510
|
+
function getTelemetryDistinctId(machineIdPrefix, osProvider = getDefaultTelemetryOsProvider()) {
|
|
5511
|
+
return createHash("sha256").update(`${machineIdPrefix}${osProvider.hostname()}`).digest("hex");
|
|
5512
|
+
}
|
|
5513
|
+
|
|
5503
5514
|
// ../../../../telemetry-core/src/posthog-client.ts
|
|
5504
5515
|
var NO_OP_CLIENT = {
|
|
5505
5516
|
enabled: false,
|
|
@@ -5534,7 +5545,7 @@ function createDefaultPostHogTransport(apiKey, options) {
|
|
|
5534
5545
|
}
|
|
5535
5546
|
function isTelemetryClientEnabled(input) {
|
|
5536
5547
|
const env = input.env ?? process.env;
|
|
5537
|
-
return !shouldDisableTelemetry({ env, productEnvPrefix: input.product.productEnvPrefix }) &&
|
|
5548
|
+
return !shouldDisableTelemetry({ env, productEnvPrefix: input.product.productEnvPrefix }) && hasTelemetryApiKey(env, input.product.defaultApiKey);
|
|
5538
5549
|
}
|
|
5539
5550
|
function createTelemetryClient(input) {
|
|
5540
5551
|
if (!isTelemetryClientEnabled(input)) {
|
|
@@ -5600,7 +5611,8 @@ function createTransport(input) {
|
|
|
5600
5611
|
flushAt: 1,
|
|
5601
5612
|
flushInterval: 0,
|
|
5602
5613
|
host: getTelemetryHost(env, input.product.defaultHost),
|
|
5603
|
-
disableGeoip: false
|
|
5614
|
+
disableGeoip: input.product.disableGeoip ?? false,
|
|
5615
|
+
...input.product.transportOptions
|
|
5604
5616
|
});
|
|
5605
5617
|
} catch (error) {
|
|
5606
5618
|
input.diagnostics?.({
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Scenario contract is now sized to the change (1-2 scenarios for small single-surface work, 3+ for risky or multi-surface work), and each scenario names the cheapest faithful proof: a test file + test id at a code seam, or the real-surface scenario itself when no seam exists. "Tests are the FLOOR (always required)" is gone — prose, docs, prompt, and visual-only changes take review + real-surface QA, and a test pinning their text is called out as pretend-coverage. The TDD sections across `prompts-core` ultrawork variants (default/gpt/gemini/glm) are scoped to production code changes with a test seam, and the execution-loop PIN step now asks for characterization pins only when refactoring behavior whose regressions the change could hide. Driver: the 2026-08-03 session-corpus investigation that traced contract-test sprawl (22 tests for an HTML/CSS profile page, prose contract tests on docs) to the always-required test floor. `directive.md` re-synced from `prompts-core/ultrawork/codex.md`; 26,555 chars across 470 lines.
|
|
6
|
+
|
|
5
7
|
- The `ulw`/`ultrawork` trigger now injects a compact bootstrap pointer instead of the full directive: it mandates the `ULTRAWORK MODE ENABLED!` opener, an immediate `create_goal` call with `objective` only, and reading the full directive from the bundled `ultrawork` skill at a runtime-resolved absolute path. Codex App truncates large hook outputs (head plus tail, middle omitted), which silently dropped the `create_goal` bootstrap since v4.14.1; the pointer stays far below the truncation budget so no part of it can be lost (fixes code-yeongyu/oh-my-openagent#5828). When the plugin skills tree is absent (standalone component installs), the hook falls back to emitting the full directive.
|
|
6
8
|
- New `skills/ultrawork/SKILL.md` carries the complete directive body behind skill frontmatter and is regenerated from `@oh-my-opencode/prompts-core` by `scripts/sync-directive.mjs`; `directive-source.test.ts` pins the skill body to `directive.md` byte for byte.
|
|
7
9
|
- Runtime hook migrated from `python3 hooks/ultrawork-detector.py` to the component-standard TypeScript build output `node dist/cli.js hook user-prompt-submit`, removing the Codex runtime dependency on Python.
|
|
@@ -17,7 +17,7 @@ Before judging test relevance or maintainability, explicitly load or consult the
|
|
|
17
17
|
|
|
18
18
|
Run the `remove-ai-slops` overfit/slop review pass over tests and production code. Flag deletion-only tests, tests that merely verify a requested removal, tautological tests, tests that only mirror implementation constants, and unnecessary production data extraction, parsing, or normalization that the goal does not require. Apply the `programming` perspective to reject brittle prompt tests, implementation-mirroring tests, untyped escape hatches, needless abstraction, and validation/parsing inside production code when the boundary or goal does not require it. Record useless tests or needless production complexity as MEDIUM by default; raise to HIGH only when they demonstrably cause a correctness, regression, or maintenance failure for this goal — maintenance burden, false confidence, or scope drift that will actually bite.
|
|
19
19
|
|
|
20
|
-
Write your report artifact to `<attemptDir>/<goalId>-code-review.md`, where you read `currentAttemptDir` from `omo ulw-loop status --json` (`.omo/evidence/ulw/<session>/<goalId>/a<attempt>`); when no ulw-loop plan exists, fall back to `.omo/evidence/<goal>-code-review.md`. The report must include findings by severity: CRITICAL, HIGH, MEDIUM, LOW. Include file and line references when a finding is tied to code.
|
|
20
|
+
Write your report artifact to `<attemptDir>/<goalId>-code-review.md`, where you read `currentAttemptDir` from `omo-agent-toolkit ulw-loop status --json` (`.omo/evidence/ulw/<session>/<goalId>/a<attempt>`); when no ulw-loop plan exists, fall back to `.omo/evidence/<goal>-code-review.md`. The report must include findings by severity: CRITICAL, HIGH, MEDIUM, LOW. Include file and line references when a finding is tied to code.
|
|
21
21
|
|
|
22
22
|
Return:
|
|
23
23
|
- `codeQualityStatus`: CLEAR, WATCH, or BLOCK.
|
|
@@ -15,7 +15,7 @@ Review from the user's perspective: infer what the user originally wanted, what
|
|
|
15
15
|
|
|
16
16
|
Before approval, load or consult `remove-ai-slops` and `programming` when available. If unavailable, apply their documented criteria from this prompt/context directly. Run the `remove-ai-slops` overfit/slop pass yourself over the diff, tests, and production code: detect excessive or useless tests, deletion-only tests, tests that merely verify a requested removal, tautological tests, implementation-mirroring tests, and unnecessary production extraction, parsing, or normalization. Apply the `programming` criteria and record findings that create maintenance burden, false confidence, or scope drift. Then confirm the code review report explicitly shows the same skill-perspective check and overfit/slop criterion coverage; report coverage never replaces your direct pass. A finding blocks only when it violates a stated success criterion. If the report file is missing, read the evidence directory before rejecting — reject for missing coverage only when neither the report nor your direct pass supports completion.
|
|
17
17
|
|
|
18
|
-
Write your report artifact to `<attemptDir>/<goalId>-gate-review.md`, where you read `currentAttemptDir` from `omo ulw-loop status --json` (`.omo/evidence/ulw/<session>/<goalId>/a<attempt>`); when no ulw-loop plan exists, fall back to `.omo/evidence/<goal>-gate-review.md`. Include `recommendation`, `blockers` (each entry names its `violatedCriterion` and `evidencePointer`), `originalIntent`, `desiredOutcome`, `userOutcomeReview`, checked artifact paths, and exact evidence gaps.
|
|
18
|
+
Write your report artifact to `<attemptDir>/<goalId>-gate-review.md`, where you read `currentAttemptDir` from `omo-agent-toolkit ulw-loop status --json` (`.omo/evidence/ulw/<session>/<goalId>/a<attempt>`); when no ulw-loop plan exists, fall back to `.omo/evidence/<goal>-gate-review.md`. Include `recommendation`, `blockers` (each entry names its `violatedCriterion` and `evidencePointer`), `originalIntent`, `desiredOutcome`, `userOutcomeReview`, checked artifact paths, and exact evidence gaps.
|
|
19
19
|
|
|
20
20
|
Return the recommendation (APPROVE/REJECT) AND, on REJECT, the top blockers inline in your final message — each with its violated criterion id, a one-line observation, and an evidence pointer. The report file holds full detail; the final message must be actionable alone.
|
|
21
21
|
|
|
@@ -18,5 +18,5 @@ Produce a `manualQa` matrix with:
|
|
|
18
18
|
|
|
19
19
|
Run real scenarios. Reject skipped, inferred, and partial cases. Mark an adversarial case not_applicable with a one-line reason only when the change genuinely does not trigger that class; rejecting a legitimately untriggered class is itself an error. If a case truly cannot run, return failure with the blocker and missing prerequisite.
|
|
20
20
|
|
|
21
|
-
Write artifacts under the current attempt directory: read `currentAttemptDir` from `omo ulw-loop status --json` (`.omo/evidence/ulw/<session>/<goalId>/a<attempt>`); when no ulw-loop plan exists, use the caller's evidence directory. Write the QA matrix itself to `<attemptDir>/<goalId>-manual-qa.md`. Every PASS must point to a non-empty artifact.
|
|
21
|
+
Write artifacts under the current attempt directory: read `currentAttemptDir` from `omo-agent-toolkit ulw-loop status --json` (`.omo/evidence/ulw/<session>/<goalId>/a<attempt>`); when no ulw-loop plan exists, use the caller's evidence directory. Write the QA matrix itself to `<attemptDir>/<goalId>-manual-qa.md`. Every PASS must point to a non-empty artifact.
|
|
22
22
|
"""
|