oh-my-opencode 4.18.1 → 4.19.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/skills/codex-qa/scripts/lsp-e2e.sh +39 -16
- package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +111 -28
- package/README.ja.md +2 -2
- package/README.ko.md +2 -2
- package/README.md +4 -4
- package/README.ru.md +2 -2
- package/README.zh-cn.md +2 -2
- package/bin/AGENTS.md +33 -0
- package/dist/agents/atlas/agent.d.ts +6 -5
- package/dist/agents/sisyphus/index.d.ts +5 -0
- package/dist/agents/sisyphus/kimi-k3.d.ts +19 -0
- package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
- package/dist/agents/sisyphus-junior/agent.d.ts +8 -4
- package/dist/agents/sisyphus-junior/index.d.ts +2 -0
- package/dist/agents/sisyphus-junior/kimi-k3.d.ts +12 -0
- package/dist/agents/types.d.ts +2 -2
- package/dist/cli/index.js +690 -139
- package/dist/cli-node/index.js +690 -139
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schema/browser-automation.d.ts +1 -0
- package/dist/config/schema/commands.d.ts +1 -3
- package/dist/config/schema/default-mode.d.ts +1 -1
- package/dist/config/schema/goal.d.ts +7 -0
- package/dist/config/schema/hooks.d.ts +1 -1
- package/dist/config/schema/oh-my-opencode-config.d.ts +6 -10
- package/dist/config/schema/ralph-loop.d.ts +1 -1
- package/dist/config/schema.d.ts +1 -1
- package/dist/create-hooks.d.ts +1 -1
- package/dist/features/builtin-commands/templates/goal.d.ts +1 -0
- package/dist/features/builtin-commands/templates/stop-continuation.d.ts +1 -1
- package/dist/features/builtin-commands/types.d.ts +1 -1
- package/dist/hooks/anthropic-context-window-limit-recovery/empty-content-recovery-sdk.d.ts +6 -0
- package/dist/hooks/auto-slash-command/executor.d.ts +1 -0
- package/dist/hooks/category-skill-reminder/hook.d.ts +9 -1
- package/dist/hooks/comment-checker/hook.d.ts +8 -1
- package/dist/hooks/goal/command-arguments.d.ts +13 -0
- package/dist/hooks/goal/controller.d.ts +26 -0
- package/dist/hooks/goal/index.d.ts +23 -0
- package/dist/hooks/goal/prompt.d.ts +3 -0
- package/dist/hooks/goal/store.d.ts +8 -0
- package/dist/hooks/goal/tools.d.ts +10 -0
- package/dist/hooks/goal/types.d.ts +93 -0
- package/dist/hooks/goal/validation.d.ts +4 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/keyword-detector/hook.d.ts +1 -2
- package/dist/hooks/ralph-loop/types.d.ts +1 -1
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +3 -0
- package/dist/index.js +3706 -4329
- package/dist/oh-my-opencode.schema.json +23 -19
- package/dist/plugin/chat-message/loop-commands.d.ts +1 -1
- package/dist/plugin/chat-message/types.d.ts +23 -10
- package/dist/plugin/hooks/create-core-hooks.d.ts +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +3 -2
- package/dist/plugin/hooks/create-transform-hooks.d.ts +0 -2
- package/dist/plugin/messages-transform.d.ts +1 -0
- package/dist/plugin/stop-continuation.d.ts +2 -2
- package/dist/plugin-handlers/prometheus-agent-config-builder.d.ts +2 -0
- package/dist/shared/system-directive.d.ts +0 -1
- package/dist/skills/ulw-plan/SKILL.md +11 -7
- package/dist/skills/ulw-plan/references/full-workflow.md +117 -6
- package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
- package/dist/skills/ulw-research/SKILL.md +3 -3
- package/dist/tools/delegate-task/types.d.ts +0 -1
- package/dist/tui.js +115 -28
- package/package.json +14 -14
- package/packages/git-bash-mcp/dist/cli.js +81 -19
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +4 -4
- package/packages/lsp-core/src/lsp/directory-diagnostics.test.ts +118 -1
- package/packages/lsp-core/src/lsp/directory-diagnostics.ts +1 -1
- package/packages/lsp-daemon/dist/cli.js +262 -63
- package/packages/lsp-daemon/dist/client.js +194 -50
- package/packages/lsp-daemon/dist/daemon-client.d.ts +2 -2
- package/packages/lsp-daemon/dist/daemon-client.js +26 -2
- package/packages/lsp-daemon/dist/ensure-daemon.d.ts +5 -4
- package/packages/lsp-daemon/dist/ensure-daemon.js +79 -18
- package/packages/lsp-daemon/dist/index.js +262 -63
- package/packages/lsp-daemon/dist/proxy.d.ts +2 -0
- package/packages/lsp-daemon/dist/proxy.js +79 -23
- package/packages/lsp-tools-mcp/dist/cli.js +82 -20
- package/packages/lsp-tools-mcp/dist/mcp.js +82 -20
- package/packages/lsp-tools-mcp/dist/tools.js +1 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/.mcp.json +2 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +352 -17
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +7 -6
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +195 -56
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +100 -28
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +21 -9
- package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +1 -1
- package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +35 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +69 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +57 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/.mcp.json +2 -1
- package/packages/omo-codex/plugin/components/lsp/AGENTS.md +1 -0
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +113 -31
- 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 +1 -0
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.5.md +1 -1
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.6.md +5 -3
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +8 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/README.md +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +3 -3
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +148 -61
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +4 -72
- package/packages/omo-codex/plugin/components/start-work-continuation/src/codex-hook.ts +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/src/plan-checklist.ts +171 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +213 -24
- package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +4 -3
- package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +25 -4
- package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-scaffold.md +15 -0
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -10
- package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +3 -3
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +50 -33
- 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 +50 -33
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +11 -7
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +117 -6
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +50 -33
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +3 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +5 -6
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +5 -6
- package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +2 -2
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +13 -13
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +32 -28
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +17 -45
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +455 -0
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +13 -20
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +7 -0
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +3 -2
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +50 -33
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +11 -7
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +117 -6
- package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
- package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +2 -2
- package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +2 -2
- package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -0
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +6 -6
- package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +3 -3
- package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +62 -0
- package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +271 -14
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +7 -0
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +38 -22
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +0 -5
- package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +293 -0
- package/packages/omo-codex/scripts/install-config.test.mjs +10 -10
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +353 -18
- package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +39 -2
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +11 -7
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +117 -6
- package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
- package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -3
- package/dist/features/builtin-commands/templates/ralph-loop.d.ts +0 -3
- package/dist/skills/ultraresearch/SKILL.md +0 -10
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +0 -273
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -12
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -107
- package/packages/shared-skills/skills/lcx-doctor/SKILL.md +0 -128
- package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +0 -11
- package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +0 -268
- package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +0 -11
- package/packages/shared-skills/skills/ultraresearch/SKILL.md +0 -10
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/SKILL.md +0 -0
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -0
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -0
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/SKILL.md +0 -0
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/agents/openai.yaml +0 -0
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/SKILL.md +0 -0
- /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/agents/openai.yaml +0 -0
|
@@ -882,9 +882,16 @@ function findTomlSection(config, header) {
|
|
|
882
882
|
const lines = config.match(/[^\n]*\n?|$/g) ?? [];
|
|
883
883
|
let offset = 0;
|
|
884
884
|
let start = -1;
|
|
885
|
+
let multilineQuote = null;
|
|
885
886
|
for (const line of lines) {
|
|
886
887
|
if (line.length === 0)
|
|
887
888
|
break;
|
|
889
|
+
const multilineScan = scanTomlMultilineLine(line, multilineQuote);
|
|
890
|
+
multilineQuote = multilineScan.nextQuote;
|
|
891
|
+
if (multilineScan.wasInside) {
|
|
892
|
+
offset += line.length;
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
888
895
|
const trimmed = line.trim();
|
|
889
896
|
if (start === -1) {
|
|
890
897
|
if (tomlTableHeaderMatches(trimmed, headerLine, targetHeaderPath))
|
|
@@ -899,8 +906,37 @@ function findTomlSection(config, header) {
|
|
|
899
906
|
return { start, end: config.length, text: config.slice(start) };
|
|
900
907
|
}
|
|
901
908
|
function replaceOrInsertSetting(config, section, key, value) {
|
|
902
|
-
const
|
|
903
|
-
|
|
909
|
+
const targetPath = parseTomlDottedKey(key);
|
|
910
|
+
if (!targetPath)
|
|
911
|
+
return config;
|
|
912
|
+
const lines = section.text.match(/[^\n]*\n?|$/g) ?? [];
|
|
913
|
+
let offset = 0;
|
|
914
|
+
let multilineQuote = null;
|
|
915
|
+
for (const line of lines) {
|
|
916
|
+
if (line.length === 0)
|
|
917
|
+
break;
|
|
918
|
+
const multilineScan = scanTomlMultilineLine(line, multilineQuote);
|
|
919
|
+
multilineQuote = multilineScan.nextQuote;
|
|
920
|
+
if (multilineScan.wasInside) {
|
|
921
|
+
offset += line.length;
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
const assignmentIndex = findUnquotedAssignment(line);
|
|
925
|
+
if (assignmentIndex < 0) {
|
|
926
|
+
offset += line.length;
|
|
927
|
+
continue;
|
|
928
|
+
}
|
|
929
|
+
const settingPath = parseTomlDottedKey(line.slice(0, assignmentIndex).trim());
|
|
930
|
+
if (!settingPath || !tomlPathMatches(settingPath, targetPath)) {
|
|
931
|
+
offset += line.length;
|
|
932
|
+
continue;
|
|
933
|
+
}
|
|
934
|
+
const replacement2 = replaceTomlAssignmentValue(line, assignmentIndex, value);
|
|
935
|
+
const assignmentEnd = multilineScan.nextQuote ? findTomlMultilineValueEnd(section.text, offset + line.length, multilineScan.nextQuote) : offset + line.length;
|
|
936
|
+
const sectionReplacement = section.text.slice(0, offset) + replacement2 + section.text.slice(assignmentEnd);
|
|
937
|
+
return config.slice(0, section.start) + sectionReplacement + config.slice(section.end);
|
|
938
|
+
}
|
|
939
|
+
const replacement = insertSetting(section.text, key, value);
|
|
904
940
|
return config.slice(0, section.start) + replacement + config.slice(section.end);
|
|
905
941
|
}
|
|
906
942
|
function removeSetting(config, section, key) {
|
|
@@ -920,6 +956,50 @@ function replaceOrInsertRootSetting(config, key, value) {
|
|
|
920
956
|
return replacement;
|
|
921
957
|
return `${replacement.trimEnd()}
|
|
922
958
|
|
|
959
|
+
${suffix.trimStart()}`;
|
|
960
|
+
}
|
|
961
|
+
function replaceOrInsertRootDottedSetting(config, keyPath, value) {
|
|
962
|
+
const targetPath = parseTomlDottedKey(keyPath);
|
|
963
|
+
if (!targetPath)
|
|
964
|
+
return config;
|
|
965
|
+
const lines = config.match(/[^\n]*\n?|$/g) ?? [];
|
|
966
|
+
let offset = 0;
|
|
967
|
+
let multilineQuote = null;
|
|
968
|
+
for (const line of lines) {
|
|
969
|
+
if (line.length === 0)
|
|
970
|
+
break;
|
|
971
|
+
const multilineScan = scanTomlMultilineLine(line, multilineQuote);
|
|
972
|
+
multilineQuote = multilineScan.nextQuote;
|
|
973
|
+
if (multilineScan.wasInside) {
|
|
974
|
+
offset += line.length;
|
|
975
|
+
continue;
|
|
976
|
+
}
|
|
977
|
+
if (isTomlTableHeaderLine(line))
|
|
978
|
+
break;
|
|
979
|
+
const assignmentIndex = findUnquotedAssignment(line);
|
|
980
|
+
if (assignmentIndex < 0) {
|
|
981
|
+
offset += line.length;
|
|
982
|
+
continue;
|
|
983
|
+
}
|
|
984
|
+
const settingPath = parseTomlDottedKey(line.slice(0, assignmentIndex).trim());
|
|
985
|
+
if (!settingPath || !tomlPathMatches(settingPath, targetPath)) {
|
|
986
|
+
offset += line.length;
|
|
987
|
+
continue;
|
|
988
|
+
}
|
|
989
|
+
const replacement2 = replaceTomlAssignmentValue(line, assignmentIndex, value);
|
|
990
|
+
const assignmentEnd = multilineScan.nextQuote ? findTomlMultilineValueEnd(config, offset + line.length, multilineScan.nextQuote) : offset + line.length;
|
|
991
|
+
return config.slice(0, offset) + replacement2 + config.slice(assignmentEnd);
|
|
992
|
+
}
|
|
993
|
+
const sectionStart = findFirstTableStart(config);
|
|
994
|
+
const root = config.slice(0, sectionStart).trimEnd();
|
|
995
|
+
const suffix = config.slice(sectionStart);
|
|
996
|
+
const replacement = `${root}${root.length > 0 ? `
|
|
997
|
+
` : ""}${keyPath} = ${value}
|
|
998
|
+
`;
|
|
999
|
+
if (suffix.length === 0)
|
|
1000
|
+
return replacement;
|
|
1001
|
+
return `${replacement.trimEnd()}
|
|
1002
|
+
|
|
923
1003
|
${suffix.trimStart()}`;
|
|
924
1004
|
}
|
|
925
1005
|
function appendBlock(config, block) {
|
|
@@ -932,9 +1012,16 @@ function appendBlock(config, block) {
|
|
|
932
1012
|
function findFirstTableStart(config) {
|
|
933
1013
|
const lines = config.match(/[^\n]*\n?|$/g) ?? [];
|
|
934
1014
|
let offset = 0;
|
|
1015
|
+
let multilineQuote = null;
|
|
935
1016
|
for (const line of lines) {
|
|
936
1017
|
if (line.length === 0)
|
|
937
1018
|
break;
|
|
1019
|
+
const multilineScan = scanTomlMultilineLine(line, multilineQuote);
|
|
1020
|
+
multilineQuote = multilineScan.nextQuote;
|
|
1021
|
+
if (multilineScan.wasInside) {
|
|
1022
|
+
offset += line.length;
|
|
1023
|
+
continue;
|
|
1024
|
+
}
|
|
938
1025
|
if (isTomlTableHeaderLine(line))
|
|
939
1026
|
return offset;
|
|
940
1027
|
offset += line.length;
|
|
@@ -972,6 +1059,131 @@ function isTomlTableHeaderLine(line) {
|
|
|
972
1059
|
const normalizedLine = stripUnquotedInlineComment(line).trim();
|
|
973
1060
|
return normalizedLine.startsWith("[") && normalizedLine.endsWith("]");
|
|
974
1061
|
}
|
|
1062
|
+
function scanTomlMultilineLine(line, currentQuote) {
|
|
1063
|
+
if (currentQuote) {
|
|
1064
|
+
return {
|
|
1065
|
+
wasInside: true,
|
|
1066
|
+
nextQuote: findTomlMultilineDelimiter(line, currentQuote, 0) === -1 ? currentQuote : null
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
let quote = null;
|
|
1070
|
+
let index = 0;
|
|
1071
|
+
while (index < line.length) {
|
|
1072
|
+
const char = line[index];
|
|
1073
|
+
if (quote === '"') {
|
|
1074
|
+
if (char === "\\") {
|
|
1075
|
+
index += 2;
|
|
1076
|
+
continue;
|
|
1077
|
+
}
|
|
1078
|
+
if (char === '"')
|
|
1079
|
+
quote = null;
|
|
1080
|
+
index += 1;
|
|
1081
|
+
continue;
|
|
1082
|
+
}
|
|
1083
|
+
if (quote === "'") {
|
|
1084
|
+
if (char === "'")
|
|
1085
|
+
quote = null;
|
|
1086
|
+
index += 1;
|
|
1087
|
+
continue;
|
|
1088
|
+
}
|
|
1089
|
+
if (char === "#")
|
|
1090
|
+
break;
|
|
1091
|
+
const delimiter2 = line.startsWith('"""', index) ? '"""' : line.startsWith("'''", index) ? "'''" : null;
|
|
1092
|
+
if (delimiter2) {
|
|
1093
|
+
const closingIndex = findTomlMultilineDelimiter(line, delimiter2, index + delimiter2.length);
|
|
1094
|
+
return { wasInside: false, nextQuote: closingIndex === -1 ? delimiter2 : null };
|
|
1095
|
+
}
|
|
1096
|
+
if (char === '"' || char === "'")
|
|
1097
|
+
quote = char;
|
|
1098
|
+
index += 1;
|
|
1099
|
+
}
|
|
1100
|
+
return { wasInside: false, nextQuote: null };
|
|
1101
|
+
}
|
|
1102
|
+
function findTomlMultilineDelimiter(line, delimiter2, startIndex) {
|
|
1103
|
+
let index = line.indexOf(delimiter2, startIndex);
|
|
1104
|
+
while (index !== -1) {
|
|
1105
|
+
if (delimiter2 === "'''" || countPrecedingBackslashes(line, index) % 2 === 0)
|
|
1106
|
+
return index;
|
|
1107
|
+
index = line.indexOf(delimiter2, index + 1);
|
|
1108
|
+
}
|
|
1109
|
+
return -1;
|
|
1110
|
+
}
|
|
1111
|
+
function countPrecedingBackslashes(line, index) {
|
|
1112
|
+
let count = 0;
|
|
1113
|
+
let cursor = index - 1;
|
|
1114
|
+
while (cursor >= 0 && line[cursor] === "\\") {
|
|
1115
|
+
count += 1;
|
|
1116
|
+
cursor -= 1;
|
|
1117
|
+
}
|
|
1118
|
+
return count;
|
|
1119
|
+
}
|
|
1120
|
+
function findUnquotedAssignment(line) {
|
|
1121
|
+
return findUnquotedCharacter(line, "=", 0);
|
|
1122
|
+
}
|
|
1123
|
+
function findUnquotedComment(line, startIndex) {
|
|
1124
|
+
return findUnquotedCharacter(line, "#", startIndex);
|
|
1125
|
+
}
|
|
1126
|
+
function findUnquotedCharacter(line, target, startIndex) {
|
|
1127
|
+
let quote = null;
|
|
1128
|
+
let index = startIndex;
|
|
1129
|
+
while (index < line.length) {
|
|
1130
|
+
const char = line[index];
|
|
1131
|
+
if (quote === '"') {
|
|
1132
|
+
if (char === "\\") {
|
|
1133
|
+
index += 2;
|
|
1134
|
+
continue;
|
|
1135
|
+
}
|
|
1136
|
+
if (char === '"')
|
|
1137
|
+
quote = null;
|
|
1138
|
+
index += 1;
|
|
1139
|
+
continue;
|
|
1140
|
+
}
|
|
1141
|
+
if (quote === "'") {
|
|
1142
|
+
if (char === "'")
|
|
1143
|
+
quote = null;
|
|
1144
|
+
index += 1;
|
|
1145
|
+
continue;
|
|
1146
|
+
}
|
|
1147
|
+
if (char === '"' || char === "'") {
|
|
1148
|
+
quote = char;
|
|
1149
|
+
index += 1;
|
|
1150
|
+
continue;
|
|
1151
|
+
}
|
|
1152
|
+
if (char === target)
|
|
1153
|
+
return index;
|
|
1154
|
+
if (char === "#")
|
|
1155
|
+
return -1;
|
|
1156
|
+
index += 1;
|
|
1157
|
+
}
|
|
1158
|
+
return -1;
|
|
1159
|
+
}
|
|
1160
|
+
function tomlPathMatches(candidate, target) {
|
|
1161
|
+
return candidate.length === target.length && candidate.every((part, index) => part === target[index]);
|
|
1162
|
+
}
|
|
1163
|
+
function replaceTomlAssignmentValue(line, assignmentIndex, value) {
|
|
1164
|
+
const newline = line.endsWith(`
|
|
1165
|
+
`) ? `
|
|
1166
|
+
` : "";
|
|
1167
|
+
const lineBody = newline ? line.slice(0, -1) : line;
|
|
1168
|
+
const commentIndex = findUnquotedComment(lineBody, assignmentIndex + 1);
|
|
1169
|
+
const comment = commentIndex === -1 ? "" : ` ${lineBody.slice(commentIndex).trimStart()}`;
|
|
1170
|
+
return `${lineBody.slice(0, assignmentIndex + 1)} ${value}${comment}${newline}`;
|
|
1171
|
+
}
|
|
1172
|
+
function findTomlMultilineValueEnd(text, startOffset, quote) {
|
|
1173
|
+
const lines = text.slice(startOffset).match(/[^\n]*\n?|$/g) ?? [];
|
|
1174
|
+
let offset = startOffset;
|
|
1175
|
+
let currentQuote = quote;
|
|
1176
|
+
for (const line of lines) {
|
|
1177
|
+
if (line.length === 0)
|
|
1178
|
+
break;
|
|
1179
|
+
const scan = scanTomlMultilineLine(line, currentQuote);
|
|
1180
|
+
currentQuote = scan.nextQuote;
|
|
1181
|
+
offset += line.length;
|
|
1182
|
+
if (currentQuote === null)
|
|
1183
|
+
return offset;
|
|
1184
|
+
}
|
|
1185
|
+
return text.length;
|
|
1186
|
+
}
|
|
975
1187
|
function stripUnquotedInlineComment(line) {
|
|
976
1188
|
let quote = null;
|
|
977
1189
|
let index = 0;
|
|
@@ -1232,6 +1444,10 @@ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
|
|
|
1232
1444
|
{
|
|
1233
1445
|
previous: { model: "gpt-5.5", effort: "xhigh" },
|
|
1234
1446
|
current: { model: "gpt-5.6-sol", effort: "ultra" }
|
|
1447
|
+
},
|
|
1448
|
+
{
|
|
1449
|
+
previous: { model: "gpt-5.6-sol", effort: "ultra" },
|
|
1450
|
+
current: { model: "gpt-5.6-terra", effort: "high" }
|
|
1235
1451
|
}
|
|
1236
1452
|
]
|
|
1237
1453
|
],
|
|
@@ -2195,13 +2411,137 @@ function delay(milliseconds) {
|
|
|
2195
2411
|
return new Promise((resolveDelay) => setTimeout(resolveDelay, milliseconds));
|
|
2196
2412
|
}
|
|
2197
2413
|
|
|
2414
|
+
// ../src/install/toml-setting-reader.ts
|
|
2415
|
+
function hasTomlSetting(config, keyPath) {
|
|
2416
|
+
const targetPath = parseTomlDottedKey(keyPath);
|
|
2417
|
+
if (!targetPath)
|
|
2418
|
+
return false;
|
|
2419
|
+
return hasTomlAssignment(config, (tablePath, settingPath) => {
|
|
2420
|
+
const fullPath = [...tablePath, ...settingPath];
|
|
2421
|
+
return fullPath.length === targetPath.length && fullPath.every((part, index) => part === targetPath[index]);
|
|
2422
|
+
});
|
|
2423
|
+
}
|
|
2424
|
+
function hasTomlRootDottedKeyPrefix(config, rootKey) {
|
|
2425
|
+
return hasTomlAssignment(config, (tablePath, settingPath) => tablePath.length === 0 && settingPath.length > 1 && settingPath[0] === rootKey);
|
|
2426
|
+
}
|
|
2427
|
+
function hasTomlAssignment(config, predicate) {
|
|
2428
|
+
let tablePath = [];
|
|
2429
|
+
let multilineQuote = null;
|
|
2430
|
+
for (const line of config.split(`
|
|
2431
|
+
`)) {
|
|
2432
|
+
const multilineScan = scanTomlMultilineLine(line, multilineQuote);
|
|
2433
|
+
multilineQuote = multilineScan.nextQuote;
|
|
2434
|
+
if (multilineScan.wasInside)
|
|
2435
|
+
continue;
|
|
2436
|
+
const normalizedLine = stripUnquotedInlineComment2(line).trim();
|
|
2437
|
+
if (normalizedLine.length === 0)
|
|
2438
|
+
continue;
|
|
2439
|
+
const headerPath = parseTomlTableHeader2(normalizedLine);
|
|
2440
|
+
if (headerPath) {
|
|
2441
|
+
tablePath = headerPath;
|
|
2442
|
+
continue;
|
|
2443
|
+
}
|
|
2444
|
+
if (isTomlTableHeaderLine2(normalizedLine)) {
|
|
2445
|
+
tablePath = null;
|
|
2446
|
+
continue;
|
|
2447
|
+
}
|
|
2448
|
+
if (!tablePath)
|
|
2449
|
+
continue;
|
|
2450
|
+
const assignmentIndex = findUnquotedAssignment2(normalizedLine);
|
|
2451
|
+
if (assignmentIndex < 0)
|
|
2452
|
+
continue;
|
|
2453
|
+
const settingPath = parseTomlDottedKey(normalizedLine.slice(0, assignmentIndex).trim());
|
|
2454
|
+
if (!settingPath)
|
|
2455
|
+
continue;
|
|
2456
|
+
if (predicate(tablePath, settingPath))
|
|
2457
|
+
return true;
|
|
2458
|
+
}
|
|
2459
|
+
return false;
|
|
2460
|
+
}
|
|
2461
|
+
function parseTomlTableHeader2(line) {
|
|
2462
|
+
if (!line.startsWith("[") || !line.endsWith("]") || line.startsWith("[["))
|
|
2463
|
+
return null;
|
|
2464
|
+
return parseTomlDottedKey(line.slice(1, -1).trim());
|
|
2465
|
+
}
|
|
2466
|
+
function isTomlTableHeaderLine2(line) {
|
|
2467
|
+
return line.startsWith("[") && line.endsWith("]");
|
|
2468
|
+
}
|
|
2469
|
+
function stripUnquotedInlineComment2(line) {
|
|
2470
|
+
let quote = null;
|
|
2471
|
+
let index = 0;
|
|
2472
|
+
while (index < line.length) {
|
|
2473
|
+
const char = line[index];
|
|
2474
|
+
if (quote === '"') {
|
|
2475
|
+
if (char === "\\") {
|
|
2476
|
+
index += 2;
|
|
2477
|
+
continue;
|
|
2478
|
+
}
|
|
2479
|
+
if (char === '"')
|
|
2480
|
+
quote = null;
|
|
2481
|
+
index += 1;
|
|
2482
|
+
continue;
|
|
2483
|
+
}
|
|
2484
|
+
if (quote === "'") {
|
|
2485
|
+
if (char === "'")
|
|
2486
|
+
quote = null;
|
|
2487
|
+
index += 1;
|
|
2488
|
+
continue;
|
|
2489
|
+
}
|
|
2490
|
+
if (char === '"' || char === "'") {
|
|
2491
|
+
quote = char;
|
|
2492
|
+
index += 1;
|
|
2493
|
+
continue;
|
|
2494
|
+
}
|
|
2495
|
+
if (char === "#")
|
|
2496
|
+
return line.slice(0, index);
|
|
2497
|
+
index += 1;
|
|
2498
|
+
}
|
|
2499
|
+
return line;
|
|
2500
|
+
}
|
|
2501
|
+
function findUnquotedAssignment2(line) {
|
|
2502
|
+
let quote = null;
|
|
2503
|
+
let index = 0;
|
|
2504
|
+
while (index < line.length) {
|
|
2505
|
+
const char = line[index];
|
|
2506
|
+
if (quote === '"') {
|
|
2507
|
+
if (char === "\\") {
|
|
2508
|
+
index += 2;
|
|
2509
|
+
continue;
|
|
2510
|
+
}
|
|
2511
|
+
if (char === '"')
|
|
2512
|
+
quote = null;
|
|
2513
|
+
index += 1;
|
|
2514
|
+
continue;
|
|
2515
|
+
}
|
|
2516
|
+
if (quote === "'") {
|
|
2517
|
+
if (char === "'")
|
|
2518
|
+
quote = null;
|
|
2519
|
+
index += 1;
|
|
2520
|
+
continue;
|
|
2521
|
+
}
|
|
2522
|
+
if (char === '"' || char === "'") {
|
|
2523
|
+
quote = char;
|
|
2524
|
+
index += 1;
|
|
2525
|
+
continue;
|
|
2526
|
+
}
|
|
2527
|
+
if (char === "=")
|
|
2528
|
+
return index;
|
|
2529
|
+
index += 1;
|
|
2530
|
+
}
|
|
2531
|
+
return -1;
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2198
2534
|
// ../src/install/codex-config-features.ts
|
|
2199
2535
|
function ensureFeatureEnabled(config, featureName) {
|
|
2200
2536
|
const section = findTomlSection(config, "features");
|
|
2201
|
-
if (!section)
|
|
2537
|
+
if (!section) {
|
|
2538
|
+
if (hasTomlRootDottedKeyPrefix(config, "features")) {
|
|
2539
|
+
return replaceOrInsertRootDottedSetting(config, `features.${featureName}`, "true");
|
|
2540
|
+
}
|
|
2202
2541
|
return appendBlock(config, `[features]
|
|
2203
2542
|
${featureName} = true
|
|
2204
2543
|
`);
|
|
2544
|
+
}
|
|
2205
2545
|
return replaceOrInsertSetting(config, section, featureName, "true");
|
|
2206
2546
|
}
|
|
2207
2547
|
|
|
@@ -2269,7 +2609,7 @@ function ensureAutonomousPermissions(config) {
|
|
|
2269
2609
|
next = replaceOrInsertRootSetting(next, "sandbox_mode", JSON.stringify("danger-full-access"));
|
|
2270
2610
|
next = replaceOrInsertRootSetting(next, "network_access", JSON.stringify("enabled"));
|
|
2271
2611
|
for (const featureName of AUTONOMOUS_FEATURES) {
|
|
2272
|
-
next =
|
|
2612
|
+
next = ensureFeatureEnabled(next, featureName);
|
|
2273
2613
|
}
|
|
2274
2614
|
next = removeWindowsSandboxSetting(next);
|
|
2275
2615
|
next = ensureNoticeEnabled(next, "hide_full_access_warning");
|
|
@@ -2287,14 +2627,6 @@ function ensureNoticeEnabled(config, key) {
|
|
|
2287
2627
|
return appendNoticeBlock(config, key);
|
|
2288
2628
|
return replaceOrInsertSetting(config, section, key, "true");
|
|
2289
2629
|
}
|
|
2290
|
-
function ensureFeatureEnabled2(config, key) {
|
|
2291
|
-
const section = findTomlSection(config, "features");
|
|
2292
|
-
if (section === null)
|
|
2293
|
-
return appendBlock(config, `[features]
|
|
2294
|
-
${key} = true
|
|
2295
|
-
`);
|
|
2296
|
-
return replaceOrInsertSetting(config, section, key, "true");
|
|
2297
|
-
}
|
|
2298
2630
|
function appendNoticeBlock(config, key) {
|
|
2299
2631
|
return appendBlock(config, `[notice]
|
|
2300
2632
|
${key} = true
|
|
@@ -2366,7 +2698,7 @@ function readStringArraySetting(sectionText, key) {
|
|
|
2366
2698
|
const assignmentIndex = line.indexOf("=");
|
|
2367
2699
|
if (assignmentIndex === -1)
|
|
2368
2700
|
return null;
|
|
2369
|
-
return parseTomlStringArray(
|
|
2701
|
+
return parseTomlStringArray(stripUnquotedInlineComment3(line.slice(assignmentIndex + 1)).trim());
|
|
2370
2702
|
}
|
|
2371
2703
|
return null;
|
|
2372
2704
|
}
|
|
@@ -2410,7 +2742,7 @@ function parseTomlString(input, startIndex) {
|
|
|
2410
2742
|
}
|
|
2411
2743
|
return null;
|
|
2412
2744
|
}
|
|
2413
|
-
function
|
|
2745
|
+
function stripUnquotedInlineComment3(line) {
|
|
2414
2746
|
let quote = null;
|
|
2415
2747
|
let index = 0;
|
|
2416
2748
|
while (index < line.length) {
|
|
@@ -2624,24 +2956,27 @@ import { readFileSync } from "node:fs";
|
|
|
2624
2956
|
import { dirname as dirname7, isAbsolute as isAbsolute5, join as join17 } from "node:path";
|
|
2625
2957
|
var CODEX_AGENTS_HEADER = "agents";
|
|
2626
2958
|
var CODEX_MULTI_AGENT_V2_HEADER = "features.multi_agent_v2";
|
|
2959
|
+
var CODEX_MULTI_AGENT_V2_THREAD_LIMIT_KEY = `${CODEX_MULTI_AGENT_V2_HEADER}.max_concurrent_threads_per_session`;
|
|
2627
2960
|
var CODEX_SUBAGENT_THREAD_LIMIT = 1000;
|
|
2961
|
+
var CODEX_MULTI_AGENT_V2_THREAD_LIMIT = 16;
|
|
2628
2962
|
function ensureCodexMultiAgentV2Config(config, options = {}) {
|
|
2629
2963
|
const featureFlag = removeFeatureFlagSetting(config, "multi_agent_v2");
|
|
2630
2964
|
const v2Preferred = options.multiAgentVersion === "v2";
|
|
2631
2965
|
const modelKnown = options.multiAgentVersion != null || readRootModel(featureFlag.config) !== null;
|
|
2632
2966
|
const agentsConfig = v2Preferred ? removeAgentsMaxThreads(featureFlag.config) : modelKnown ? ensureAgentsMaxThreads(featureFlag.config) : raiseExistingAgentsMaxThreads(featureFlag.config);
|
|
2633
|
-
const maxThreadsValue = CODEX_SUBAGENT_THREAD_LIMIT.toString();
|
|
2634
2967
|
const preserveDisable = featureFlag.value === false && !v2Preferred;
|
|
2635
2968
|
const featureConfig = preserveDisable ? setMultiAgentV2Disable(agentsConfig) : v2Preferred ? removeMultiAgentV2Disable(agentsConfig) : agentsConfig;
|
|
2969
|
+
if (hasTomlSetting(featureConfig, CODEX_MULTI_AGENT_V2_THREAD_LIMIT_KEY))
|
|
2970
|
+
return featureConfig;
|
|
2636
2971
|
const section = findTomlSection(featureConfig, CODEX_MULTI_AGENT_V2_HEADER);
|
|
2637
2972
|
if (!section) {
|
|
2638
2973
|
const enabledSetting = preserveDisable ? `enabled = false
|
|
2639
2974
|
` : "";
|
|
2640
2975
|
return appendBlock(featureConfig, `[${CODEX_MULTI_AGENT_V2_HEADER}]
|
|
2641
|
-
${enabledSetting}max_concurrent_threads_per_session = ${
|
|
2976
|
+
${enabledSetting}max_concurrent_threads_per_session = ${CODEX_MULTI_AGENT_V2_THREAD_LIMIT}
|
|
2642
2977
|
`);
|
|
2643
2978
|
}
|
|
2644
|
-
return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session",
|
|
2979
|
+
return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session", CODEX_MULTI_AGENT_V2_THREAD_LIMIT.toString());
|
|
2645
2980
|
}
|
|
2646
2981
|
function resolveCodexMultiAgentVersion(config, configPath) {
|
|
2647
2982
|
const model = readRootModel(config);
|
|
@@ -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.19.0) Checking Bootstrap Provisioning"
|
|
12
12
|
}
|
|
13
13
|
]
|
|
14
14
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# packages/omo-codex/plugin/components/codegraph/
|
|
1
|
+
# packages/omo-codex/plugin/components/codegraph/ (CodeGraph MCP Wrapper + Bootstrap Hooks)
|
|
2
2
|
|
|
3
|
-
**Generated:** 2026-07-
|
|
3
|
+
**Generated:** 2026-07-17 (7d664b96b)
|
|
4
4
|
|
|
5
5
|
## OVERVIEW
|
|
6
6
|
|
|
@@ -12,13 +12,13 @@ Codex wiring (all repo-relative to `packages/omo-codex/plugin/`):
|
|
|
12
12
|
- **PostToolUse hook:** `hooks/post-tool-use-checking-codegraph-init-guidance.json`, matcher `^(codegraph[._].*|mcp__codegraph__.*)$` → `dist/cli.js hook post-tool-use`.
|
|
13
13
|
- Both hooks registered in `.codex-plugin/plugin.json`; Windows variants dispatch via `components/bootstrap/scripts/node-dispatch.ps1`.
|
|
14
14
|
|
|
15
|
-
Serve pipeline (`src/serve.ts`): OMO SOT config gate (`[codex].codegraph.enabled=false` → unavailable stub) → resolve binary (`OMO_CODEGRAPH_BIN` env → bundled → provisioned `~/.omo/codegraph/bin` → PATH) → Node support gate (major 20
|
|
15
|
+
Serve pipeline (`src/serve.ts`): OMO SOT config gate (`[codex].codegraph.enabled=false` → unavailable stub) → resolve binary (`OMO_CODEGRAPH_BIN` env → bundled → provisioned `~/.omo/codegraph/bin` → PATH) → Node support gate (major 20-24; >=25 crashes CodeGraph mid-indexing; `CODEGRAPH_ALLOW_UNSAFE_NODE=1` overrides) → auto-provision into `~/.omo/codegraph` unless `codegraph.auto_provision=false` → bridge JSON-RPC to `codegraph serve --mcp`. Project cwd resolved from `OMO_CODEGRAPH_PROJECT_CWD` → `OMO_CODEGRAPH_SESSION_START_CWD` → `PWD` → wrapper cwd. When the binary is missing/disabled, `mcp-unavailable.ts` still answers `initialize`/`tools/*` with the skip reason so Codex startup never fails.
|
|
16
16
|
|
|
17
17
|
Hook pipeline (`src/hook.ts` + `src/session-start-worker.ts`): `hook session-start` probes `status --json` (2s timeout); uninitialized project → spawns a detached `hook session-start-worker` (prepare workspace + gitignore → `status --json` → `init` or `sync`, 60s per command) and emits a SessionStart `additionalContext` notice. Worker outcomes append to `~/.omo/codegraph/session-start.jsonl`. `hook post-tool-use` emits init guidance when a codegraph tool result indicates an uninitialized project. `cli.js` with no hook subcommand falls through to serve.
|
|
18
18
|
|
|
19
19
|
## includeCode CONTRACT (commit 4cf383c5b)
|
|
20
20
|
|
|
21
|
-
`src/mcp-bridge.ts` rewrites the upstream `codegraph_node` contract in-flight: `tools/list` responses get a clarified description + `includeCode` schema description, and `tools/call` results replace "Structural outline only" text. Contract: `includeCode=true` returns leaf-symbol source only; container symbols (classes, interfaces, structs, enums, modules, namespaces) return structural outlines with member lists BY DESIGN
|
|
21
|
+
`src/mcp-bridge.ts` rewrites the upstream `codegraph_node` contract in-flight: `tools/list` responses get a clarified description + `includeCode` schema description, and `tools/call` results replace "Structural outline only" text. Contract: `includeCode=true` returns leaf-symbol source only; container symbols (classes, interfaces, structs, enums, modules, namespaces) return structural outlines with member lists BY DESIGN: for container source, request a specific member symbol or file mode with `symbolsOnly=false` plus `offset`/`limit`. Pinned by `test/serve-mcp-bridge.test.ts`.
|
|
22
22
|
|
|
23
23
|
## KEY FILES
|
|
24
24
|
|
|
@@ -28,7 +28,7 @@ Hook pipeline (`src/hook.ts` + `src/session-start-worker.ts`): `hook session-sta
|
|
|
28
28
|
| `src/cli.ts` | Hook CLI router: `hook session-start` / `hook post-tool-use` / `hook session-start-worker` / serve fallback |
|
|
29
29
|
| `src/hook.ts` | SessionStart probe + detached worker spawn, PostToolUse guidance emission |
|
|
30
30
|
| `src/session-start-worker.ts` | Background bootstrap: provision → workspace prep → `init`/`sync`, jsonl outcome log |
|
|
31
|
-
| `src/mcp-bridge.ts` | Stdio JSON-RPC forwarder; per-request framed/line response-mode tracking; codegraph_node contract rewrites |
|
|
31
|
+
| `src/mcp-bridge.ts` | Stdio JSON-RPC forwarder; per-request framed/line response-mode tracking; codegraph_node contract rewrites; awaits stdio writes and SIGKILLs the child on response-forwarding failure |
|
|
32
32
|
| `src/mcp-unavailable.ts` | Reason-bearing stub MCP server for disabled/missing binary |
|
|
33
33
|
| `src/serve-invocation.ts` | win32 invocation shim: `.cmd`/`.bat` via `cmd.exe /d /s /c`, `.js`/`.mjs`/`.cjs` via `process.execPath` (mirrored by `resolveCodegraphCommandInvocation` in session-start-worker) |
|
|
34
34
|
| `src/hook-types.ts` | Shared hook/worker option + outcome types |
|
|
@@ -37,7 +37,7 @@ Hook pipeline (`src/hook.ts` + `src/session-start-worker.ts`): `hook session-sta
|
|
|
37
37
|
|
|
38
38
|
| Task | Location |
|
|
39
39
|
|------|----------|
|
|
40
|
-
| Resolution order, provisioning, Node gate, env, gitignore/workspace prep | `packages/utils/src/codegraph/` (`resolve.ts`, `provision.ts`, `node-support.ts`, `env.ts`, `workspace.ts`, `guidance.ts`)
|
|
40
|
+
| Resolution order, provisioning, Node gate, env, gitignore/workspace prep | `packages/utils/src/codegraph/` (`resolve.ts`, `provision.ts`, `node-support.ts`, `env.ts`, `workspace.ts`, `guidance.ts`), bundled at build time |
|
|
41
41
|
| `[codex].codegraph` config keys (`enabled`, `auto_provision`, `trustedCodegraphInstallDir`) | `packages/omo-codex/plugin/shared/src/config-loader.ts` |
|
|
42
42
|
| JSON-RPC framing primitives | `packages/mcp-stdio-core/src/` |
|
|
43
43
|
| Build / test / typecheck | `bun run build` (bun build → `dist/serve.js` + `dist/cli.js`, target node ESM), `bun test ./test`, `tsc --noEmit` |
|
|
@@ -49,3 +49,4 @@ Hook pipeline (`src/hook.ts` + `src/session-start-worker.ts`): `hook session-sta
|
|
|
49
49
|
- `CODEGRAPH_VERSION` is duplicated in `serve.ts` and `session-start-worker.ts` and must match the `@colbymchenry/codegraph` optionalDependency version.
|
|
50
50
|
- `trustedCodegraphInstallDir` overrides the `~/.omo/codegraph` install dir and is forwarded to children as `CODEGRAPH_INSTALL_DIR`.
|
|
51
51
|
- `resolution.source === "env"` is never auto-provisioned over: a user-set `OMO_CODEGRAPH_BIN` pointing at a missing file skips the MCP instead of silently substituting a download.
|
|
52
|
+
- `runBridgedCodegraphProcess` awaits every stdio write and races `childExit` against response forwarding; a forwarding error (e.g. parent stdout `EPIPE`) rejects the serve promise, destroys the child pipes, and `SIGKILL`s the codegraph child if still alive so a held-open child is never orphaned. Pinned by `test/serve-mcp-bridge-lifecycle.test.ts` and the held-open case in `test/serve-mcp-bridge.test.ts`.
|