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
|
@@ -440,7 +440,7 @@ async function readOptionalFile(path) {
|
|
|
440
440
|
// components/bootstrap/src/worker.ts
|
|
441
441
|
import { appendFile as appendFile2, mkdir as mkdir8, readFile as readFile13 } from "node:fs/promises";
|
|
442
442
|
import { homedir as homedir4 } from "node:os";
|
|
443
|
-
import { dirname as
|
|
443
|
+
import { dirname as dirname9, join as join22, resolve as resolve7 } from "node:path";
|
|
444
444
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
445
445
|
|
|
446
446
|
// components/bootstrap/src/provision.ts
|
|
@@ -864,211 +864,185 @@ async function defaultVersionProbe2(binaryPath) {
|
|
|
864
864
|
}
|
|
865
865
|
|
|
866
866
|
// components/bootstrap/src/setup.ts
|
|
867
|
-
import { copyFile as copyFile2, mkdir as mkdir7, readdir as
|
|
868
|
-
import { join as
|
|
867
|
+
import { copyFile as copyFile2, mkdir as mkdir7, readdir as readdir5, rm as rm10, stat as stat5 } from "node:fs/promises";
|
|
868
|
+
import { join as join21 } from "node:path";
|
|
869
869
|
|
|
870
870
|
// ../src/install/link-cached-plugin-agents.ts
|
|
871
|
-
import { copyFile, lstat as
|
|
872
|
-
import { basename as basename3, join as
|
|
871
|
+
import { copyFile, lstat as lstat3, mkdir as mkdir4, readdir as readdir2, rm as rm6, writeFile as writeFile4 } from "node:fs/promises";
|
|
872
|
+
import { basename as basename3, join as join10 } from "node:path";
|
|
873
873
|
|
|
874
|
-
// ../src/install/
|
|
875
|
-
import { lstat, readFile as readFile4,
|
|
874
|
+
// ../src/install/preserved-agent-settings.ts
|
|
875
|
+
import { lstat, readFile as readFile4, readdir, writeFile as writeFile3 } from "node:fs/promises";
|
|
876
876
|
import { join as join8 } from "node:path";
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
877
|
+
|
|
878
|
+
// ../src/install/managed-agent-reasoning-defaults.ts
|
|
879
|
+
var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
|
|
880
|
+
[
|
|
881
|
+
"explorer",
|
|
882
|
+
[
|
|
883
|
+
{
|
|
884
|
+
previous: { model: "gpt-5.4-mini", effort: "low" },
|
|
885
|
+
current: { model: "gpt-5.6-terra", effort: "medium" }
|
|
886
|
+
},
|
|
887
|
+
{
|
|
888
|
+
previous: { model: "gpt-5.6-terra", effort: "medium" },
|
|
889
|
+
current: { model: "gpt-5.6-luna", effort: "low" }
|
|
890
|
+
}
|
|
884
891
|
]
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
892
|
+
],
|
|
893
|
+
[
|
|
894
|
+
"librarian",
|
|
895
|
+
[
|
|
896
|
+
{
|
|
897
|
+
previous: { model: "gpt-5.4-mini", effort: "low" },
|
|
898
|
+
current: { model: "gpt-5.6-terra", effort: "medium" }
|
|
899
|
+
},
|
|
900
|
+
{
|
|
901
|
+
previous: { model: "gpt-5.6-terra", effort: "medium" },
|
|
902
|
+
current: { model: "gpt-5.6-luna", effort: "low" }
|
|
903
|
+
}
|
|
904
|
+
]
|
|
905
|
+
],
|
|
906
|
+
[
|
|
907
|
+
"momus",
|
|
908
|
+
[
|
|
909
|
+
{
|
|
910
|
+
previous: { model: "gpt-5.5", effort: "xhigh" },
|
|
911
|
+
current: { model: "gpt-5.6-sol", effort: "ultra" }
|
|
912
|
+
}
|
|
913
|
+
]
|
|
914
|
+
],
|
|
915
|
+
[
|
|
916
|
+
"plan",
|
|
917
|
+
[
|
|
918
|
+
{
|
|
919
|
+
previous: { model: "gpt-5.6-sol", effort: "xhigh" },
|
|
920
|
+
current: { model: "gpt-5.6-sol", effort: "max" }
|
|
921
|
+
}
|
|
922
|
+
]
|
|
923
|
+
],
|
|
924
|
+
[
|
|
925
|
+
"lazycodex-worker-medium",
|
|
926
|
+
[
|
|
927
|
+
{
|
|
928
|
+
previous: { model: "gpt-5.6-sol", effort: "high" },
|
|
929
|
+
current: { model: "gpt-5.6-luna", effort: "max" }
|
|
930
|
+
}
|
|
931
|
+
]
|
|
932
|
+
],
|
|
933
|
+
[
|
|
934
|
+
"lazycodex-qa-executor",
|
|
935
|
+
[
|
|
936
|
+
{
|
|
937
|
+
previous: { model: "gpt-5.6-terra", effort: "medium" },
|
|
938
|
+
current: { model: "gpt-5.6-luna", effort: "high" }
|
|
939
|
+
}
|
|
940
|
+
]
|
|
941
|
+
],
|
|
942
|
+
[
|
|
943
|
+
"lazycodex-gate-reviewer",
|
|
944
|
+
[
|
|
945
|
+
{
|
|
946
|
+
previous: { model: "gpt-5.6-sol", effort: "xhigh" },
|
|
947
|
+
current: { model: "gpt-5.6-sol", effort: "high" }
|
|
948
|
+
}
|
|
949
|
+
]
|
|
950
|
+
]
|
|
951
|
+
]);
|
|
952
|
+
function resolveManagedAgentReasoning(input) {
|
|
953
|
+
const steps = MANAGED_REASONING_DEFAULT_UPGRADES.get(input.agentName);
|
|
954
|
+
if (steps === undefined)
|
|
955
|
+
return input.preserved.effort;
|
|
956
|
+
const latest = steps[steps.length - 1];
|
|
957
|
+
if (latest === undefined)
|
|
958
|
+
return input.preserved.effort;
|
|
959
|
+
if (input.bundledModel !== latest.current.model || input.bundledEffort !== latest.current.effort) {
|
|
960
|
+
return input.preserved.effort;
|
|
961
|
+
}
|
|
962
|
+
const preservedMatchesAnyStep = steps.some((step) => input.preserved.model === step.previous.model && input.preserved.effort === step.previous.effort);
|
|
963
|
+
return preservedMatchesAnyStep ? latest.current.effort : input.preserved.effort;
|
|
930
964
|
}
|
|
931
965
|
|
|
932
|
-
// ../src/install/
|
|
933
|
-
var MANIFEST_FILE = ".installed-agents.json";
|
|
966
|
+
// ../src/install/preserved-agent-settings.ts
|
|
934
967
|
async function capturePreservedAgentReasoning(input) {
|
|
935
|
-
const agentsDir =
|
|
936
|
-
if (!await
|
|
968
|
+
const agentsDir = join8(input.codexHome, "agents");
|
|
969
|
+
if (!await exists(agentsDir))
|
|
937
970
|
return new Map;
|
|
938
971
|
const preserved = new Map;
|
|
939
972
|
const agentEntries = await readdir(agentsDir, { withFileTypes: true });
|
|
940
973
|
for (const entry of agentEntries) {
|
|
941
974
|
if (!entry.name.endsWith(".toml"))
|
|
942
975
|
continue;
|
|
943
|
-
const content = await
|
|
976
|
+
const content = await readTextIfExists(join8(agentsDir, entry.name));
|
|
944
977
|
if (content === null)
|
|
945
978
|
continue;
|
|
946
979
|
const effort = extractReasoningEffort(content);
|
|
947
|
-
if (effort !== null)
|
|
948
|
-
preserved.set(agentNameFromToml(entry.name),
|
|
980
|
+
if (effort !== null) {
|
|
981
|
+
preserved.set(agentNameFromToml(entry.name), {
|
|
982
|
+
model: extractModel(content),
|
|
983
|
+
effort
|
|
984
|
+
});
|
|
985
|
+
}
|
|
949
986
|
}
|
|
950
987
|
return preserved;
|
|
951
988
|
}
|
|
952
989
|
async function capturePreservedAgentServiceTier(input) {
|
|
953
|
-
const agentsDir =
|
|
954
|
-
if (!await
|
|
990
|
+
const agentsDir = join8(input.codexHome, "agents");
|
|
991
|
+
if (!await exists(agentsDir))
|
|
955
992
|
return new Map;
|
|
956
993
|
const preserved = new Map;
|
|
957
994
|
const agentEntries = await readdir(agentsDir, { withFileTypes: true });
|
|
958
995
|
for (const entry of agentEntries) {
|
|
959
996
|
if (!entry.name.endsWith(".toml"))
|
|
960
997
|
continue;
|
|
961
|
-
const content = await
|
|
998
|
+
const content = await readTextIfExists(join8(agentsDir, entry.name));
|
|
962
999
|
if (content === null)
|
|
963
1000
|
continue;
|
|
964
1001
|
preserved.set(agentNameFromToml(entry.name), extractServiceTier(content));
|
|
965
1002
|
}
|
|
966
1003
|
return preserved;
|
|
967
1004
|
}
|
|
968
|
-
async function
|
|
969
|
-
|
|
970
|
-
await purgeRetiredManagedAgentFiles({ codexHome: input.codexHome });
|
|
971
|
-
if (bundledAgents.length === 0) {
|
|
972
|
-
await writeManifest(input.pluginRoot, []);
|
|
973
|
-
return [];
|
|
974
|
-
}
|
|
975
|
-
const agentsDir = join9(input.codexHome, "agents");
|
|
976
|
-
await mkdir4(agentsDir, { recursive: true });
|
|
977
|
-
const linked = [];
|
|
978
|
-
for (const agentPath of bundledAgents) {
|
|
979
|
-
const agentFileName = basename3(agentPath);
|
|
980
|
-
const agentName = agentNameFromToml(agentFileName);
|
|
981
|
-
const linkPath = join9(agentsDir, agentFileName);
|
|
982
|
-
await replaceWithCopy(linkPath, agentPath);
|
|
983
|
-
await restorePreservedReasoning({
|
|
984
|
-
agentName,
|
|
985
|
-
linkPath,
|
|
986
|
-
target: agentPath,
|
|
987
|
-
value: input.preservedReasoning?.get(agentName)
|
|
988
|
-
});
|
|
989
|
-
await restorePreservedServiceTier({
|
|
990
|
-
linkPath,
|
|
991
|
-
preserved: input.preservedServiceTier?.has(agentName) ?? false,
|
|
992
|
-
value: input.preservedServiceTier?.get(agentName) ?? null
|
|
993
|
-
});
|
|
994
|
-
linked.push({ name: agentFileName, path: linkPath, target: agentPath });
|
|
995
|
-
}
|
|
996
|
-
await writeManifest(input.pluginRoot, linked.map((entry) => entry.path));
|
|
997
|
-
return linked;
|
|
998
|
-
}
|
|
999
|
-
async function restorePreservedServiceTier(input) {
|
|
1000
|
-
if (!input.preserved)
|
|
1005
|
+
async function restorePreservedReasoning(input) {
|
|
1006
|
+
if (input.value === undefined)
|
|
1001
1007
|
return;
|
|
1002
|
-
const content = await
|
|
1003
|
-
|
|
1008
|
+
const content = await readFile4(input.target, "utf8");
|
|
1009
|
+
const bundledEffort = extractReasoningEffort(content);
|
|
1010
|
+
const effort = resolveManagedAgentReasoning({
|
|
1011
|
+
agentName: input.agentName,
|
|
1012
|
+
bundledModel: extractModel(content),
|
|
1013
|
+
bundledEffort,
|
|
1014
|
+
preserved: input.value
|
|
1015
|
+
});
|
|
1016
|
+
if (bundledEffort === effort)
|
|
1004
1017
|
return;
|
|
1005
|
-
const replacement =
|
|
1018
|
+
const replacement = replaceTopLevelStringSetting(content, "model_reasoning_effort", effort, { insertIfMissing: false });
|
|
1006
1019
|
if (!replacement.replaced)
|
|
1007
1020
|
return;
|
|
1008
1021
|
await writeFile3(input.linkPath, replacement.content);
|
|
1009
1022
|
}
|
|
1010
|
-
async function
|
|
1011
|
-
|
|
1012
|
-
if (!await exists2(componentsRoot))
|
|
1013
|
-
return [];
|
|
1014
|
-
const componentEntries = await readdir(componentsRoot, { withFileTypes: true });
|
|
1015
|
-
const agents = [];
|
|
1016
|
-
for (const entry of componentEntries) {
|
|
1017
|
-
if (!entry.isDirectory())
|
|
1018
|
-
continue;
|
|
1019
|
-
const agentsRoot = join9(componentsRoot, entry.name, "agents");
|
|
1020
|
-
if (!await exists2(agentsRoot))
|
|
1021
|
-
continue;
|
|
1022
|
-
const agentEntries = await readdir(agentsRoot, { withFileTypes: true });
|
|
1023
|
-
for (const file of agentEntries) {
|
|
1024
|
-
if (!file.isFile() || !file.name.endsWith(".toml"))
|
|
1025
|
-
continue;
|
|
1026
|
-
agents.push(join9(agentsRoot, file.name));
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
agents.sort();
|
|
1030
|
-
return agents;
|
|
1031
|
-
}
|
|
1032
|
-
async function replaceWithCopy(linkPath, target) {
|
|
1033
|
-
await prepareReplacement(linkPath);
|
|
1034
|
-
await copyFile(target, linkPath);
|
|
1035
|
-
}
|
|
1036
|
-
async function prepareReplacement(linkPath) {
|
|
1037
|
-
if (!await exists2(linkPath))
|
|
1038
|
-
return;
|
|
1039
|
-
const entryStat = await lstat2(linkPath);
|
|
1040
|
-
if (entryStat.isDirectory() && !entryStat.isSymbolicLink()) {
|
|
1041
|
-
throw new Error(`${linkPath} already exists and is a directory; refusing to replace`);
|
|
1042
|
-
}
|
|
1043
|
-
await rm6(linkPath, { force: true });
|
|
1044
|
-
}
|
|
1045
|
-
async function writeManifest(pluginRoot, agentPaths) {
|
|
1046
|
-
const manifestPath = join9(pluginRoot, MANIFEST_FILE);
|
|
1047
|
-
const payload = { agents: [...agentPaths].sort() };
|
|
1048
|
-
await writeFile3(manifestPath, `${JSON.stringify(payload, null, "\t")}
|
|
1049
|
-
`);
|
|
1050
|
-
}
|
|
1051
|
-
async function restorePreservedReasoning(input) {
|
|
1052
|
-
if (input.value === undefined)
|
|
1023
|
+
async function restorePreservedServiceTier(input) {
|
|
1024
|
+
if (!input.preserved)
|
|
1053
1025
|
return;
|
|
1054
|
-
const content = await
|
|
1055
|
-
|
|
1056
|
-
if (bundledEffort === input.value)
|
|
1026
|
+
const content = await readFile4(input.linkPath, "utf8");
|
|
1027
|
+
if (extractServiceTier(content) === input.value)
|
|
1057
1028
|
return;
|
|
1058
|
-
const replacement =
|
|
1029
|
+
const replacement = replaceTopLevelStringSetting(content, "service_tier", input.value, { insertIfMissing: true });
|
|
1059
1030
|
if (!replacement.replaced)
|
|
1060
1031
|
return;
|
|
1061
1032
|
await writeFile3(input.linkPath, replacement.content);
|
|
1062
1033
|
}
|
|
1063
|
-
async function
|
|
1034
|
+
async function readTextIfExists(path) {
|
|
1064
1035
|
try {
|
|
1065
|
-
return await
|
|
1036
|
+
return await readFile4(path, "utf8");
|
|
1066
1037
|
} catch (error) {
|
|
1067
|
-
if (
|
|
1038
|
+
if (nodeErrorCode(error) === "ENOENT")
|
|
1068
1039
|
return null;
|
|
1069
1040
|
throw error;
|
|
1070
1041
|
}
|
|
1071
1042
|
}
|
|
1043
|
+
function extractModel(content) {
|
|
1044
|
+
return extractTopLevelStringSetting(content, "model");
|
|
1045
|
+
}
|
|
1072
1046
|
function extractReasoningEffort(content) {
|
|
1073
1047
|
return extractTopLevelStringSetting(content, "model_reasoning_effort");
|
|
1074
1048
|
}
|
|
@@ -1088,12 +1062,6 @@ function extractTopLevelStringSetting(content, key) {
|
|
|
1088
1062
|
}
|
|
1089
1063
|
return null;
|
|
1090
1064
|
}
|
|
1091
|
-
function replaceReasoningEffort(content, value) {
|
|
1092
|
-
return replaceTopLevelStringSetting(content, "model_reasoning_effort", value, { insertIfMissing: false });
|
|
1093
|
-
}
|
|
1094
|
-
function replaceServiceTier(content, value) {
|
|
1095
|
-
return replaceTopLevelStringSetting(content, "service_tier", value, { insertIfMissing: true });
|
|
1096
|
-
}
|
|
1097
1065
|
function replaceTopLevelStringSetting(content, key, value, options) {
|
|
1098
1066
|
const lines = content.split(/\n/);
|
|
1099
1067
|
for (let index = 0;index < lines.length; index += 1) {
|
|
@@ -1153,6 +1121,64 @@ function parseJsonString(value) {
|
|
|
1153
1121
|
return null;
|
|
1154
1122
|
}
|
|
1155
1123
|
}
|
|
1124
|
+
async function exists(path) {
|
|
1125
|
+
try {
|
|
1126
|
+
await lstat(path);
|
|
1127
|
+
return true;
|
|
1128
|
+
} catch (error) {
|
|
1129
|
+
if (nodeErrorCode(error) !== "ENOENT")
|
|
1130
|
+
throw error;
|
|
1131
|
+
return false;
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
function nodeErrorCode(error) {
|
|
1135
|
+
if (!(error instanceof Error) || !("code" in error))
|
|
1136
|
+
return null;
|
|
1137
|
+
return typeof error.code === "string" ? error.code : null;
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// ../src/install/retired-managed-agent-purge.ts
|
|
1141
|
+
import { lstat as lstat2, readFile as readFile5, rm as rm5 } from "node:fs/promises";
|
|
1142
|
+
import { join as join9 } from "node:path";
|
|
1143
|
+
var RETIRED_MANAGED_AGENT_FILES = [
|
|
1144
|
+
{
|
|
1145
|
+
fileName: "codex-ultrawork-reviewer.toml",
|
|
1146
|
+
requiredMarkers: [
|
|
1147
|
+
'name = "codex-ultrawork-reviewer"',
|
|
1148
|
+
'description = "Strict ultrawork verification reviewer.',
|
|
1149
|
+
'developer_instructions = """You are the ultrawork verification reviewer.'
|
|
1150
|
+
]
|
|
1151
|
+
}
|
|
1152
|
+
];
|
|
1153
|
+
async function purgeRetiredManagedAgentFiles(input) {
|
|
1154
|
+
const agentsDir = join9(input.codexHome, "agents");
|
|
1155
|
+
if (!await exists2(agentsDir))
|
|
1156
|
+
return;
|
|
1157
|
+
for (const retiredAgent of RETIRED_MANAGED_AGENT_FILES) {
|
|
1158
|
+
const agentPath = join9(agentsDir, retiredAgent.fileName);
|
|
1159
|
+
if (!await exists2(agentPath))
|
|
1160
|
+
continue;
|
|
1161
|
+
const agentStat = await lstat2(agentPath);
|
|
1162
|
+
if (agentStat.isDirectory() && !agentStat.isSymbolicLink())
|
|
1163
|
+
continue;
|
|
1164
|
+
const content = await readTextIfExists2(agentPath);
|
|
1165
|
+
if (content === null || !hasRequiredMarkers(content, retiredAgent.requiredMarkers))
|
|
1166
|
+
continue;
|
|
1167
|
+
await rm5(agentPath, { force: true });
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
function hasRequiredMarkers(content, markers) {
|
|
1171
|
+
return markers.every((marker) => content.includes(marker));
|
|
1172
|
+
}
|
|
1173
|
+
async function readTextIfExists2(path) {
|
|
1174
|
+
try {
|
|
1175
|
+
return await readFile5(path, "utf8");
|
|
1176
|
+
} catch (error) {
|
|
1177
|
+
if (nodeErrorCode2(error) === "ENOENT")
|
|
1178
|
+
return null;
|
|
1179
|
+
throw error;
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1156
1182
|
async function exists2(path) {
|
|
1157
1183
|
try {
|
|
1158
1184
|
await lstat2(path);
|
|
@@ -1169,9 +1195,102 @@ function nodeErrorCode2(error) {
|
|
|
1169
1195
|
return typeof error.code === "string" ? error.code : null;
|
|
1170
1196
|
}
|
|
1171
1197
|
|
|
1198
|
+
// ../src/install/link-cached-plugin-agents.ts
|
|
1199
|
+
var MANIFEST_FILE = ".installed-agents.json";
|
|
1200
|
+
async function linkCachedPluginAgents(input) {
|
|
1201
|
+
const bundledAgents = await discoverBundledAgents(input.pluginRoot);
|
|
1202
|
+
await purgeRetiredManagedAgentFiles({ codexHome: input.codexHome });
|
|
1203
|
+
if (bundledAgents.length === 0) {
|
|
1204
|
+
await writeManifest(input.pluginRoot, []);
|
|
1205
|
+
return [];
|
|
1206
|
+
}
|
|
1207
|
+
const agentsDir = join10(input.codexHome, "agents");
|
|
1208
|
+
await mkdir4(agentsDir, { recursive: true });
|
|
1209
|
+
const linked = [];
|
|
1210
|
+
for (const agentPath of bundledAgents) {
|
|
1211
|
+
const agentFileName = basename3(agentPath);
|
|
1212
|
+
const agentName = agentNameFromToml2(agentFileName);
|
|
1213
|
+
const linkPath = join10(agentsDir, agentFileName);
|
|
1214
|
+
await replaceWithCopy(linkPath, agentPath);
|
|
1215
|
+
await restorePreservedReasoning({
|
|
1216
|
+
agentName,
|
|
1217
|
+
linkPath,
|
|
1218
|
+
target: agentPath,
|
|
1219
|
+
value: input.preservedReasoning?.get(agentName)
|
|
1220
|
+
});
|
|
1221
|
+
await restorePreservedServiceTier({
|
|
1222
|
+
linkPath,
|
|
1223
|
+
preserved: input.preservedServiceTier?.has(agentName) ?? false,
|
|
1224
|
+
value: input.preservedServiceTier?.get(agentName) ?? null
|
|
1225
|
+
});
|
|
1226
|
+
linked.push({ name: agentFileName, path: linkPath, target: agentPath });
|
|
1227
|
+
}
|
|
1228
|
+
await writeManifest(input.pluginRoot, linked.map((entry) => entry.path));
|
|
1229
|
+
return linked;
|
|
1230
|
+
}
|
|
1231
|
+
async function discoverBundledAgents(pluginRoot) {
|
|
1232
|
+
const componentsRoot = join10(pluginRoot, "components");
|
|
1233
|
+
if (!await exists3(componentsRoot))
|
|
1234
|
+
return [];
|
|
1235
|
+
const componentEntries = await readdir2(componentsRoot, { withFileTypes: true });
|
|
1236
|
+
const agents = [];
|
|
1237
|
+
for (const entry of componentEntries) {
|
|
1238
|
+
if (!entry.isDirectory())
|
|
1239
|
+
continue;
|
|
1240
|
+
const agentsRoot = join10(componentsRoot, entry.name, "agents");
|
|
1241
|
+
if (!await exists3(agentsRoot))
|
|
1242
|
+
continue;
|
|
1243
|
+
const agentEntries = await readdir2(agentsRoot, { withFileTypes: true });
|
|
1244
|
+
for (const file of agentEntries) {
|
|
1245
|
+
if (!file.isFile() || !file.name.endsWith(".toml"))
|
|
1246
|
+
continue;
|
|
1247
|
+
agents.push(join10(agentsRoot, file.name));
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
agents.sort();
|
|
1251
|
+
return agents;
|
|
1252
|
+
}
|
|
1253
|
+
async function replaceWithCopy(linkPath, target) {
|
|
1254
|
+
await prepareReplacement(linkPath);
|
|
1255
|
+
await copyFile(target, linkPath);
|
|
1256
|
+
}
|
|
1257
|
+
async function prepareReplacement(linkPath) {
|
|
1258
|
+
if (!await exists3(linkPath))
|
|
1259
|
+
return;
|
|
1260
|
+
const entryStat = await lstat3(linkPath);
|
|
1261
|
+
if (entryStat.isDirectory() && !entryStat.isSymbolicLink()) {
|
|
1262
|
+
throw new Error(`${linkPath} already exists and is a directory; refusing to replace`);
|
|
1263
|
+
}
|
|
1264
|
+
await rm6(linkPath, { force: true });
|
|
1265
|
+
}
|
|
1266
|
+
async function writeManifest(pluginRoot, agentPaths) {
|
|
1267
|
+
const manifestPath = join10(pluginRoot, MANIFEST_FILE);
|
|
1268
|
+
const payload = { agents: [...agentPaths].sort() };
|
|
1269
|
+
await writeFile4(manifestPath, `${JSON.stringify(payload, null, "\t")}
|
|
1270
|
+
`);
|
|
1271
|
+
}
|
|
1272
|
+
function agentNameFromToml2(fileName) {
|
|
1273
|
+
return fileName.endsWith(".toml") ? fileName.slice(0, -".toml".length) : fileName;
|
|
1274
|
+
}
|
|
1275
|
+
async function exists3(path) {
|
|
1276
|
+
try {
|
|
1277
|
+
await lstat3(path);
|
|
1278
|
+
return true;
|
|
1279
|
+
} catch (error) {
|
|
1280
|
+
if (nodeErrorCode3(error) !== "ENOENT")
|
|
1281
|
+
throw error;
|
|
1282
|
+
return false;
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
function nodeErrorCode3(error) {
|
|
1286
|
+
if (!(error instanceof Error) || !("code" in error))
|
|
1287
|
+
return null;
|
|
1288
|
+
return typeof error.code === "string" ? error.code : null;
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1172
1291
|
// ../src/install/codex-cache-bins.ts
|
|
1173
|
-
import { chmod as chmod2, lstat as
|
|
1174
|
-
import { basename as basename4, isAbsolute as isAbsolute3, join as
|
|
1292
|
+
import { chmod as chmod2, lstat as lstat7, mkdir as mkdir5, readFile as readFile8, readdir as readdir4, readlink as readlink3, rm as rm9, stat as stat4, symlink, writeFile as writeFile5 } from "node:fs/promises";
|
|
1293
|
+
import { basename as basename4, isAbsolute as isAbsolute3, join as join14, relative as relative2, resolve as resolve4, sep } from "node:path";
|
|
1175
1294
|
|
|
1176
1295
|
// ../src/install/codex-cache-command-shim.ts
|
|
1177
1296
|
var COMMAND_SHIM_MARKER = ":: generated by oh-my-openagent Codex installer";
|
|
@@ -1215,14 +1334,14 @@ function windowsCommandShim(targetPath) {
|
|
|
1215
1334
|
}
|
|
1216
1335
|
|
|
1217
1336
|
// ../src/install/codex-cache-dangling-bins.ts
|
|
1218
|
-
import { lstat as
|
|
1219
|
-
import { dirname as dirname5, isAbsolute as isAbsolute2, join as
|
|
1337
|
+
import { lstat as lstat5, readFile as readFile6, readdir as readdir3, readlink, rm as rm7, stat as stat3 } from "node:fs/promises";
|
|
1338
|
+
import { dirname as dirname5, isAbsolute as isAbsolute2, join as join11, resolve as resolve3 } from "node:path";
|
|
1220
1339
|
|
|
1221
1340
|
// ../src/install/codex-cache-fs.ts
|
|
1222
|
-
import { lstat as
|
|
1341
|
+
import { lstat as lstat4 } from "node:fs/promises";
|
|
1223
1342
|
async function fileExistsStrict(path) {
|
|
1224
1343
|
try {
|
|
1225
|
-
await
|
|
1344
|
+
await lstat4(path);
|
|
1226
1345
|
return true;
|
|
1227
1346
|
} catch (error) {
|
|
1228
1347
|
if (isNodeErrorWithCode(error) && error.code === "ENOENT")
|
|
@@ -1239,12 +1358,12 @@ function isNodeErrorWithCode(error) {
|
|
|
1239
1358
|
|
|
1240
1359
|
// ../src/install/codex-cache-dangling-bins.ts
|
|
1241
1360
|
async function removeDanglingManagedComponentBins(binDir, platform, managedBinNames) {
|
|
1242
|
-
const entries = await
|
|
1361
|
+
const entries = await readdir3(binDir, { withFileTypes: true });
|
|
1243
1362
|
for (const entry of entries) {
|
|
1244
1363
|
const binName = managedBinNameForEntry(entry.name, platform);
|
|
1245
1364
|
if (binName === null || !managedBinNames.has(binName))
|
|
1246
1365
|
continue;
|
|
1247
|
-
const linkPath =
|
|
1366
|
+
const linkPath = join11(binDir, entry.name);
|
|
1248
1367
|
if (platform === "win32") {
|
|
1249
1368
|
await removeDanglingGeneratedCommandShim(linkPath);
|
|
1250
1369
|
continue;
|
|
@@ -1259,7 +1378,7 @@ function managedBinNameForEntry(name, platform) {
|
|
|
1259
1378
|
}
|
|
1260
1379
|
async function removeDanglingManagedSymlink(linkPath) {
|
|
1261
1380
|
try {
|
|
1262
|
-
const linkStat = await
|
|
1381
|
+
const linkStat = await lstat5(linkPath);
|
|
1263
1382
|
if (!linkStat.isSymbolicLink())
|
|
1264
1383
|
return;
|
|
1265
1384
|
const linkTarget = await readlink(linkPath);
|
|
@@ -1274,7 +1393,7 @@ async function removeDanglingManagedSymlink(linkPath) {
|
|
|
1274
1393
|
}
|
|
1275
1394
|
async function removeDanglingGeneratedCommandShim(linkPath) {
|
|
1276
1395
|
try {
|
|
1277
|
-
const linkStat = await
|
|
1396
|
+
const linkStat = await lstat5(linkPath);
|
|
1278
1397
|
if (!linkStat.isFile())
|
|
1279
1398
|
return;
|
|
1280
1399
|
const content = await readFile6(linkPath, "utf8");
|
|
@@ -1325,8 +1444,8 @@ function hasOmoCodexPluginPrefix(parts, endExclusive) {
|
|
|
1325
1444
|
}
|
|
1326
1445
|
|
|
1327
1446
|
// ../src/install/codex-cache-legacy-bins.ts
|
|
1328
|
-
import { lstat as
|
|
1329
|
-
import { join as
|
|
1447
|
+
import { lstat as lstat6, readFile as readFile7, readlink as readlink2, rm as rm8 } from "node:fs/promises";
|
|
1448
|
+
import { join as join12 } from "node:path";
|
|
1330
1449
|
var LEGACY_CODEX_COMPONENT_BINS = [
|
|
1331
1450
|
{ name: "omo", component: "ulw-loop" },
|
|
1332
1451
|
{ name: "codex-comment-checker", component: "comment-checker" },
|
|
@@ -1338,13 +1457,13 @@ var LEGACY_CODEX_COMPONENT_BINS = [
|
|
|
1338
1457
|
];
|
|
1339
1458
|
async function removeLegacyCodexComponentBins(binDir, platform) {
|
|
1340
1459
|
for (const entry of LEGACY_CODEX_COMPONENT_BINS) {
|
|
1341
|
-
const linkPath =
|
|
1460
|
+
const linkPath = join12(binDir, platform === "win32" ? `${entry.name}.cmd` : entry.name);
|
|
1342
1461
|
await removeLegacyCodexComponentBin(linkPath, entry.component, platform);
|
|
1343
1462
|
}
|
|
1344
1463
|
}
|
|
1345
1464
|
async function removeLegacyCodexComponentBin(linkPath, component, platform) {
|
|
1346
1465
|
try {
|
|
1347
|
-
const stat4 = await
|
|
1466
|
+
const stat4 = await lstat6(linkPath);
|
|
1348
1467
|
if (platform !== "win32") {
|
|
1349
1468
|
if (!stat4.isSymbolicLink())
|
|
1350
1469
|
return;
|
|
@@ -1389,10 +1508,10 @@ function isNodeErrorWithCode2(error) {
|
|
|
1389
1508
|
}
|
|
1390
1509
|
|
|
1391
1510
|
// ../src/install/codex-cache-runtime-wrapper.ts
|
|
1392
|
-
import { join as
|
|
1511
|
+
import { join as join13 } from "node:path";
|
|
1393
1512
|
var RUNTIME_WRAPPER_MARKER = "OMO_GENERATED_RUNTIME_WRAPPER";
|
|
1394
1513
|
function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
|
|
1395
|
-
const ulwLoopBin = toPosixPath(
|
|
1514
|
+
const ulwLoopBin = toPosixPath(join13(binDir, "omo-ulw-loop"));
|
|
1396
1515
|
const nodeCli = escapePosixDoubleQuoted(toPosixPath(nodeCliPath));
|
|
1397
1516
|
const escapedCliPath = escapePosixDoubleQuoted(toPosixPath(cliPath));
|
|
1398
1517
|
const escapedCodexHome = escapePosixDoubleQuoted(toPosixPath(codexHome));
|
|
@@ -1437,7 +1556,7 @@ function posixRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
|
|
|
1437
1556
|
`);
|
|
1438
1557
|
}
|
|
1439
1558
|
function windowsRuntimeWrapper(cliPath, codexHome, binDir, nodeCliPath) {
|
|
1440
|
-
const ulwLoopBin =
|
|
1559
|
+
const ulwLoopBin = join13(binDir, "omo-ulw-loop.cmd");
|
|
1441
1560
|
return [
|
|
1442
1561
|
"@echo off",
|
|
1443
1562
|
`rem ${RUNTIME_WRAPPER_MARKER}`,
|
|
@@ -1494,29 +1613,29 @@ async function linkCachedPluginBins(input) {
|
|
|
1494
1613
|
return linked;
|
|
1495
1614
|
}
|
|
1496
1615
|
async function linkRootRuntimeBin(input) {
|
|
1497
|
-
const cliPath =
|
|
1616
|
+
const cliPath = join14(input.repoRoot, "dist", "cli", "index.js");
|
|
1498
1617
|
if (!await isFile2(cliPath))
|
|
1499
1618
|
return null;
|
|
1500
|
-
const nodeCliPath =
|
|
1619
|
+
const nodeCliPath = join14(input.repoRoot, "dist", "cli-node", "index.js");
|
|
1501
1620
|
const platform = input.platform ?? process.platform;
|
|
1502
1621
|
await mkdir5(input.binDir, { recursive: true });
|
|
1503
1622
|
if (platform === "win32") {
|
|
1504
|
-
const linkPath2 =
|
|
1623
|
+
const linkPath2 = join14(input.binDir, "omo.cmd");
|
|
1505
1624
|
await replaceRuntimeWrapper(linkPath2, windowsRuntimeWrapper(cliPath, input.codexHome, input.binDir, nodeCliPath));
|
|
1506
1625
|
return { name: "omo", path: linkPath2, target: cliPath };
|
|
1507
1626
|
}
|
|
1508
|
-
const linkPath =
|
|
1627
|
+
const linkPath = join14(input.binDir, "omo");
|
|
1509
1628
|
await replaceRuntimeWrapper(linkPath, posixRuntimeWrapper(cliPath, input.codexHome, input.binDir, nodeCliPath));
|
|
1510
1629
|
await chmod2(linkPath, 493);
|
|
1511
1630
|
return { name: "omo", path: linkPath, target: cliPath };
|
|
1512
1631
|
}
|
|
1513
1632
|
async function linkCachedPluginBin(binDir, link, platform) {
|
|
1514
1633
|
if (platform === "win32") {
|
|
1515
|
-
const linkPath2 =
|
|
1634
|
+
const linkPath2 = join14(binDir, `${link.name}.cmd`);
|
|
1516
1635
|
await replaceCommandShim(linkPath2, link.target);
|
|
1517
1636
|
return linkPath2;
|
|
1518
1637
|
}
|
|
1519
|
-
const linkPath =
|
|
1638
|
+
const linkPath = join14(binDir, link.name);
|
|
1520
1639
|
await replaceSymlink(linkPath, link.target);
|
|
1521
1640
|
return linkPath;
|
|
1522
1641
|
}
|
|
@@ -1535,16 +1654,16 @@ async function discoverPackageBins(root) {
|
|
|
1535
1654
|
return links;
|
|
1536
1655
|
}
|
|
1537
1656
|
async function collectPackageBins(directory, root, links) {
|
|
1538
|
-
const entries = await
|
|
1657
|
+
const entries = await readdir4(directory, { withFileTypes: true });
|
|
1539
1658
|
if (entries.some((entry) => entry.isFile() && entry.name === "package.json")) {
|
|
1540
|
-
await appendPackageBinLinks(
|
|
1659
|
+
await appendPackageBinLinks(join14(directory, "package.json"), directory, root, links);
|
|
1541
1660
|
}
|
|
1542
1661
|
for (const entry of entries) {
|
|
1543
1662
|
if (!entry.isDirectory())
|
|
1544
1663
|
continue;
|
|
1545
1664
|
if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "dist")
|
|
1546
1665
|
continue;
|
|
1547
|
-
const childPath =
|
|
1666
|
+
const childPath = join14(directory, entry.name);
|
|
1548
1667
|
if (!childPath.startsWith(root))
|
|
1549
1668
|
continue;
|
|
1550
1669
|
await collectPackageBins(childPath, root, links);
|
|
@@ -1603,17 +1722,17 @@ async function replaceSymlink(linkPath, targetPath) {
|
|
|
1603
1722
|
async function replaceCommandShim(linkPath, targetPath) {
|
|
1604
1723
|
if (await existingNonShim(linkPath))
|
|
1605
1724
|
throw new Error(`${linkPath} already exists and is not a command shim`);
|
|
1606
|
-
await
|
|
1725
|
+
await writeFile5(linkPath, windowsCommandShim(targetPath));
|
|
1607
1726
|
}
|
|
1608
1727
|
async function replaceRuntimeWrapper(linkPath, content) {
|
|
1609
1728
|
if (await existingNonRuntimeWrapper(linkPath))
|
|
1610
1729
|
throw new Error(`${linkPath} already exists and is not a generated OMO runtime wrapper`);
|
|
1611
1730
|
await rm9(linkPath, { force: true });
|
|
1612
|
-
await
|
|
1731
|
+
await writeFile5(linkPath, content);
|
|
1613
1732
|
}
|
|
1614
1733
|
async function existingNonRuntimeWrapper(path) {
|
|
1615
1734
|
try {
|
|
1616
|
-
const stat5 = await
|
|
1735
|
+
const stat5 = await lstat7(path);
|
|
1617
1736
|
if (stat5.isSymbolicLink())
|
|
1618
1737
|
return false;
|
|
1619
1738
|
if (!stat5.isFile())
|
|
@@ -1628,7 +1747,7 @@ async function existingNonRuntimeWrapper(path) {
|
|
|
1628
1747
|
}
|
|
1629
1748
|
async function existingNonShim(path) {
|
|
1630
1749
|
try {
|
|
1631
|
-
const stat5 = await
|
|
1750
|
+
const stat5 = await lstat7(path);
|
|
1632
1751
|
if (!stat5.isFile())
|
|
1633
1752
|
return true;
|
|
1634
1753
|
const content = await readFile8(path, "utf8");
|
|
@@ -1643,7 +1762,7 @@ async function existingNonShim(path) {
|
|
|
1643
1762
|
}
|
|
1644
1763
|
async function existingNonSymlink(path) {
|
|
1645
1764
|
try {
|
|
1646
|
-
const stat5 = await
|
|
1765
|
+
const stat5 = await lstat7(path);
|
|
1647
1766
|
if (!stat5.isSymbolicLink())
|
|
1648
1767
|
return true;
|
|
1649
1768
|
await readlink3(path);
|
|
@@ -1657,7 +1776,7 @@ async function existingNonSymlink(path) {
|
|
|
1657
1776
|
|
|
1658
1777
|
// ../src/install/codex-config-toml.ts
|
|
1659
1778
|
import { mkdir as mkdir6, readFile as readFile10 } from "node:fs/promises";
|
|
1660
|
-
import { dirname as
|
|
1779
|
+
import { dirname as dirname8 } from "node:path";
|
|
1661
1780
|
|
|
1662
1781
|
// ../src/install/toml-section-editor.ts
|
|
1663
1782
|
function findTomlSection(config, header) {
|
|
@@ -1978,6 +2097,9 @@ function stripTomlLineComment(line) {
|
|
|
1978
2097
|
var LEGACY_MANAGED_CODEX_AGENT_NAMES_TO_PURGE = ["codex-ultrawork-reviewer"];
|
|
1979
2098
|
var CURRENT_MANAGED_CODEX_AGENT_NAMES = [
|
|
1980
2099
|
"explorer",
|
|
2100
|
+
"lazycodex-worker-high",
|
|
2101
|
+
"lazycodex-worker-low",
|
|
2102
|
+
"lazycodex-worker-medium",
|
|
1981
2103
|
"librarian",
|
|
1982
2104
|
"metis",
|
|
1983
2105
|
"momus",
|
|
@@ -2015,14 +2137,14 @@ function tomlKeySegment(value) {
|
|
|
2015
2137
|
}
|
|
2016
2138
|
|
|
2017
2139
|
// ../src/install/codex-config-atomic-write.ts
|
|
2018
|
-
import { lstat as
|
|
2019
|
-
import { basename as basename5, dirname as dirname6, isAbsolute as isAbsolute4, join as
|
|
2140
|
+
import { lstat as lstat8, readlink as readlink4, realpath, rename as rename3, unlink, writeFile as writeFile6 } from "node:fs/promises";
|
|
2141
|
+
import { basename as basename5, dirname as dirname6, isAbsolute as isAbsolute4, join as join15, resolve as resolve5 } from "node:path";
|
|
2020
2142
|
var RENAME_RETRY_DELAYS_MS = [10, 25, 50];
|
|
2021
2143
|
var RETRIABLE_RENAME_CODES = new Set(["EPERM", "EBUSY"]);
|
|
2022
2144
|
async function writeFileAtomic(targetPath, data) {
|
|
2023
2145
|
const writeTarget = await resolveSymlinkTarget(targetPath);
|
|
2024
|
-
const temporaryPath =
|
|
2025
|
-
await
|
|
2146
|
+
const temporaryPath = join15(dirname6(writeTarget), `.tmp-${basename5(writeTarget)}-${process.pid}-${Date.now()}`);
|
|
2147
|
+
await writeFile6(temporaryPath, data);
|
|
2026
2148
|
try {
|
|
2027
2149
|
await renameWithRetry(temporaryPath, writeTarget);
|
|
2028
2150
|
} catch (error) {
|
|
@@ -2036,7 +2158,7 @@ async function writeFileAtomic(targetPath, data) {
|
|
|
2036
2158
|
}
|
|
2037
2159
|
async function resolveSymlinkTarget(targetPath) {
|
|
2038
2160
|
try {
|
|
2039
|
-
const linkStats = await
|
|
2161
|
+
const linkStats = await lstat8(targetPath);
|
|
2040
2162
|
if (!linkStats.isSymbolicLink())
|
|
2041
2163
|
return targetPath;
|
|
2042
2164
|
} catch (error) {
|
|
@@ -2392,15 +2514,21 @@ function isRootSetting(line, key) {
|
|
|
2392
2514
|
|
|
2393
2515
|
// ../src/install/codex-model-catalog.ts
|
|
2394
2516
|
import { readFile as readFile9 } from "node:fs/promises";
|
|
2395
|
-
import { join as
|
|
2517
|
+
import { join as join16 } from "node:path";
|
|
2396
2518
|
var FALLBACK_CODEX_MODEL_CATALOG = {
|
|
2397
2519
|
current: {
|
|
2398
|
-
model: "gpt-5.
|
|
2399
|
-
modelContextWindow:
|
|
2520
|
+
model: "gpt-5.6-sol",
|
|
2521
|
+
modelContextWindow: 372000,
|
|
2400
2522
|
modelReasoningEffort: "high",
|
|
2401
2523
|
planModeReasoningEffort: "xhigh"
|
|
2402
2524
|
},
|
|
2403
2525
|
managedProfiles: [
|
|
2526
|
+
{
|
|
2527
|
+
model: "gpt-5.5",
|
|
2528
|
+
modelContextWindow: 400000,
|
|
2529
|
+
modelReasoningEffort: "high",
|
|
2530
|
+
planModeReasoningEffort: "xhigh"
|
|
2531
|
+
},
|
|
2404
2532
|
{
|
|
2405
2533
|
model: "gpt-5.5",
|
|
2406
2534
|
modelContextWindow: 1e6,
|
|
@@ -2411,7 +2539,7 @@ var FALLBACK_CODEX_MODEL_CATALOG = {
|
|
|
2411
2539
|
]
|
|
2412
2540
|
};
|
|
2413
2541
|
async function readCodexModelCatalog(codexPackageRoot) {
|
|
2414
|
-
const catalogPath =
|
|
2542
|
+
const catalogPath = join16(codexPackageRoot, "plugin", "model-catalog.json");
|
|
2415
2543
|
try {
|
|
2416
2544
|
const parsed = JSON.parse(await readFile9(catalogPath, "utf8"));
|
|
2417
2545
|
return parseCodexModelCatalog(parsed) ?? FALLBACK_CODEX_MODEL_CATALOG;
|
|
@@ -2494,30 +2622,87 @@ function isRootSetting2(line, key) {
|
|
|
2494
2622
|
}
|
|
2495
2623
|
|
|
2496
2624
|
// ../src/install/codex-multi-agent-v2-config.ts
|
|
2625
|
+
import { readFileSync } from "node:fs";
|
|
2626
|
+
import { dirname as dirname7, isAbsolute as isAbsolute5, join as join17 } from "node:path";
|
|
2497
2627
|
var CODEX_AGENTS_HEADER = "agents";
|
|
2498
2628
|
var CODEX_MULTI_AGENT_V2_HEADER = "features.multi_agent_v2";
|
|
2499
2629
|
var CODEX_SUBAGENT_THREAD_LIMIT = 1000;
|
|
2500
|
-
function ensureCodexMultiAgentV2Config(config) {
|
|
2630
|
+
function ensureCodexMultiAgentV2Config(config, options = {}) {
|
|
2501
2631
|
const featureFlag = removeFeatureFlagSetting(config, "multi_agent_v2");
|
|
2502
|
-
const
|
|
2503
|
-
const
|
|
2632
|
+
const v2Preferred = options.multiAgentVersion === "v2";
|
|
2633
|
+
const modelKnown = options.multiAgentVersion != null || readRootModel(featureFlag.config) !== null;
|
|
2634
|
+
const agentsConfig = v2Preferred ? removeAgentsMaxThreads(featureFlag.config) : modelKnown ? ensureAgentsMaxThreads(featureFlag.config) : raiseExistingAgentsMaxThreads(featureFlag.config);
|
|
2504
2635
|
const maxThreadsValue = CODEX_SUBAGENT_THREAD_LIMIT.toString();
|
|
2636
|
+
const preserveDisable = featureFlag.value === false && !v2Preferred;
|
|
2637
|
+
const featureConfig = preserveDisable ? setMultiAgentV2Disable(agentsConfig) : v2Preferred ? removeMultiAgentV2Disable(agentsConfig) : agentsConfig;
|
|
2638
|
+
const section = findTomlSection(featureConfig, CODEX_MULTI_AGENT_V2_HEADER);
|
|
2505
2639
|
if (!section) {
|
|
2506
|
-
const enabledSetting =
|
|
2640
|
+
const enabledSetting = preserveDisable ? `enabled = false
|
|
2507
2641
|
` : "";
|
|
2508
|
-
return appendBlock(
|
|
2642
|
+
return appendBlock(featureConfig, `[${CODEX_MULTI_AGENT_V2_HEADER}]
|
|
2509
2643
|
${enabledSetting}max_concurrent_threads_per_session = ${maxThreadsValue}
|
|
2510
2644
|
`);
|
|
2511
2645
|
}
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2646
|
+
return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session", maxThreadsValue);
|
|
2647
|
+
}
|
|
2648
|
+
function resolveCodexMultiAgentVersion(config, configPath) {
|
|
2649
|
+
const model = readRootModel(config);
|
|
2650
|
+
if (model === null)
|
|
2651
|
+
return null;
|
|
2652
|
+
const catalogPath = resolveCatalogPath(readRootModelCatalogPath(config), configPath);
|
|
2653
|
+
const catalogVersion = readCatalogMultiAgentVersion(model, catalogPath);
|
|
2654
|
+
if (catalogVersion !== null)
|
|
2655
|
+
return catalogVersion;
|
|
2656
|
+
return /^gpt-5\.6\b/i.test(model) ? "v2" : null;
|
|
2657
|
+
}
|
|
2658
|
+
function resolveCatalogPath(configuredPath, configPath) {
|
|
2659
|
+
if (configuredPath === null)
|
|
2660
|
+
return join17(dirname7(configPath), "models_cache.json");
|
|
2661
|
+
return isAbsolute5(configuredPath) ? configuredPath : join17(dirname7(configPath), configuredPath);
|
|
2662
|
+
}
|
|
2663
|
+
function readCatalogMultiAgentVersion(model, cachePath) {
|
|
2664
|
+
let raw;
|
|
2665
|
+
try {
|
|
2666
|
+
raw = readFileSync(cachePath, "utf8");
|
|
2667
|
+
} catch {
|
|
2668
|
+
return null;
|
|
2669
|
+
}
|
|
2670
|
+
let cache;
|
|
2671
|
+
try {
|
|
2672
|
+
cache = JSON.parse(raw);
|
|
2673
|
+
} catch {
|
|
2674
|
+
return null;
|
|
2519
2675
|
}
|
|
2520
|
-
|
|
2676
|
+
if (!isRecord2(cache) || !Array.isArray(cache.models))
|
|
2677
|
+
return null;
|
|
2678
|
+
for (const entry of cache.models) {
|
|
2679
|
+
if (!isRecord2(entry))
|
|
2680
|
+
continue;
|
|
2681
|
+
if (entry.slug !== model && entry.id !== model)
|
|
2682
|
+
continue;
|
|
2683
|
+
const version = entry.multi_agent_version;
|
|
2684
|
+
if (version === "v1" || version === "v2")
|
|
2685
|
+
return version;
|
|
2686
|
+
return null;
|
|
2687
|
+
}
|
|
2688
|
+
return null;
|
|
2689
|
+
}
|
|
2690
|
+
function readRootModel(config) {
|
|
2691
|
+
const double = config.match(/^\s*model\s*=\s*"([^"]+)"/m);
|
|
2692
|
+
if (double !== null)
|
|
2693
|
+
return double[1] ?? null;
|
|
2694
|
+
const single = config.match(/^\s*model\s*=\s*'([^']+)'/m);
|
|
2695
|
+
return single?.[1] ?? null;
|
|
2696
|
+
}
|
|
2697
|
+
function readRootModelCatalogPath(config) {
|
|
2698
|
+
const double = config.match(/^\s*model_catalog_json\s*=\s*"([^"]+)"/m);
|
|
2699
|
+
if (double !== null)
|
|
2700
|
+
return double[1] ?? null;
|
|
2701
|
+
const single = config.match(/^\s*model_catalog_json\s*=\s*'([^']+)'/m);
|
|
2702
|
+
return single?.[1] ?? null;
|
|
2703
|
+
}
|
|
2704
|
+
function isRecord2(value) {
|
|
2705
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2521
2706
|
}
|
|
2522
2707
|
function removeFeatureFlagSetting(config, featureName) {
|
|
2523
2708
|
const section = findTomlSection(config, "features");
|
|
@@ -2538,6 +2723,36 @@ max_threads = ${maxThreadsValue}
|
|
|
2538
2723
|
}
|
|
2539
2724
|
return replaceOrInsertSetting(config, section, "max_threads", maxThreadsValue);
|
|
2540
2725
|
}
|
|
2726
|
+
function removeAgentsMaxThreads(config) {
|
|
2727
|
+
const section = findTomlSection(config, CODEX_AGENTS_HEADER);
|
|
2728
|
+
if (!section)
|
|
2729
|
+
return config;
|
|
2730
|
+
if (!/^\s*max_threads\s*=/m.test(section.text))
|
|
2731
|
+
return config;
|
|
2732
|
+
return removeSetting(config, section, "max_threads");
|
|
2733
|
+
}
|
|
2734
|
+
function removeMultiAgentV2Disable(config) {
|
|
2735
|
+
const section = findTomlSection(config, CODEX_MULTI_AGENT_V2_HEADER);
|
|
2736
|
+
if (!section)
|
|
2737
|
+
return config;
|
|
2738
|
+
if (!/^\s*enabled\s*=\s*false(?:\s*#.*)?$/m.test(section.text))
|
|
2739
|
+
return config;
|
|
2740
|
+
return removeSetting(config, section, "enabled");
|
|
2741
|
+
}
|
|
2742
|
+
function setMultiAgentV2Disable(config) {
|
|
2743
|
+
const section = findTomlSection(config, CODEX_MULTI_AGENT_V2_HEADER);
|
|
2744
|
+
if (!section)
|
|
2745
|
+
return config;
|
|
2746
|
+
return replaceOrInsertSetting(config, section, "enabled", "false");
|
|
2747
|
+
}
|
|
2748
|
+
function raiseExistingAgentsMaxThreads(config) {
|
|
2749
|
+
const section = findTomlSection(config, CODEX_AGENTS_HEADER);
|
|
2750
|
+
if (!section)
|
|
2751
|
+
return config;
|
|
2752
|
+
if (!/^\s*max_threads\s*=/m.test(section.text))
|
|
2753
|
+
return config;
|
|
2754
|
+
return replaceOrInsertSetting(config, section, "max_threads", CODEX_SUBAGENT_THREAD_LIMIT.toString());
|
|
2755
|
+
}
|
|
2541
2756
|
function readBooleanSetting(sectionText, key) {
|
|
2542
2757
|
const match = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=\\s*(true|false)\\s*(?:#.*)?$`, "m").exec(sectionText);
|
|
2543
2758
|
if (!match)
|
|
@@ -2547,7 +2762,7 @@ function readBooleanSetting(sectionText, key) {
|
|
|
2547
2762
|
|
|
2548
2763
|
// ../src/install/codex-config-toml.ts
|
|
2549
2764
|
async function updateCodexConfig(input) {
|
|
2550
|
-
await mkdir6(
|
|
2765
|
+
await mkdir6(dirname8(input.configPath), { recursive: true });
|
|
2551
2766
|
let config;
|
|
2552
2767
|
try {
|
|
2553
2768
|
config = await readFile10(input.configPath, "utf8");
|
|
@@ -2570,7 +2785,9 @@ async function updateCodexConfig(input) {
|
|
|
2570
2785
|
config = ensureFeatureEnabled(config, "multi_agent");
|
|
2571
2786
|
config = removeUnsupportedCodexMultiAgentModeConfig(config);
|
|
2572
2787
|
config = ensureCodexReasoningConfig(config, await readCodexModelCatalog(input.repoRoot));
|
|
2573
|
-
config = ensureCodexMultiAgentV2Config(config
|
|
2788
|
+
config = ensureCodexMultiAgentV2Config(config, {
|
|
2789
|
+
multiAgentVersion: resolveCodexMultiAgentVersion(config, input.configPath)
|
|
2790
|
+
});
|
|
2574
2791
|
if (input.autonomousPermissions === true)
|
|
2575
2792
|
config = ensureAutonomousPermissions(config);
|
|
2576
2793
|
if (!(input.preserveMarketplaceSource === true && hasMarketplaceBlock(config, input.marketplaceName))) {
|
|
@@ -2594,12 +2811,12 @@ function isMissingFileError(error) {
|
|
|
2594
2811
|
}
|
|
2595
2812
|
|
|
2596
2813
|
// ../src/install/codex-git-bash-mcp-env.ts
|
|
2597
|
-
import { readFile as readFile11, writeFile as
|
|
2598
|
-
import { join as
|
|
2814
|
+
import { readFile as readFile11, writeFile as writeFile7 } from "node:fs/promises";
|
|
2815
|
+
import { join as join18 } from "node:path";
|
|
2599
2816
|
var GIT_BASH_ENV_KEY = "OMO_CODEX_GIT_BASH_PATH";
|
|
2600
2817
|
var CODEGRAPH_RELATIVE_ARGS = new Set(["components/codegraph/dist/serve.js", "./components/codegraph/dist/serve.js"]);
|
|
2601
2818
|
async function stampGitBashMcpEnv(input) {
|
|
2602
|
-
const manifestPath =
|
|
2819
|
+
const manifestPath = join18(input.pluginRoot, ".mcp.json");
|
|
2603
2820
|
if (!await fileExistsStrict(manifestPath))
|
|
2604
2821
|
return false;
|
|
2605
2822
|
const parsed = JSON.parse(await readFile11(manifestPath, "utf8"));
|
|
@@ -2620,7 +2837,7 @@ async function stampGitBashMcpEnv(input) {
|
|
|
2620
2837
|
}
|
|
2621
2838
|
if (!changed)
|
|
2622
2839
|
return false;
|
|
2623
|
-
await
|
|
2840
|
+
await writeFile7(manifestPath, `${JSON.stringify(parsed, null, "\t")}
|
|
2624
2841
|
`);
|
|
2625
2842
|
return true;
|
|
2626
2843
|
}
|
|
@@ -2632,14 +2849,14 @@ function stampCodegraphMcpPath(mcpServers, pluginRoot) {
|
|
|
2632
2849
|
const entrypoint = args[0];
|
|
2633
2850
|
if (typeof entrypoint !== "string" || !CODEGRAPH_RELATIVE_ARGS.has(entrypoint))
|
|
2634
2851
|
return false;
|
|
2635
|
-
codegraphServer["args"] = [
|
|
2852
|
+
codegraphServer["args"] = [join18(pluginRoot, "components", "codegraph", "dist", "serve.js"), ...args.slice(1)];
|
|
2636
2853
|
return true;
|
|
2637
2854
|
}
|
|
2638
2855
|
|
|
2639
2856
|
// ../src/install/codex-hook-trust.ts
|
|
2640
2857
|
import { createHash as createHash3 } from "node:crypto";
|
|
2641
2858
|
import { readFile as readFile12 } from "node:fs/promises";
|
|
2642
|
-
import { join as
|
|
2859
|
+
import { join as join19 } from "node:path";
|
|
2643
2860
|
var EVENT_LABELS = new Map([
|
|
2644
2861
|
["PreToolUse", "pre_tool_use"],
|
|
2645
2862
|
["PermissionRequest", "permission_request"],
|
|
@@ -2653,16 +2870,16 @@ var EVENT_LABELS = new Map([
|
|
|
2653
2870
|
["Stop", "stop"]
|
|
2654
2871
|
]);
|
|
2655
2872
|
async function trustedHookStatesForPlugin(input) {
|
|
2656
|
-
const manifestPath =
|
|
2657
|
-
if (!await
|
|
2873
|
+
const manifestPath = join19(input.pluginRoot, ".codex-plugin", "plugin.json");
|
|
2874
|
+
if (!await exists4(manifestPath))
|
|
2658
2875
|
return [];
|
|
2659
2876
|
const manifest = JSON.parse(await readFile12(manifestPath, "utf8"));
|
|
2660
2877
|
if (!isPlainRecord(manifest))
|
|
2661
2878
|
return [];
|
|
2662
2879
|
const states = [];
|
|
2663
2880
|
for (const hookPath of hookManifestPaths(manifest.hooks)) {
|
|
2664
|
-
const hooksPath =
|
|
2665
|
-
if (!await
|
|
2881
|
+
const hooksPath = join19(input.pluginRoot, hookPath);
|
|
2882
|
+
if (!await exists4(hooksPath))
|
|
2666
2883
|
continue;
|
|
2667
2884
|
const parsed = JSON.parse(await readFile12(hooksPath, "utf8"));
|
|
2668
2885
|
if (!isPlainRecord(parsed) || !isPlainRecord(parsed.hooks))
|
|
@@ -2745,7 +2962,7 @@ function canonicalJson(value) {
|
|
|
2745
2962
|
function stripDotSlash(value) {
|
|
2746
2963
|
return value.startsWith("./") ? value.slice(2) : value;
|
|
2747
2964
|
}
|
|
2748
|
-
async function
|
|
2965
|
+
async function exists4(path) {
|
|
2749
2966
|
try {
|
|
2750
2967
|
await readFile12(path, "utf8");
|
|
2751
2968
|
return true;
|
|
@@ -2758,7 +2975,7 @@ async function exists3(path) {
|
|
|
2758
2975
|
|
|
2759
2976
|
// ../src/install/codex-installer-bin-dir.ts
|
|
2760
2977
|
import { homedir as homedir3 } from "node:os";
|
|
2761
|
-
import { join as
|
|
2978
|
+
import { join as join20, resolve as resolve6 } from "node:path";
|
|
2762
2979
|
function resolveCodexInstallerBinDir(input) {
|
|
2763
2980
|
const explicitBinDir = input.binDir ?? input.env?.CODEX_LOCAL_BIN_DIR;
|
|
2764
2981
|
if (explicitBinDir !== undefined && explicitBinDir.trim().length > 0)
|
|
@@ -2767,7 +2984,7 @@ function resolveCodexInstallerBinDir(input) {
|
|
|
2767
2984
|
const defaultCodexHome = resolve6(homeDir, ".codex");
|
|
2768
2985
|
const resolvedCodexHome = resolve6(input.codexHome);
|
|
2769
2986
|
if (resolvedCodexHome !== defaultCodexHome)
|
|
2770
|
-
return
|
|
2987
|
+
return join20(resolvedCodexHome, "bin");
|
|
2771
2988
|
return resolve6(homeDir, ".local", "bin");
|
|
2772
2989
|
}
|
|
2773
2990
|
|
|
@@ -2923,9 +3140,9 @@ async function resolveGitBashStep(options, degraded) {
|
|
|
2923
3140
|
return false;
|
|
2924
3141
|
}
|
|
2925
3142
|
async function linkBundledAgentsStep(options) {
|
|
2926
|
-
const agentsTarget =
|
|
3143
|
+
const agentsTarget = join21(options.codexHome, "agents");
|
|
2927
3144
|
try {
|
|
2928
|
-
const stageRoot =
|
|
3145
|
+
const stageRoot = join21(options.pluginData, "bootstrap", "agents-stage");
|
|
2929
3146
|
await stageBundledAgents(options.pluginRoot, stageRoot);
|
|
2930
3147
|
const preservedReasoning = await capturePreservedAgentReasoning({ codexHome: options.codexHome });
|
|
2931
3148
|
const preservedServiceTier = await capturePreservedAgentServiceTier({ codexHome: options.codexHome });
|
|
@@ -2935,7 +3152,7 @@ async function linkBundledAgentsStep(options) {
|
|
|
2935
3152
|
preservedReasoning,
|
|
2936
3153
|
preservedServiceTier
|
|
2937
3154
|
});
|
|
2938
|
-
const agentConfigs = linked.map((link) => ({ configFile: `./agents/${link.name}`, name:
|
|
3155
|
+
const agentConfigs = linked.map((link) => ({ configFile: `./agents/${link.name}`, name: agentNameFromToml3(link.name) })).sort((left, right) => left.name.localeCompare(right.name));
|
|
2939
3156
|
return { agentConfigs, degraded: [] };
|
|
2940
3157
|
} catch (error) {
|
|
2941
3158
|
return {
|
|
@@ -2953,21 +3170,21 @@ async function linkBundledAgentsStep(options) {
|
|
|
2953
3170
|
async function stageBundledAgents(pluginRoot, stageRoot) {
|
|
2954
3171
|
await rm10(stageRoot, { force: true, recursive: true });
|
|
2955
3172
|
await mkdir7(stageRoot, { recursive: true });
|
|
2956
|
-
const componentsRoot =
|
|
3173
|
+
const componentsRoot = join21(pluginRoot, "components");
|
|
2957
3174
|
for (const componentName of await directoryNames(componentsRoot)) {
|
|
2958
|
-
const agentsDir =
|
|
3175
|
+
const agentsDir = join21(componentsRoot, componentName, "agents");
|
|
2959
3176
|
const agentFiles = (await fileNames(agentsDir)).filter((name) => name.endsWith(".toml"));
|
|
2960
3177
|
if (agentFiles.length === 0)
|
|
2961
3178
|
continue;
|
|
2962
|
-
const stagedAgentsDir =
|
|
3179
|
+
const stagedAgentsDir = join21(stageRoot, "components", componentName, "agents");
|
|
2963
3180
|
await mkdir7(stagedAgentsDir, { recursive: true });
|
|
2964
3181
|
for (const agentFile of agentFiles) {
|
|
2965
|
-
await copyFile2(
|
|
3182
|
+
await copyFile2(join21(agentsDir, agentFile), join21(stagedAgentsDir, agentFile));
|
|
2966
3183
|
}
|
|
2967
3184
|
}
|
|
2968
3185
|
}
|
|
2969
3186
|
async function updateConfigStep(options, inputs, degraded) {
|
|
2970
|
-
const configPath =
|
|
3187
|
+
const configPath = join21(options.codexHome, "config.toml");
|
|
2971
3188
|
try {
|
|
2972
3189
|
await assertWritableConfigIfPresent(configPath);
|
|
2973
3190
|
const trustedHookStates = await trustedHookStatesForPlugin({
|
|
@@ -3023,7 +3240,7 @@ async function linkComponentBinsStep(options, degraded) {
|
|
|
3023
3240
|
await linkRuntimeWrapperStep(options, binDir, degraded);
|
|
3024
3241
|
}
|
|
3025
3242
|
async function linkRuntimeWrapperStep(options, binDir, degraded) {
|
|
3026
|
-
const cliPath =
|
|
3243
|
+
const cliPath = join21(options.pluginRoot, "dist", "cli", "index.js");
|
|
3027
3244
|
try {
|
|
3028
3245
|
const linked = await linkRootRuntimeBin({
|
|
3029
3246
|
binDir,
|
|
@@ -3056,7 +3273,7 @@ async function stampGitBashEnvStep(options, degraded) {
|
|
|
3056
3273
|
degraded.push({
|
|
3057
3274
|
component: "git-bash-env",
|
|
3058
3275
|
hint: BOOTSTRAP_DOCTOR_HINT,
|
|
3059
|
-
reason: `failed to stamp ${
|
|
3276
|
+
reason: `failed to stamp ${join21(options.pluginRoot, ".mcp.json")}: ${errorMessage(error)}`
|
|
3060
3277
|
});
|
|
3061
3278
|
}
|
|
3062
3279
|
}
|
|
@@ -3068,7 +3285,7 @@ async function fileNames(root) {
|
|
|
3068
3285
|
}
|
|
3069
3286
|
async function entryNames(root, keep) {
|
|
3070
3287
|
try {
|
|
3071
|
-
const entries = await
|
|
3288
|
+
const entries = await readdir5(root, { withFileTypes: true });
|
|
3072
3289
|
return entries.filter((entry) => keep(entry)).map((entry) => entry.name).sort();
|
|
3073
3290
|
} catch (error) {
|
|
3074
3291
|
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
@@ -3076,7 +3293,7 @@ async function entryNames(root, keep) {
|
|
|
3076
3293
|
throw error;
|
|
3077
3294
|
}
|
|
3078
3295
|
}
|
|
3079
|
-
function
|
|
3296
|
+
function agentNameFromToml3(fileName) {
|
|
3080
3297
|
return fileName.endsWith(".toml") ? fileName.slice(0, -".toml".length) : fileName;
|
|
3081
3298
|
}
|
|
3082
3299
|
function errorMessage(error) {
|
|
@@ -3124,11 +3341,11 @@ function resolvePluginDataRoot(env) {
|
|
|
3124
3341
|
const fromEnv = env["PLUGIN_DATA"]?.trim();
|
|
3125
3342
|
if (fromEnv !== undefined && fromEnv.length > 0)
|
|
3126
3343
|
return fromEnv;
|
|
3127
|
-
return
|
|
3344
|
+
return join22(homedir4(), ".local", "share", "lazycodex");
|
|
3128
3345
|
}
|
|
3129
3346
|
async function readPluginVersion(pluginRoot) {
|
|
3130
3347
|
try {
|
|
3131
|
-
const parsed = JSON.parse(await readFile13(
|
|
3348
|
+
const parsed = JSON.parse(await readFile13(join22(pluginRoot, ".codex-plugin", "plugin.json"), "utf8"));
|
|
3132
3349
|
if (typeof parsed !== "object" || parsed === null)
|
|
3133
3350
|
return;
|
|
3134
3351
|
const version = parsed["version"];
|
|
@@ -3195,7 +3412,7 @@ async function runBootstrapWorker(options = {}) {
|
|
|
3195
3412
|
degraded.push({
|
|
3196
3413
|
component: "bootstrap",
|
|
3197
3414
|
hint: BOOTSTRAP_DOCTOR_HINT,
|
|
3198
|
-
reason: `plugin version unresolved from ${
|
|
3415
|
+
reason: `plugin version unresolved from ${join22(pluginRoot, ".codex-plugin", "plugin.json")}`
|
|
3199
3416
|
});
|
|
3200
3417
|
}
|
|
3201
3418
|
for (const step of steps) {
|
|
@@ -3234,12 +3451,12 @@ function resolvePluginRoot(env) {
|
|
|
3234
3451
|
const fromEnv = env["PLUGIN_ROOT"]?.trim();
|
|
3235
3452
|
if (fromEnv !== undefined && fromEnv.length > 0)
|
|
3236
3453
|
return fromEnv;
|
|
3237
|
-
return resolve7(
|
|
3454
|
+
return resolve7(dirname9(fileURLToPath2(import.meta.url)), "..", "..", "..");
|
|
3238
3455
|
}
|
|
3239
3456
|
async function appendBootstrapLog(pluginData, now, event, details) {
|
|
3240
3457
|
try {
|
|
3241
|
-
const logPath =
|
|
3242
|
-
await mkdir8(
|
|
3458
|
+
const logPath = join22(pluginData, "bootstrap", "bootstrap.log");
|
|
3459
|
+
await mkdir8(dirname9(logPath), { recursive: true });
|
|
3243
3460
|
await appendFile2(logPath, `${JSON.stringify({ timestamp: new Date(now).toISOString(), event, ...details })}
|
|
3244
3461
|
`);
|
|
3245
3462
|
} catch {}
|