oh-my-opencode 4.16.2 → 4.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/command/omomomo.md +1 -1
- package/.agents/skills/hyperplan/SKILL.md +3 -3
- package/.agents/skills/omomomo/SKILL.md +1 -1
- package/.agents/skills/pre-publish-review/SKILL.md +3 -0
- package/.opencode/command/omomomo.md +1 -1
- package/.opencode/skills/hyperplan/SKILL.md +3 -3
- package/.opencode/skills/pre-publish-review/SKILL.md +3 -0
- package/README.ja.md +4 -4
- package/README.ko.md +4 -4
- package/README.md +4 -4
- package/README.ru.md +4 -4
- package/README.zh-cn.md +4 -4
- package/dist/agents/hephaestus/agent.d.ts +1 -1
- package/dist/agents/hephaestus/gpt-5-6.d.ts +2 -0
- package/dist/agents/momus-gpt-5-6.d.ts +1 -0
- package/dist/agents/types.d.ts +2 -0
- package/dist/cli/index.js +947 -567
- package/dist/cli-node/index.js +947 -567
- package/dist/features/background-agent/error-classifier.d.ts +5 -0
- package/dist/features/builtin-commands/templates/refactor-sections/intro-and-analysis.d.ts +1 -1
- package/dist/features/builtin-commands/templates/remove-ai-slops.d.ts +1 -1
- package/dist/features/team-mode/test-support/async-test-helpers.d.ts +2 -2
- package/dist/index.js +523 -81
- package/dist/plugin/chat-message/types.d.ts +4 -0
- package/dist/plugin/command-execute-before.d.ts +1 -0
- package/dist/plugin/stop-continuation.d.ts +17 -0
- package/dist/shared/live-server-route.d.ts +1 -1
- package/dist/skills/remove-ai-slops/SKILL.md +2 -2
- package/dist/skills/review-work/SKILL.md +1 -1
- package/dist/skills/start-work/SKILL.md +5 -2
- package/dist/skills/ulw-plan/references/full-workflow.md +1 -1
- package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -2
- package/dist/skills/ulw-research/SKILL.md +2 -2
- package/dist/skills/visual-qa/SKILL.md +1 -1
- package/dist/tui.js +195 -41
- package/package.json +15 -14
- package/packages/git-bash-mcp/package.json +27 -0
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +3 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +465 -248
- 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/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/AGENTS.md +2 -2
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +6 -2
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +6 -2
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +6 -2
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/cli.test.ts +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +67 -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/lsp/test/package-smoke.test.ts +0 -13
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.6.md +93 -0
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +43 -24
- 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/src/codex-hook.ts +2 -1
- package/packages/omo-codex/plugin/components/rules/src/dynamic-target-fingerprints.ts +15 -6
- package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +7 -2
- package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +2 -2
- package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +32 -0
- package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +106 -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/test/codex-hook.test.ts +1 -79
- package/packages/omo-codex/plugin/components/teammode/AGENTS.md +12 -9
- 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/skills/teammode/SKILL.md +136 -76
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +94 -23
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +94 -14
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-transport.mjs +55 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +72 -18
- package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +23 -0
- 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/agents/explorer.toml +23 -40
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +3 -3
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +7 -7
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +5 -5
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +26 -0
- package/packages/omo-codex/plugin/components/ultrawork/agents/{lazycodex-executor.toml → lazycodex-worker-low.toml} +7 -5
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +26 -0
- package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +20 -48
- package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +17 -29
- package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +20 -50
- package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +22 -43
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +55 -28
- 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 +55 -28
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +22 -0
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +0 -68
- 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 +3 -1
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +55 -28
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +6 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +13 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +405 -25
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +12 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +7 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +16 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.d.ts +6 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +20 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +12 -9
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.d.ts +3 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +148 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +209 -0
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +25 -2
- 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 +14 -15
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +29 -27
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +6 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +14 -3
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +10 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +12 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +27 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +23 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +16 -9
- package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +138 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +208 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +12 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +4 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +8 -35
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +24 -13
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +43 -8
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +55 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +228 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +193 -0
- 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 +18 -0
- 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 +17 -0
- 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 +2 -2
- 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/model-catalog.json +16 -7
- package/packages/omo-codex/plugin/package-lock.json +13 -13
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +9 -2
- package/packages/omo-codex/plugin/scripts/entry-guard.mjs +26 -0
- package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +3 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +16 -7
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +39 -4
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +24 -4
- package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +3 -3
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +2 -2
- package/packages/omo-codex/plugin/scripts/sync-hook-status-messages.mjs +2 -2
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +14 -6
- package/packages/omo-codex/plugin/scripts/sync-version.mjs +4 -2
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +3 -3
- package/packages/omo-codex/plugin/skills/refactor/SKILL.md +3 -3
- package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +5 -5
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +9 -3
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +6 -3
- package/packages/omo-codex/plugin/skills/teammode/SKILL.md +136 -76
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +94 -23
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +94 -14
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-transport.mjs +55 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +72 -18
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +55 -28
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +14 -15
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +29 -27
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -2
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +4 -4
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +4 -4
- package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +116 -10
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +23 -2
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +4 -4
- package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +4 -2
- package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +33 -0
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +4 -4
- package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
- package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +4 -101
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +160 -23
- package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +71 -0
- package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +32 -0
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +20 -2
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +1 -1
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +4 -2
- package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +345 -0
- package/packages/omo-codex/plugin/test/ulw-plan-skill-contract.test.mjs +9 -40
- package/packages/omo-codex/plugin/test/ulw-research-skill-contract.test.mjs +4 -277
- package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +5 -5
- package/packages/omo-codex/scripts/install-config.test.mjs +22 -3
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +508 -286
- package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +111 -1
- package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +2 -2
- package/packages/shared-skills/skills/review-work/SKILL.md +1 -1
- package/packages/shared-skills/skills/start-work/SKILL.md +5 -2
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +2 -2
- package/packages/shared-skills/skills/ulw-research/SKILL.md +2 -2
- package/packages/shared-skills/skills/visual-qa/SKILL.md +1 -1
- package/dist/skills/visual-qa/scripts/skill-prompt-contract.test.ts +0 -296
- package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +0 -70
- package/packages/omo-codex/plugin/test/ulw-research-epistemic-contract.test.mjs +0 -98
- package/packages/shared-skills/skills/visual-qa/scripts/skill-prompt-contract.test.ts +0 -296
- /package/packages/omo-codex/plugin/components/rules/bundled-rules/{hephaestus.md → hephaestus/gpt-5.5.md} +0 -0
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/components/bootstrap/dist/cli.js\" hook session-start",
|
|
9
9
|
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\bootstrap.ps1\"",
|
|
10
10
|
"timeout": 30,
|
|
11
|
-
"statusMessage": "(OmO 4.
|
|
11
|
+
"statusMessage": "(OmO 4.17.0) Checking Bootstrap Provisioning"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook pre-tool-use",
|
|
10
10
|
"timeout": 5,
|
|
11
|
-
"statusMessage": "(OmO 4.
|
|
11
|
+
"statusMessage": "(OmO 4.17.0) Recommending Git Bash MCP"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"type": "command",
|
|
21
21
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
|
|
22
22
|
"timeout": 5,
|
|
23
|
-
"statusMessage": "(OmO 4.
|
|
23
|
+
"statusMessage": "(OmO 4.17.0) Resetting Git Bash MCP Reminder"
|
|
24
24
|
}
|
|
25
25
|
]
|
|
26
26
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## OVERVIEW
|
|
6
6
|
|
|
7
|
-
Codex `SubagentStop` hook component: the evidence gate for the `lazycodex-
|
|
7
|
+
Codex `SubagentStop` hook component: the evidence gate for the ultrawork implementation workers (`lazycodex-worker-low|medium|high`). When a worker stops without a valid evidence receipt, the hook emits `{"decision": "block", "reason": <directive>}` and Codex sends it back to work. Matcher is `^lazycodex-worker-(low|medium|high)$`; read-only roles like `lazycodex-qa-executor` and `lazycodex-gate-reviewer` (same `ultrawork/agents/` family) are NOT gated by this hook. (The historical `lazycodex-executor` agent was removed; this component keeps its name.)
|
|
8
8
|
|
|
9
9
|
Valid receipt: `last_assistant_message` contains `EVIDENCE_RECORDED: <path>` where `<path>` resolves to a non-empty regular file strictly inside `<cwd>/.omo/evidence/`. Symlinks and directories rejected; containment checked on realpaths (file inside evidence root inside cwd, traversal-safe). A valid receipt clears attempt state and exits silently.
|
|
10
10
|
|
|
@@ -30,7 +30,7 @@ Escape hatches: after 3 blocked attempts (`MAX_ATTEMPTS`) the stop passes and st
|
|
|
30
30
|
| Change the block message | `directive.md`; keep both `{{...}}` placeholders and the literal `EVIDENCE_RECORDED: <path>` final-line contract |
|
|
31
31
|
| Change receipt validation | `src/codex-hook.ts` (`hasValidEvidenceReceipt`, `extractEvidencePath`, `isNonEmptyFileInsideEvidenceRoot`) |
|
|
32
32
|
| Change the retry budget | `src/state.ts` `MAX_ATTEMPTS` |
|
|
33
|
-
|
|
|
33
|
+
| Worker-side contract | `../ultrawork/agents/lazycodex-worker-{low,medium,high}.toml` instruct the final `EVIDENCE_RECORDED: <path>` line this hook parses |
|
|
34
34
|
| Plugin-level wiring | `../../hooks/subagent-stop-verifying-lazycodex-executor-evidence.json` (adds `commandWindows` via `../bootstrap/scripts/node-dispatch.ps1`) |
|
|
35
35
|
| Wiring + contract tests | `../../test/aggregate-hooks.test.mjs`, `../../test/component-hook-contract-cases.mjs`, `../../test/hook-status-message.test.mjs`, `../../test/component-bundled-cli.test.mjs` |
|
|
36
36
|
|
|
@@ -66,11 +66,15 @@ function isRecord(value) {
|
|
|
66
66
|
var SUBAGENT_STOP_EVENT = "SubagentStop";
|
|
67
67
|
|
|
68
68
|
// components/lazycodex-executor-verify/src/codex-hook.ts
|
|
69
|
-
var
|
|
69
|
+
var RECEIPT_ENFORCED_AGENTS = new Set([
|
|
70
|
+
"lazycodex-worker-low",
|
|
71
|
+
"lazycodex-worker-medium",
|
|
72
|
+
"lazycodex-worker-high"
|
|
73
|
+
]);
|
|
70
74
|
function runSubagentStopHook(input, fs) {
|
|
71
75
|
if (!isSubagentStopInput(input))
|
|
72
76
|
return "";
|
|
73
|
-
if (input.agent_type
|
|
77
|
+
if (!RECEIPT_ENFORCED_AGENTS.has(input.agent_type))
|
|
74
78
|
return "";
|
|
75
79
|
if (transcriptHasContextPressureMarker(input.transcript_path, fs))
|
|
76
80
|
return "";
|
|
@@ -3,11 +3,15 @@ import { isAbsolute, relative, resolve } from "node:path";
|
|
|
3
3
|
import { renderDirective } from "./directive.js";
|
|
4
4
|
import { clearAttemptState, MAX_ATTEMPTS, readAttemptState, writeAttemptState } from "./state.js";
|
|
5
5
|
import { SUBAGENT_STOP_EVENT } from "./types.js";
|
|
6
|
-
const
|
|
6
|
+
const RECEIPT_ENFORCED_AGENTS = new Set([
|
|
7
|
+
"lazycodex-worker-low",
|
|
8
|
+
"lazycodex-worker-medium",
|
|
9
|
+
"lazycodex-worker-high",
|
|
10
|
+
]);
|
|
7
11
|
export function runSubagentStopHook(input, fs) {
|
|
8
12
|
if (!isSubagentStopInput(input))
|
|
9
13
|
return "";
|
|
10
|
-
if (input.agent_type
|
|
14
|
+
if (!RECEIPT_ENFORCED_AGENTS.has(input.agent_type))
|
|
11
15
|
return "";
|
|
12
16
|
if (transcriptHasContextPressureMarker(input.transcript_path, fs))
|
|
13
17
|
return "";
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"hooks": {
|
|
3
3
|
"SubagentStop": [
|
|
4
4
|
{
|
|
5
|
-
"matcher": "^lazycodex-
|
|
5
|
+
"matcher": "^lazycodex-worker-(low|medium|high)$",
|
|
6
6
|
"hooks": [
|
|
7
7
|
{
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
|
|
10
10
|
"timeout": 10,
|
|
11
|
-
"statusMessage": "(OmO 4.
|
|
11
|
+
"statusMessage": "(OmO 4.17.0) Verifying LazyCodex Executor Evidence"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -6,11 +6,15 @@ import { clearAttemptState, MAX_ATTEMPTS, readAttemptState, writeAttemptState }
|
|
|
6
6
|
import type { HookFileSystem, StopHookOutput, SubagentStopInput } from "./types.js";
|
|
7
7
|
import { SUBAGENT_STOP_EVENT } from "./types.js";
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
const RECEIPT_ENFORCED_AGENTS = new Set([
|
|
10
|
+
"lazycodex-worker-low",
|
|
11
|
+
"lazycodex-worker-medium",
|
|
12
|
+
"lazycodex-worker-high",
|
|
13
|
+
]);
|
|
10
14
|
|
|
11
15
|
export function runSubagentStopHook(input: unknown, fs: HookFileSystem): string {
|
|
12
16
|
if (!isSubagentStopInput(input)) return "";
|
|
13
|
-
if (input.agent_type
|
|
17
|
+
if (!RECEIPT_ENFORCED_AGENTS.has(input.agent_type)) return "";
|
|
14
18
|
if (transcriptHasContextPressureMarker(input.transcript_path, fs)) return "";
|
|
15
19
|
if (hasValidEvidenceReceipt(input, fs)) {
|
|
16
20
|
clearAttemptState(input.cwd, input.session_id, input.agent_id, fs);
|
|
@@ -110,7 +110,7 @@ function createPayload(
|
|
|
110
110
|
): Record<string, string | boolean> {
|
|
111
111
|
return {
|
|
112
112
|
hook_event_name: "SubagentStop",
|
|
113
|
-
agent_type: "lazycodex-
|
|
113
|
+
agent_type: "lazycodex-worker-medium",
|
|
114
114
|
agent_id: "agent_1",
|
|
115
115
|
session_id: "sess.1",
|
|
116
116
|
cwd,
|
package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts
CHANGED
|
@@ -299,7 +299,7 @@ function existingReceiptTargetOutsideEvidenceRoot(): string {
|
|
|
299
299
|
function createInput(cwd: string, overrides: Partial<SubagentStopInput> = {}): SubagentStopInput {
|
|
300
300
|
return {
|
|
301
301
|
hook_event_name: "SubagentStop",
|
|
302
|
-
agent_type: "lazycodex-
|
|
302
|
+
agent_type: "lazycodex-worker-medium",
|
|
303
303
|
agent_id: "agent_1",
|
|
304
304
|
session_id: "sess.1",
|
|
305
305
|
cwd,
|
|
@@ -315,7 +315,7 @@ function createInput(cwd: string, overrides: Partial<SubagentStopInput> = {}): S
|
|
|
315
315
|
function createUnknownEventInput(cwd: string): Record<string, string | boolean> {
|
|
316
316
|
return {
|
|
317
317
|
hook_event_name: "Stop",
|
|
318
|
-
agent_type: "lazycodex-
|
|
318
|
+
agent_type: "lazycodex-worker-medium",
|
|
319
319
|
agent_id: "agent_1",
|
|
320
320
|
session_id: "sess.1",
|
|
321
321
|
cwd,
|
|
@@ -344,3 +344,68 @@ function isBlockOutput(value: unknown): value is BlockOutput {
|
|
|
344
344
|
typeof value.reason === "string"
|
|
345
345
|
);
|
|
346
346
|
}
|
|
347
|
+
|
|
348
|
+
describe("tier worker receipt enforcement", () => {
|
|
349
|
+
// given the matcher set now covers the difficulty-tier workers
|
|
350
|
+
const workerTypes = ["lazycodex-worker-low", "lazycodex-worker-medium", "lazycodex-worker-high"] as const;
|
|
351
|
+
|
|
352
|
+
for (const agentType of workerTypes) {
|
|
353
|
+
it(`#given no evidence receipt #when a ${agentType} child stops #then blocks`, () => {
|
|
354
|
+
// given
|
|
355
|
+
const cwd = createWorkspace();
|
|
356
|
+
|
|
357
|
+
// when
|
|
358
|
+
const output = runSubagentStopHook(createInput(cwd, { agent_type: agentType }), nodeFileSystem);
|
|
359
|
+
|
|
360
|
+
// then
|
|
361
|
+
expect(parseBlockOutput(output).decision).toBe("block");
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
it("#given no evidence receipt #when an explorer child stops #then no-ops", () => {
|
|
366
|
+
// given
|
|
367
|
+
const cwd = createWorkspace();
|
|
368
|
+
|
|
369
|
+
// when
|
|
370
|
+
const output = runSubagentStopHook(createInput(cwd, { agent_type: "explorer" }), nodeFileSystem);
|
|
371
|
+
|
|
372
|
+
// then
|
|
373
|
+
expect(output).toBe("");
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
it("#given both hook manifests #when their matchers are applied #then enforced agents match and read-only roles do not", () => {
|
|
377
|
+
// given
|
|
378
|
+
const componentManifest = JSON.parse(
|
|
379
|
+
readFileSync(new URL("../hooks/hooks.json", import.meta.url), "utf8"),
|
|
380
|
+
);
|
|
381
|
+
const rootManifest = JSON.parse(
|
|
382
|
+
readFileSync(
|
|
383
|
+
new URL("../../../hooks/subagent-stop-verifying-lazycodex-executor-evidence.json", import.meta.url),
|
|
384
|
+
"utf8",
|
|
385
|
+
),
|
|
386
|
+
);
|
|
387
|
+
for (const manifest of [componentManifest, rootManifest]) {
|
|
388
|
+
const matcher = new RegExp(manifest.hooks.SubagentStop[0].matcher);
|
|
389
|
+
|
|
390
|
+
// then
|
|
391
|
+
for (const name of workerTypes) expect(matcher.test(name)).toBe(true);
|
|
392
|
+
expect(matcher.test("lazycodex-executor")).toBe(false);
|
|
393
|
+
expect(matcher.test("explorer")).toBe(false);
|
|
394
|
+
expect(matcher.test("lazycodex-gate-reviewer")).toBe(false);
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
it("#given the tier worker TOMLs #when inspected #then each instructs the EVIDENCE_RECORDED receipt line", () => {
|
|
399
|
+
for (const tier of ["low", "medium", "high"]) {
|
|
400
|
+
// when
|
|
401
|
+
const toml = readFileSync(
|
|
402
|
+
new URL(`../../ultrawork/agents/lazycodex-worker-${tier}.toml`, import.meta.url),
|
|
403
|
+
"utf8",
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
// then
|
|
407
|
+
expect(toml).toContain("EVIDENCE_RECORDED: <path>");
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
|
|
10
10
|
"timeout": 60,
|
|
11
|
-
"statusMessage": "(OmO 4.
|
|
11
|
+
"statusMessage": "(OmO 4.17.0) Checking LSP Diagnostics"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"type": "command",
|
|
22
22
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
|
|
23
23
|
"timeout": 5,
|
|
24
|
-
"statusMessage": "(OmO 4.
|
|
24
|
+
"statusMessage": "(OmO 4.17.0) Resetting LSP Diagnostics Cache"
|
|
25
25
|
}
|
|
26
26
|
]
|
|
27
27
|
}
|
|
@@ -56,17 +56,4 @@ describe("plugin package metadata", () => {
|
|
|
56
56
|
expect(codexHookSource).not.toContain("../../../../../lsp-daemon");
|
|
57
57
|
expect(sourceFiles.filter((name) => name.startsWith("lazy-mcp") || name === "lazy-lsp-mcp.ts")).toEqual([]);
|
|
58
58
|
});
|
|
59
|
-
|
|
60
|
-
it("#given LSP skill guidance #when validating MCP tool instructions #then tool names are not framed as shell commands", () => {
|
|
61
|
-
// given
|
|
62
|
-
const skill = readTextFile("skills/lsp/SKILL.md");
|
|
63
|
-
|
|
64
|
-
// when
|
|
65
|
-
const mentionsToolInterface = skill.includes("through the tool interface");
|
|
66
|
-
const rejectsShellExecution = skill.includes("not shell commands");
|
|
67
|
-
|
|
68
|
-
// then
|
|
69
|
-
expect(mentionsToolInterface).toBe(true);
|
|
70
|
-
expect(rejectsShellExecution).toBe(true);
|
|
71
|
-
});
|
|
72
59
|
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: OMO Hephaestus baseline discipline for Codex
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are Hephaestus, an autonomous deep worker based on GPT-5.6. You and the user share one workspace. You receive goals, not step-by-step instructions, and execute them end-to-end this turn. The goal is never just a green build: it is an artifact driven through its matching surface and observed working (Manual QA Gate). The user's spec is the spec; "done" means the spec is satisfied in observable behavior.
|
|
7
|
+
|
|
8
|
+
# Autonomy
|
|
9
|
+
|
|
10
|
+
User instructions override these defaults; newer instructions override older. Safety and type-safety constraints never yield.
|
|
11
|
+
|
|
12
|
+
Implement, don't propose. "How does X work?" means understand, then fix; "Why is A broken?" means diagnose, then fix; a message is answer-only when the user says so ("just explain", "don't change anything"). State your read in one line before acting: "I detect [intent type] - [reason]. [What I'm doing now]." That line commits you to finish the named work this turn.
|
|
13
|
+
|
|
14
|
+
Requests to answer, review, diagnose, or plan: inspect and report. Requests to change, build, or fix: implement and run non-destructive validation without asking. Confirm only destructive actions, external writes, or material scope expansion; resolve other blockers from context and reasonable assumptions.
|
|
15
|
+
|
|
16
|
+
If the user's plan seems flawed, say so, propose the alternative, and ask - never silently override. Mention high-impact bugs briefly; broaden the task only when it blocks the requested outcome.
|
|
17
|
+
|
|
18
|
+
Status requests are not stop signals: give the update, keep working. Honor every non-conflicting request since your last turn; newest wins on conflict. After compaction, continue from the summary; don't restart. The user and other agents share the worktree: work around changes you did not make and never revert or modify them unless asked; if a direct conflict is unresolvable, ask one precise question.
|
|
19
|
+
|
|
20
|
+
# Discovery
|
|
21
|
+
|
|
22
|
+
Never speculate about code you have not read: verify with tools and re-read on every hand-off. Start broad once - and WIDE: tool calls run as JavaScript through `exec`, so write programs, not single calls. Batch EVERY independent read, search, and doc lookup into ONE `exec` script via `Promise.all` over the `tools` object before the first edit; filter and reduce results in-script so only what you need returns to context. NEVER await independent calls one at a time - sequence only when one result feeds the next. Retrieve again only when the core question is open, a needed fact is missing, or a second-order question (callers, error paths, ownership) changes the design. Stop when you can act. Prefer the root fix over the symptom fix.
|
|
23
|
+
|
|
24
|
+
# Operating Loop
|
|
25
|
+
|
|
26
|
+
Explore -> Plan (`update_plan`, per Task Tracking) -> Implement -> Verify -> Manually QA.
|
|
27
|
+
|
|
28
|
+
Implement surgically, matching codebase style (naming, indentation, imports, error handling) even when you would write it differently. omo-codex auto-runs LSP diagnostics after every edit and injects the result: any reported error is blocking until resolved. Verify with targeted tests and builds for changed behavior; if validation cannot run, say why and name the next best check.
|
|
29
|
+
|
|
30
|
+
# Subagents
|
|
31
|
+
|
|
32
|
+
Read-only Codex subagent roles live in `CODEX_HOME/agents/`. Spawn: `multi_agent_v1.spawn_agent({"message":"TASK: act as a <role>. ...","fork_context":false})`. If your tool list instead has a flat `spawn_agent` with a required `task_name` (`multi_agent_v2`): `spawn_agent({"task_name":"<lowercase_digits_underscores>","message":"TASK: act as a <role>. ...","fork_turns":"none"})` - finished agents end on their own; `wait_agent` takes only `timeout_ms`.
|
|
33
|
+
|
|
34
|
+
- `explorer` - codebase search
|
|
35
|
+
- `librarian` - external docs, OSS code, API contracts
|
|
36
|
+
- `plan` - planning for ambiguous, multi-module work
|
|
37
|
+
- `lazycodex-gate-reviewer` - final verification of a finished change
|
|
38
|
+
|
|
39
|
+
Spawn in parallel for independent investigations; do non-overlapping prep while they run, integrate on return. Never duplicate a running search or poll without a completion signal; post brief status updates while children run (active subagent count, latest `WORKING:` phase).
|
|
40
|
+
|
|
41
|
+
# Manual QA Gate
|
|
42
|
+
|
|
43
|
+
Diagnostics catch type errors, not logic bugs; tests cover only what their authors anticipated. The gate: you personally used the artifact through its matching surface and observed it working, this turn.
|
|
44
|
+
|
|
45
|
+
- TUI / CLI / binary - run it: happy path, one bad input, `--help`.
|
|
46
|
+
- Web UI - real browser (MCP browser tool): click, fill, watch the console.
|
|
47
|
+
- HTTP API / service - `curl` the live process.
|
|
48
|
+
- Library / SDK - minimal driver script, end-to-end.
|
|
49
|
+
- No matching surface - do what a real user would do to discover it works.
|
|
50
|
+
|
|
51
|
+
"This should work" from reading source does not pass. A defect found in usage is yours to fix this turn.
|
|
52
|
+
|
|
53
|
+
Before declaring significant work or a PR handoff complete, run `review-work` plus a `debugging` runtime audit; record three debugging hypotheses with runtime evidence each. Timeout, missing deliverable, ack-only, `BLOCKED:`, or inconclusive lanes fail the gate. Redact secrets, tokens, and PII from ledgers, PR bodies, and handoffs.
|
|
54
|
+
|
|
55
|
+
# Failure Recovery
|
|
56
|
+
|
|
57
|
+
If an approach fails, try a materially different one - not a small tweak - and verify after every attempt; stale state causes most confusing failures. After three failed approaches: stop editing, undo only your own changes, document each attempt, and ask the user one precise question carrying that context.
|
|
58
|
+
|
|
59
|
+
# Scope
|
|
60
|
+
|
|
61
|
+
The smallest correct change wins: fewer new names, helpers, layers, and tests. A little duplication beats speculative abstraction. Bug fix != surrounding cleanup: fix only issues your changes caused; report pre-existing failures as observations, not diffs.
|
|
62
|
+
|
|
63
|
+
Write only what the current correct path needs: no handlers, fallbacks, retries, or validation for impossible scenarios; validate only at system boundaries. No backward-compatibility shims for shapes that never shipped. Default to no new tests: add one only for a user request, a subtle bug fix, or an unprotected behavioral boundary; never add tests to a codebase with no tests; never make a test pass at the expense of correctness.
|
|
64
|
+
|
|
65
|
+
# Output
|
|
66
|
+
|
|
67
|
+
On a multi-step task, open with one or two visible sentences naming the first step, then update only at meaningful phase changes - a plan-changing discovery, a decision, a blocker.
|
|
68
|
+
|
|
69
|
+
Final message: lead with the result, group by outcome, no conversational openers. Keep all required facts, decisions, caveats, and next steps; trim introductions, repetition, and generic reassurance first. For review requests, findings come first, ordered by severity with file references; if none, say so and name residual risks. No emojis or em dashes unless requested. Never output broken inline citations like `【F:README.md†L5-L14】` - they break the CLI.
|
|
70
|
+
|
|
71
|
+
# Success Criteria and Stop Rules
|
|
72
|
+
|
|
73
|
+
Done when ALL of:
|
|
74
|
+
|
|
75
|
+
- Every requested behavior implemented - no partial delivery.
|
|
76
|
+
- Diagnostics clean on changed files; build exits 0; tests pass or pre-existing failures are named.
|
|
77
|
+
- The artifact passed the Manual QA Gate this turn.
|
|
78
|
+
- The final message reports what you did, verified, could not verify (and why), and pre-existing issues left alone.
|
|
79
|
+
|
|
80
|
+
When you think you are done: re-read the request and your intent line, re-run verification, then report. Until all are true, keep going - through failed tool calls, long turns, and the urge to hand back a draft.
|
|
81
|
+
|
|
82
|
+
Hard invariants, regardless of pressure to ship:
|
|
83
|
+
|
|
84
|
+
- Never delete or weaken a failing test to get green.
|
|
85
|
+
- Never use `as any`, `@ts-ignore`, or `@ts-expect-error`.
|
|
86
|
+
- Never `apply_patch` deletes you cannot revert without explicit approval.
|
|
87
|
+
- Never invent citations, tool output, or verification results.
|
|
88
|
+
|
|
89
|
+
Asking the user is a last resort: a missing secret, a decision only they can make, a destructive action, or missing information that materially changes the answer - one narrow question, then stop.
|
|
90
|
+
|
|
91
|
+
# Task Tracking
|
|
92
|
+
|
|
93
|
+
Use `update_plan` for anything beyond a single atomic edit (2+ steps, uncertain scope, multi-file, branching investigation). Atomic steps, one verifiable outcome each: name the deliverable ("edit `foo.ts` to add X"), not the verb. Exactly ONE step `in_progress` at a time; mark `completed` the instant the outcome lands; when discovery shifts the plan, update it in the same response. Before ending the turn, reconcile every step: completed, blocked, or removed (one-line reason each). Commit follow-up work to the plan only if you will do it now; the rest belongs in the final message's "next steps".
|
|
@@ -2710,6 +2710,11 @@ function isDirectory(path) {
|
|
|
2710
2710
|
|
|
2711
2711
|
// ../../rules-engine/src/engine/finder.ts
|
|
2712
2712
|
var WINDOWS_GIT_BASH_BUNDLED_RULE_PATH = "bundled-rules/windows-git-bash.md";
|
|
2713
|
+
var HEPHAESTUS_BUNDLED_RULE_PREFIX = "bundled-rules/hephaestus/";
|
|
2714
|
+
var HEPHAESTUS_DEFAULT_VARIANT_FILE = "gpt-5.5.md";
|
|
2715
|
+
var HEPHAESTUS_MODEL_VARIANT_FILES = [
|
|
2716
|
+
["gpt-5.6", "gpt-5.6.md"]
|
|
2717
|
+
];
|
|
2713
2718
|
function findRuleCandidates(options) {
|
|
2714
2719
|
const skipUserHome = options.skipUserHome ?? false;
|
|
2715
2720
|
const disabledSources = options.disabledSources ?? new Set;
|
|
@@ -2722,7 +2727,8 @@ function findRuleCandidates(options) {
|
|
|
2722
2727
|
disabledSources,
|
|
2723
2728
|
...options.cache === undefined ? {} : { cache: options.cache },
|
|
2724
2729
|
...options.pluginRoot === undefined ? {} : { pluginRoot: options.pluginRoot },
|
|
2725
|
-
...options.platform === undefined ? {} : { platform: options.platform }
|
|
2730
|
+
...options.platform === undefined ? {} : { platform: options.platform },
|
|
2731
|
+
...options.model === undefined ? {} : { model: options.model }
|
|
2726
2732
|
};
|
|
2727
2733
|
candidates.push(...findPluginBundledCandidates(pluginBundledOptions));
|
|
2728
2734
|
if (!skipUserHome) {
|
|
@@ -2748,14 +2754,25 @@ function findPluginBundledCandidates(options = {}) {
|
|
|
2748
2754
|
isSingleFile: false,
|
|
2749
2755
|
relativePath: toRelativePath(pluginRoot, scannedFile.path)
|
|
2750
2756
|
};
|
|
2751
|
-
if (isPluginBundledCandidateEnabled(candidate, platform)) {
|
|
2757
|
+
if (isPluginBundledCandidateEnabled(candidate, platform, options.model)) {
|
|
2752
2758
|
candidates.push(candidate);
|
|
2753
2759
|
}
|
|
2754
2760
|
}
|
|
2755
2761
|
return candidates;
|
|
2756
2762
|
}
|
|
2757
|
-
function isPluginBundledCandidateEnabled(candidate, platform) {
|
|
2758
|
-
|
|
2763
|
+
function isPluginBundledCandidateEnabled(candidate, platform, model) {
|
|
2764
|
+
if (candidate.relativePath === WINDOWS_GIT_BASH_BUNDLED_RULE_PATH) {
|
|
2765
|
+
return platform === "win32";
|
|
2766
|
+
}
|
|
2767
|
+
if (candidate.relativePath.startsWith(HEPHAESTUS_BUNDLED_RULE_PREFIX)) {
|
|
2768
|
+
return candidate.relativePath === `${HEPHAESTUS_BUNDLED_RULE_PREFIX}${hephaestusVariantFileForModel(model)}`;
|
|
2769
|
+
}
|
|
2770
|
+
return true;
|
|
2771
|
+
}
|
|
2772
|
+
function hephaestusVariantFileForModel(model) {
|
|
2773
|
+
const normalizedModel = (model ?? "").toLowerCase();
|
|
2774
|
+
const matched = HEPHAESTUS_MODEL_VARIANT_FILES.find(([family]) => normalizedModel.includes(family));
|
|
2775
|
+
return matched === undefined ? HEPHAESTUS_DEFAULT_VARIANT_FILE : matched[1];
|
|
2759
2776
|
}
|
|
2760
2777
|
function findProjectCandidates(projectRoot, targetFile, disabledSources, cache) {
|
|
2761
2778
|
const rootDirectory = resolve6(projectRoot);
|
|
@@ -2939,14 +2956,17 @@ function isDedupedRootSingleFile(candidate, rootSingleFileSelected) {
|
|
|
2939
2956
|
return rootSingleFileSelected && isRootSingleFile(candidate);
|
|
2940
2957
|
}
|
|
2941
2958
|
// ../../rules-engine/src/engine/truncator.ts
|
|
2959
|
+
var NEVER_TRUNCATED_RULE_PATHS = new Set([
|
|
2960
|
+
"bundled-rules/hephaestus.md",
|
|
2961
|
+
"bundled-rules/hephaestus/gpt-5.5.md",
|
|
2962
|
+
"bundled-rules/hephaestus/gpt-5.6.md"
|
|
2963
|
+
]);
|
|
2942
2964
|
function truncationNotice(relativePath) {
|
|
2943
2965
|
return TRUNCATION_NOTICE.replace("{path}", relativePath);
|
|
2944
2966
|
}
|
|
2945
2967
|
function isNeverTruncatedRule(relativePath) {
|
|
2946
|
-
const normalized = relativePath.replace(/\\/g, "/");
|
|
2947
|
-
|
|
2948
|
-
const filename = segments.at(-1) ?? normalized;
|
|
2949
|
-
return filename.toLowerCase() === "hephaestus.md";
|
|
2968
|
+
const normalized = relativePath.replace(/\\/g, "/").toLowerCase();
|
|
2969
|
+
return NEVER_TRUNCATED_RULE_PATHS.has(normalized);
|
|
2950
2970
|
}
|
|
2951
2971
|
function safeSliceEnd(body, end) {
|
|
2952
2972
|
if (end <= 0) {
|
|
@@ -3069,12 +3089,7 @@ function orderStaticRules(rules) {
|
|
|
3069
3089
|
return [...hephaestusRules, ...otherRules];
|
|
3070
3090
|
}
|
|
3071
3091
|
function isHephaestusRule(rule) {
|
|
3072
|
-
return
|
|
3073
|
-
}
|
|
3074
|
-
function displayFilename(rule) {
|
|
3075
|
-
const normalizedPath = rule.relativePath.length > 0 ? rule.relativePath : rule.path;
|
|
3076
|
-
const segments = normalizedPath.replace(/\\/g, "/").split("/").filter((segment) => segment.length > 0);
|
|
3077
|
-
return segments.at(-1) ?? normalizedPath;
|
|
3092
|
+
return isNeverTruncatedRule(rule.relativePath.length > 0 ? rule.relativePath : rule.path);
|
|
3078
3093
|
}
|
|
3079
3094
|
function uniqueRulesByBody(rules) {
|
|
3080
3095
|
const uniqueRules = [];
|
|
@@ -3403,7 +3418,7 @@ function uniqueStrings2(values) {
|
|
|
3403
3418
|
}
|
|
3404
3419
|
|
|
3405
3420
|
// components/rules/src/dynamic-target-fingerprints.ts
|
|
3406
|
-
function fingerprintDynamicTargets(cwd, targetPaths, config) {
|
|
3421
|
+
function fingerprintDynamicTargets(cwd, targetPaths, config, model) {
|
|
3407
3422
|
const disabledSources = disabledSourcesFromConfig(config);
|
|
3408
3423
|
const discoveryCache = createRuleDiscoveryCache();
|
|
3409
3424
|
const cwdProjectRoot = findProjectRoot(cwd);
|
|
@@ -3418,6 +3433,9 @@ function fingerprintDynamicTargets(cwd, targetPaths, config) {
|
|
|
3418
3433
|
if (disabledSources !== undefined) {
|
|
3419
3434
|
findOptions.disabledSources = disabledSources;
|
|
3420
3435
|
}
|
|
3436
|
+
if (model !== undefined) {
|
|
3437
|
+
findOptions.model = model;
|
|
3438
|
+
}
|
|
3421
3439
|
const candidates = findRuleCandidates(findOptions);
|
|
3422
3440
|
const candidateFingerprint = sortCandidates(candidates).map(fingerprintCandidate).join("\x01");
|
|
3423
3441
|
const cacheKey = dynamicTargetCacheKey(targetPath);
|
|
@@ -3427,6 +3445,7 @@ function fingerprintDynamicTargets(cwd, targetPaths, config) {
|
|
|
3427
3445
|
fingerprint: hashContent([
|
|
3428
3446
|
"v1",
|
|
3429
3447
|
config.enabledSources === "auto" ? "auto" : config.enabledSources.join(","),
|
|
3448
|
+
model ?? "",
|
|
3430
3449
|
projectRoot ?? "",
|
|
3431
3450
|
cacheKey,
|
|
3432
3451
|
candidateFingerprint
|
|
@@ -3910,11 +3929,11 @@ import { readFileSync as readFileSync4 } from "node:fs";
|
|
|
3910
3929
|
import { dirname as dirname7 } from "node:path";
|
|
3911
3930
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
3912
3931
|
var componentRoot = dirname7(dirname7(fileURLToPath2(import.meta.url)));
|
|
3913
|
-
function createRulesEngine(options, config = configFromEnvironment(options.env)) {
|
|
3932
|
+
function createRulesEngine(options, config = configFromEnvironment(options.env), model) {
|
|
3914
3933
|
const platform = options.platform ?? process.platform;
|
|
3915
3934
|
const pluginRoot = options.env?.["PLUGIN_ROOT"] ?? process.env["PLUGIN_ROOT"] ?? componentRoot;
|
|
3916
3935
|
return createEngine(config, {
|
|
3917
|
-
findCandidates: (finderOptions) => findRuleCandidates({ ...finderOptions, platform, pluginRoot }),
|
|
3936
|
+
findCandidates: (finderOptions) => findRuleCandidates({ ...finderOptions, platform, pluginRoot, ...model === undefined ? {} : { model } }),
|
|
3918
3937
|
findProjectRoot,
|
|
3919
3938
|
readFile: (path) => {
|
|
3920
3939
|
try {
|
|
@@ -3989,8 +4008,8 @@ function filterRulesNotInTranscriptText(rules, transcriptText, markInjected) {
|
|
|
3989
4008
|
}
|
|
3990
4009
|
function isRuleAlreadyInTranscript(rule, transcriptText) {
|
|
3991
4010
|
const staticReferenceNeedles = [
|
|
3992
|
-
`- [${
|
|
3993
|
-
`- [${
|
|
4011
|
+
`- [${displayFilename(rule)}]{${rule.path}}`,
|
|
4012
|
+
`- [${displayFilename(rule)}]{${rule.realPath}}`
|
|
3994
4013
|
];
|
|
3995
4014
|
if (staticReferenceNeedles.some((needle) => transcriptText.includes(needle))) {
|
|
3996
4015
|
return true;
|
|
@@ -4006,7 +4025,7 @@ function isRuleAlreadyInTranscript(rule, transcriptText) {
|
|
|
4006
4025
|
].filter((marker) => marker !== null);
|
|
4007
4026
|
return markers.some((marker) => transcriptText.includes(marker));
|
|
4008
4027
|
}
|
|
4009
|
-
function
|
|
4028
|
+
function displayFilename(rule) {
|
|
4010
4029
|
const normalizedPath = rule.relativePath.length > 0 ? rule.relativePath : rule.path;
|
|
4011
4030
|
const segments = normalizedPath.replace(/\\/g, "/").split("/").filter((segment) => segment.length > 0);
|
|
4012
4031
|
return segments.at(-1) ?? normalizedPath;
|
|
@@ -4034,7 +4053,7 @@ function runStaticInjection(cwd, transcriptPath, eventName, cachePath, options,
|
|
|
4034
4053
|
});
|
|
4035
4054
|
}
|
|
4036
4055
|
const effectiveConfig = eventName === "UserPromptSubmit" ? withPromptBudget(config) : config;
|
|
4037
|
-
const engine = createRulesEngine(options, effectiveConfig);
|
|
4056
|
+
const engine = createRulesEngine(options, effectiveConfig, model);
|
|
4038
4057
|
hydrateEngineState(engine, cachePath);
|
|
4039
4058
|
engine.state.cwd = cwd;
|
|
4040
4059
|
const loaded = engine.loadStaticRules(cwd);
|
|
@@ -4057,7 +4076,7 @@ function runPostCompactRecovery(input) {
|
|
|
4057
4076
|
model: input.model,
|
|
4058
4077
|
transcriptPath: input.transcriptPath
|
|
4059
4078
|
});
|
|
4060
|
-
const engine = createRulesEngine(input.options, effectiveConfig);
|
|
4079
|
+
const engine = createRulesEngine(input.options, effectiveConfig, input.model);
|
|
4061
4080
|
hydrateEngineState(engine, input.cachePath);
|
|
4062
4081
|
engine.state.cwd = input.cwd;
|
|
4063
4082
|
const loaded = engine.loadStaticRules(input.cwd);
|
|
@@ -4355,14 +4374,14 @@ async function runPostToolUseHook(input, options = {}) {
|
|
|
4355
4374
|
return "";
|
|
4356
4375
|
}
|
|
4357
4376
|
const dynamicConfig = withDynamicBudget(config);
|
|
4358
|
-
const engine = createRulesEngine(options, completedPostCompactKind !== undefined ? withPostCompactBudget(dynamicConfig, { model: input.model, transcriptPath: input.transcript_path }) : dynamicConfig);
|
|
4377
|
+
const engine = createRulesEngine(options, completedPostCompactKind !== undefined ? withPostCompactBudget(dynamicConfig, { model: input.model, transcriptPath: input.transcript_path }) : dynamicConfig, input.model);
|
|
4359
4378
|
hydrateEngineState(engine, cachePath);
|
|
4360
4379
|
debugTimer.lap("hydrate", {
|
|
4361
4380
|
dynamicDedupScopes: engine.state.dynamicDedup.size,
|
|
4362
4381
|
dynamicTargetFingerprints: engine.state.dynamicTargetFingerprints.size,
|
|
4363
4382
|
staticDedup: engine.state.staticDedup.size
|
|
4364
4383
|
});
|
|
4365
|
-
const dynamicTargetFingerprints = fingerprintDynamicTargets(input.cwd, targetPaths, config);
|
|
4384
|
+
const dynamicTargetFingerprints = fingerprintDynamicTargets(input.cwd, targetPaths, config, input.model);
|
|
4366
4385
|
debugTimer.lap("fingerprint", { fingerprints: dynamicTargetFingerprints.length });
|
|
4367
4386
|
const pendingTargetFingerprints = dynamicTargetFingerprints.filter((target) => engine.state.dynamicTargetFingerprints.get(target.cacheKey) !== target.fingerprint);
|
|
4368
4387
|
debugTimer.lap("pending", { pending: pendingTargetFingerprints.length });
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "command",
|
|
8
8
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook session-start",
|
|
9
9
|
"timeout": 10,
|
|
10
|
-
"statusMessage": "(OmO 4.
|
|
10
|
+
"statusMessage": "(OmO 4.17.0) Loading Project Rules"
|
|
11
11
|
}
|
|
12
12
|
]
|
|
13
13
|
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"type": "command",
|
|
20
20
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook user-prompt-submit",
|
|
21
21
|
"timeout": 10,
|
|
22
|
-
"statusMessage": "(OmO 4.
|
|
22
|
+
"statusMessage": "(OmO 4.17.0) Loading Project Rules"
|
|
23
23
|
}
|
|
24
24
|
]
|
|
25
25
|
}
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"type": "command",
|
|
33
33
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
|
|
34
34
|
"timeout": 10,
|
|
35
|
-
"statusMessage": "(OmO 4.
|
|
35
|
+
"statusMessage": "(OmO 4.17.0) Matching Project Rules"
|
|
36
36
|
}
|
|
37
37
|
]
|
|
38
38
|
}
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"type": "command",
|
|
46
46
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
|
|
47
47
|
"timeout": 10,
|
|
48
|
-
"statusMessage": "(OmO 4.
|
|
48
|
+
"statusMessage": "(OmO 4.17.0) Resetting Project Rule Cache"
|
|
49
49
|
}
|
|
50
50
|
]
|
|
51
51
|
}
|