oh-my-opencode 4.5.12 → 4.7.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/opencode-qa/SKILL.md +194 -0
- package/.agents/skills/opencode-qa/references/cli-commands.md +188 -0
- package/.agents/skills/opencode-qa/references/db-investigation.md +197 -0
- package/.agents/skills/opencode-qa/references/events-hooks.md +110 -0
- package/.agents/skills/opencode-qa/references/sdk.md +96 -0
- package/.agents/skills/opencode-qa/references/server-api.md +200 -0
- package/.agents/skills/opencode-qa/references/testing-harness.md +218 -0
- package/.agents/skills/opencode-qa/references/tui-tmux.md +52 -0
- package/.agents/skills/opencode-qa/scripts/db-session-by-id.sh +53 -0
- package/.agents/skills/opencode-qa/scripts/db-session-by-name.sh +57 -0
- package/.agents/skills/opencode-qa/scripts/db-session-by-text.sh +158 -0
- package/.agents/skills/opencode-qa/scripts/export-roundtrip.sh +57 -0
- package/.agents/skills/opencode-qa/scripts/lib/common.sh +216 -0
- package/.agents/skills/opencode-qa/scripts/server-smoke.sh +64 -0
- package/.agents/skills/opencode-qa/scripts/sse-hook-probe.sh +106 -0
- package/.agents/skills/opencode-qa/scripts/tui-smoke.sh +89 -0
- package/README.ja.md +13 -3
- package/README.ko.md +13 -3
- package/README.md +24 -14
- package/README.ru.md +13 -3
- package/README.zh-cn.md +13 -3
- package/bin/oh-my-opencode.js +4 -3
- package/bin/oh-my-opencode.test.ts +35 -7
- package/bin/platform.d.ts +1 -1
- package/bin/platform.js +4 -4
- package/bin/platform.test.ts +31 -9
- package/bin/version-mismatch.js +47 -0
- package/bin/version-mismatch.test.ts +120 -0
- package/dist/cli/cleanup-command.d.ts +4 -0
- package/dist/cli/cleanup.d.ts +11 -0
- package/dist/cli/cli-program.d.ts +2 -1
- package/dist/cli/codex-ulw-loop.d.ts +12 -0
- package/dist/cli/doctor/checks/tui-plugin-config.d.ts +2 -0
- package/dist/cli/index.js +2189 -529
- package/dist/cli/install-codex/codex-cache.d.ts +1 -0
- package/dist/cli/install-codex/codex-cleanup-config.d.ts +6 -0
- package/dist/cli/install-codex/codex-cleanup.d.ts +21 -0
- package/dist/cli/install-codex/codex-config-permissions.d.ts +1 -0
- package/dist/cli/install-codex/codex-config-reasoning.d.ts +2 -0
- package/dist/cli/install-codex/codex-config-toml.d.ts +2 -1
- package/dist/cli/install-codex/codex-installation-detection.d.ts +36 -0
- package/dist/cli/install-codex/codex-model-catalog.d.ts +13 -0
- package/dist/cli/install-codex/codex-package-layout.d.ts +1 -0
- package/dist/cli/install-codex/codex-project-local-cleanup-best-effort.d.ts +7 -0
- package/dist/cli/install-codex/codex-project-local-cleanup.d.ts +35 -0
- package/dist/cli/install-codex/git-bash.d.ts +35 -0
- package/dist/cli/install-codex/index.d.ts +4 -0
- package/dist/cli/install-codex/toml-section-editor.d.ts +2 -0
- package/dist/cli/install-codex/types.d.ts +20 -0
- package/dist/cli/run/event-state.d.ts +1 -0
- package/dist/cli/run/poll-for-completion.d.ts +1 -0
- package/dist/cli/run/prompt-start.d.ts +7 -0
- package/dist/cli/star-request.d.ts +9 -0
- package/dist/config/schema/hooks.d.ts +0 -1
- package/dist/create-hooks.d.ts +0 -1
- package/dist/features/background-agent/concurrency.d.ts +1 -0
- package/dist/features/background-agent/process-cleanup.d.ts +6 -0
- package/dist/features/builtin-skills/skills/debugging.d.ts +2 -0
- package/dist/features/builtin-skills/skills/index.d.ts +1 -0
- package/dist/features/claude-code-session-state/state.d.ts +1 -0
- package/dist/features/opencode-skill-loader/index.d.ts +1 -0
- package/dist/features/opencode-skill-loader/opencode-config-skills-reader.d.ts +5 -0
- package/dist/features/tmux-subagent/attachable-session-status.d.ts +1 -1
- package/dist/features/tmux-subagent/session-status-parser.d.ts +1 -0
- package/dist/hooks/comment-checker/cli.d.ts +1 -0
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/tasks-todowrite-disabler/constants.d.ts +1 -1
- package/dist/index.js +1077 -563
- package/dist/plugin/hooks/create-core-hooks.d.ts +0 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +1 -2
- package/dist/plugin/messages-transform.d.ts +8 -1
- package/dist/plugin/user-abort-interrupted-recovery-guard.d.ts +6 -0
- package/dist/shared/command-executor/execute-hook-command.d.ts +2 -0
- package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +14 -0
- package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +7 -0
- package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +1 -0
- package/dist/shared/prompt-async-gate/timing.d.ts +1 -0
- package/dist/shared/prompt-async-gate/types.d.ts +2 -0
- package/dist/shared/prompt-async-gate.d.ts +1 -1
- package/dist/tools/skill/description-formatter.d.ts +5 -1
- package/dist/tools/skill/types.d.ts +1 -0
- package/package.json +22 -18
- package/packages/ast-grep-mcp/dist/cli.js +53 -9
- package/packages/git-bash-mcp/dist/cli.js +367 -0
- package/packages/lsp-tools-mcp/dist/lsp/process.js +1 -1
- package/packages/omo-codex/plugin/.mcp.json +11 -0
- package/packages/omo-codex/plugin/components/comment-checker/README.md +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +29 -0
- package/packages/omo-codex/plugin/components/git-bash/package.json +23 -0
- package/packages/omo-codex/plugin/components/git-bash/src/cli.ts +33 -0
- package/packages/omo-codex/plugin/components/git-bash/src/codex-hook.ts +180 -0
- package/packages/omo-codex/plugin/components/git-bash/src/index.ts +10 -0
- package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +195 -0
- package/packages/omo-codex/plugin/components/git-bash/tsconfig.build.json +13 -0
- package/packages/omo-codex/plugin/components/git-bash/tsconfig.json +25 -0
- package/packages/omo-codex/plugin/components/lsp/README.md +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/cli.ts +5 -5
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook-cli.ts +33 -0
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +19 -27
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook-cli.test.ts +28 -0
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook-errors.test.ts +55 -0
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +7 -5
- package/packages/omo-codex/plugin/components/rules/README.md +1 -1
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +6 -4
- package/packages/omo-codex/plugin/components/rules/bundled-rules/windows-git-bash.md +10 -0
- package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +0 -2
- package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +3 -1
- package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +97 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +6 -5
- package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +22 -0
- package/packages/omo-codex/plugin/components/ultrawork/CHANGELOG.md +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/README.md +3 -3
- package/packages/omo-codex/plugin/components/ultrawork/agents/codex-ultrawork-reviewer.toml +4 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +8 -7
- package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +9 -8
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +32 -6
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +27 -4
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +25 -0
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +28 -205
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +231 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +12 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint.test.ts +19 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +102 -5
- package/packages/omo-codex/plugin/hooks/hooks.json +35 -2
- package/packages/omo-codex/plugin/model-catalog.json +49 -0
- package/packages/omo-codex/plugin/package-lock.json +19 -0
- package/packages/omo-codex/plugin/package.json +3 -1
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +159 -0
- package/packages/omo-codex/plugin/scripts/build-bundled-mcp-runtimes.mjs +16 -1
- package/packages/omo-codex/plugin/scripts/build-components.mjs +2 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +269 -0
- package/packages/omo-codex/plugin/scripts/sync-hook-status-messages.mjs +89 -0
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +6 -6
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +6 -6
- package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +127 -0
- package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +9 -0
- package/packages/omo-codex/plugin/skills/refactor/SKILL.md +6 -6
- package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +6 -6
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +33 -8
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +25 -5
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +28 -205
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +231 -0
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +17 -17
- package/packages/omo-codex/plugin/test/aggregate.test.mjs +188 -20
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +129 -0
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +58 -11
- package/packages/omo-codex/plugin/test/install-time-build-runtime.test.mjs +34 -0
- package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +21 -0
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +146 -0
- package/packages/omo-codex/plugin/test/node-install-surface.test.mjs +48 -0
- package/packages/omo-codex/plugin/test/subagent-guidance.test.mjs +76 -0
- package/packages/omo-codex/plugin/test/sync-hook-status-messages.test.mjs +67 -0
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +54 -2
- package/packages/omo-codex/scripts/install/cache.mjs +5 -3
- package/packages/omo-codex/scripts/install/cli-args.mjs +112 -0
- package/packages/omo-codex/scripts/install/config.mjs +23 -1
- package/packages/omo-codex/scripts/install/delegated-command.mjs +25 -0
- package/packages/omo-codex/scripts/install/git-bash.mjs +99 -0
- package/packages/omo-codex/scripts/install/git-bash.test.mjs +174 -0
- package/packages/omo-codex/scripts/install/legacy-bins.mjs +1 -0
- package/packages/omo-codex/scripts/install/mcp-runtime-cache.mjs +5 -1
- package/packages/omo-codex/scripts/install/model-catalog.mjs +66 -0
- package/packages/omo-codex/scripts/install/multi-agent-v2-config.mjs +7 -1
- package/packages/omo-codex/scripts/install/permissions.d.mts +1 -0
- package/packages/omo-codex/scripts/install/permissions.mjs +26 -0
- package/packages/omo-codex/scripts/install/project-local-cleanup.mjs +229 -0
- package/packages/omo-codex/scripts/install/reasoning-config.mjs +72 -0
- package/packages/omo-codex/scripts/install/source-package-build.mjs +20 -0
- package/packages/omo-codex/scripts/install/toml-editor.mjs +19 -2
- package/packages/omo-codex/scripts/install-bin-links.test.mjs +23 -0
- package/packages/omo-codex/scripts/install-cli-args.test.mjs +146 -0
- package/packages/omo-codex/scripts/install-config-autonomous.test.mjs +48 -0
- package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +141 -0
- package/packages/omo-codex/scripts/install-config.test.mjs +205 -0
- package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +157 -0
- package/packages/omo-codex/scripts/install-local-git-bash-preflight.test.mjs +145 -0
- package/packages/omo-codex/scripts/install-local.mjs +91 -8
- package/packages/omo-codex/scripts/install-local.test.mjs +15 -0
- package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +60 -0
- package/packages/omo-codex/scripts/install-packaged-local.test.mjs +67 -0
- package/packages/omo-codex/scripts/install-project-local-cleanup.test.mjs +277 -0
- package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +127 -0
- package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +9 -0
- package/packages/shared-skills/skills/review-work/SKILL.md +33 -8
- package/packages/shared-skills/skills/start-work/SKILL.md +25 -5
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +11 -11
- package/postinstall.mjs +36 -3
- package/dist/hooks/context-window-monitor.d.ts +0 -19
package/dist/cli/index.js
CHANGED
|
@@ -6181,8 +6181,8 @@ var init_model_requirements = __esm(() => {
|
|
|
6181
6181
|
{ providers: ["opencode-go"], model: "qwen3.5-plus" },
|
|
6182
6182
|
{ providers: ["vercel"], model: "minimax-m2.7-highspeed" },
|
|
6183
6183
|
{ providers: ["opencode-go", "vercel"], model: "minimax-m2.7" },
|
|
6184
|
-
{ providers: ["anthropic", "
|
|
6185
|
-
{ providers: ["openai", "
|
|
6184
|
+
{ providers: ["anthropic", "vercel"], model: "claude-haiku-4-5" },
|
|
6185
|
+
{ providers: ["openai", "vercel"], model: "gpt-5.4-nano" }
|
|
6186
6186
|
]
|
|
6187
6187
|
},
|
|
6188
6188
|
explore: {
|
|
@@ -6191,8 +6191,8 @@ var init_model_requirements = __esm(() => {
|
|
|
6191
6191
|
{ providers: ["opencode-go"], model: "qwen3.5-plus" },
|
|
6192
6192
|
{ providers: ["vercel"], model: "minimax-m2.7-highspeed" },
|
|
6193
6193
|
{ providers: ["opencode-go", "vercel"], model: "minimax-m2.7" },
|
|
6194
|
-
{ providers: ["anthropic", "
|
|
6195
|
-
{ providers: ["openai", "
|
|
6194
|
+
{ providers: ["anthropic", "vercel"], model: "claude-haiku-4-5" },
|
|
6195
|
+
{ providers: ["openai", "vercel"], model: "gpt-5.4-nano" }
|
|
6196
6196
|
]
|
|
6197
6197
|
},
|
|
6198
6198
|
"multimodal-looker": {
|
|
@@ -6371,7 +6371,7 @@ var init_model_requirements = __esm(() => {
|
|
|
6371
6371
|
model: "gpt-5.4-mini"
|
|
6372
6372
|
},
|
|
6373
6373
|
{
|
|
6374
|
-
providers: ["anthropic", "github-copilot", "
|
|
6374
|
+
providers: ["anthropic", "github-copilot", "vercel"],
|
|
6375
6375
|
model: "claude-haiku-4-5"
|
|
6376
6376
|
},
|
|
6377
6377
|
{
|
|
@@ -6606,7 +6606,7 @@ var init_model_capability_heuristics = __esm(() => {
|
|
|
6606
6606
|
},
|
|
6607
6607
|
{
|
|
6608
6608
|
family: "kimi",
|
|
6609
|
-
|
|
6609
|
+
pattern: /(?:kimi|k2(?![-.]?p\d))/,
|
|
6610
6610
|
variants: ["low", "medium", "high"],
|
|
6611
6611
|
supportsThinking: false
|
|
6612
6612
|
},
|
|
@@ -6679,7 +6679,7 @@ function claudeVersionDot(model) {
|
|
|
6679
6679
|
function applyGatewayTransforms(model) {
|
|
6680
6680
|
return claudeVersionDot(model).replace(GEMINI_31_PRO_PREVIEW, "gemini-3.1-pro-preview");
|
|
6681
6681
|
}
|
|
6682
|
-
function transformModelForProviderUsingAnthropicBehavior(provider, model
|
|
6682
|
+
function transformModelForProviderUsingAnthropicBehavior(provider, model) {
|
|
6683
6683
|
if (provider === "vercel") {
|
|
6684
6684
|
const slashIndex = model.indexOf("/");
|
|
6685
6685
|
if (slashIndex !== -1) {
|
|
@@ -6700,12 +6700,12 @@ function transformModelForProviderUsingAnthropicBehavior(provider, model, direct
|
|
|
6700
6700
|
return model.replace(GEMINI_31_PRO_PREVIEW, "gemini-3.1-pro-preview").replace(GEMINI_3_FLASH_PREVIEW, "gemini-3-flash-preview");
|
|
6701
6701
|
}
|
|
6702
6702
|
if (provider === "anthropic") {
|
|
6703
|
-
return
|
|
6703
|
+
return model;
|
|
6704
6704
|
}
|
|
6705
6705
|
return model;
|
|
6706
6706
|
}
|
|
6707
6707
|
function transformModelForProviderDisplay(provider, model) {
|
|
6708
|
-
return transformModelForProviderUsingAnthropicBehavior(provider, model
|
|
6708
|
+
return transformModelForProviderUsingAnthropicBehavior(provider, model);
|
|
6709
6709
|
}
|
|
6710
6710
|
var CLAUDE_VERSION_DOT, GEMINI_31_PRO_PREVIEW, GEMINI_3_FLASH_PREVIEW;
|
|
6711
6711
|
var init_provider_model_id_transform = __esm(() => {
|
|
@@ -7874,8 +7874,30 @@ function resolveConfigPath(pathValue) {
|
|
|
7874
7874
|
return resolvedPath;
|
|
7875
7875
|
}
|
|
7876
7876
|
}
|
|
7877
|
+
function isWslEnvironment() {
|
|
7878
|
+
return process.platform === "linux" && (Boolean(process.env.WSL_DISTRO_NAME?.trim()) || Boolean(process.env.WSL_INTEROP?.trim()));
|
|
7879
|
+
}
|
|
7880
|
+
function isWindowsUserConfigRoot(pathValue) {
|
|
7881
|
+
const normalizedPath = pathValue.replaceAll("\\", "/").toLowerCase();
|
|
7882
|
+
return /^[a-z]:\/users\//.test(normalizedPath) || /^\/mnt\/[a-z]\/users\//.test(normalizedPath);
|
|
7883
|
+
}
|
|
7884
|
+
function getWindowsUserFromConfigRoot(pathValue) {
|
|
7885
|
+
const normalizedPath = pathValue.replaceAll("\\", "/");
|
|
7886
|
+
const match = /^(?:[a-z]:|\/mnt\/[a-z])\/Users\/([^/]+)/i.exec(normalizedPath);
|
|
7887
|
+
return match?.[1] ?? null;
|
|
7888
|
+
}
|
|
7889
|
+
function getWslLinuxHomeDir(windowsConfigRoot) {
|
|
7890
|
+
const envHome = process.env.HOME?.trim();
|
|
7891
|
+
if (envHome && envHome.startsWith("/") && !isWindowsUserConfigRoot(envHome)) {
|
|
7892
|
+
return envHome;
|
|
7893
|
+
}
|
|
7894
|
+
const user = process.env.USER?.trim() || process.env.LOGNAME?.trim() || process.env.SUDO_USER?.trim() || (windowsConfigRoot ? getWindowsUserFromConfigRoot(windowsConfigRoot) : undefined);
|
|
7895
|
+
return user ? join5("/home", user) : null;
|
|
7896
|
+
}
|
|
7877
7897
|
function getCliDefaultConfigDir() {
|
|
7878
|
-
const
|
|
7898
|
+
const envXdgConfig = process.env.XDG_CONFIG_HOME?.trim();
|
|
7899
|
+
const shouldIgnoreWindowsXdg = envXdgConfig !== undefined && envXdgConfig.length > 0 && isWslEnvironment() && isWindowsUserConfigRoot(envXdgConfig);
|
|
7900
|
+
const xdgConfig = shouldIgnoreWindowsXdg ? join5(getWslLinuxHomeDir(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join5(homedir3(), ".config");
|
|
7879
7901
|
return resolveConfigPath(join5(xdgConfig, "opencode"));
|
|
7880
7902
|
}
|
|
7881
7903
|
function getCliCustomConfigDir() {
|
|
@@ -51711,7 +51733,7 @@ async function withDispatchTimeout(operation, dispatchTimeoutMs, operationName)
|
|
|
51711
51733
|
}
|
|
51712
51734
|
}
|
|
51713
51735
|
}
|
|
51714
|
-
var DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS = 2000, DEFAULT_PROMPT_DISPATCH_TIMEOUT_MS = 30000, DEFAULT_PROMPT_GATE_MESSAGES_FETCH_TIMEOUT_MS = 5000, DEFAULT_PROMPT_QUEUE_RETRY_MS = 250, promptGateMessagesFetchTimeoutMsForTesting;
|
|
51736
|
+
var DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS = 2000, DEFAULT_PROMPT_SEMANTIC_DEDUPE_HOLD_MS = 15000, DEFAULT_PROMPT_DISPATCH_TIMEOUT_MS = 30000, DEFAULT_PROMPT_GATE_MESSAGES_FETCH_TIMEOUT_MS = 5000, DEFAULT_PROMPT_QUEUE_RETRY_MS = 250, promptGateMessagesFetchTimeoutMsForTesting;
|
|
51715
51737
|
|
|
51716
51738
|
// src/shared/prompt-async-gate/pending-tool-turn.ts
|
|
51717
51739
|
function getPromptQuery(input) {
|
|
@@ -51808,6 +51830,42 @@ var init_pending_tool_turn = __esm(() => {
|
|
|
51808
51830
|
init_message_inspection_error();
|
|
51809
51831
|
});
|
|
51810
51832
|
|
|
51833
|
+
// src/shared/prompt-async-gate/recent-dispatches.ts
|
|
51834
|
+
function recentDispatchKey(sessionID, dedupeKey) {
|
|
51835
|
+
return `${sessionID}\x00${dedupeKey}`;
|
|
51836
|
+
}
|
|
51837
|
+
function pruneRecentPromptDispatches(now = Date.now()) {
|
|
51838
|
+
for (const [key, dispatch] of recentPromptDispatches) {
|
|
51839
|
+
if (dispatch.expiresAt <= now) {
|
|
51840
|
+
recentPromptDispatches.delete(key);
|
|
51841
|
+
}
|
|
51842
|
+
}
|
|
51843
|
+
}
|
|
51844
|
+
function getRecentPromptDispatch(sessionID, dedupeKey) {
|
|
51845
|
+
pruneRecentPromptDispatches();
|
|
51846
|
+
return recentPromptDispatches.get(recentDispatchKey(sessionID, dedupeKey));
|
|
51847
|
+
}
|
|
51848
|
+
function rememberRecentPromptDispatch(args) {
|
|
51849
|
+
pruneRecentPromptDispatches();
|
|
51850
|
+
if (args.holdMs <= 0) {
|
|
51851
|
+
return;
|
|
51852
|
+
}
|
|
51853
|
+
recentPromptDispatches.set(recentDispatchKey(args.sessionID, args.dedupeKey), {
|
|
51854
|
+
source: args.source,
|
|
51855
|
+
expiresAt: Date.now() + args.holdMs
|
|
51856
|
+
});
|
|
51857
|
+
log("[prompt-async-gate] remembered semantic prompt dispatch", {
|
|
51858
|
+
sessionID: args.sessionID,
|
|
51859
|
+
source: args.source,
|
|
51860
|
+
holdMs: args.holdMs
|
|
51861
|
+
});
|
|
51862
|
+
}
|
|
51863
|
+
var recentPromptDispatches;
|
|
51864
|
+
var init_recent_dispatches = __esm(() => {
|
|
51865
|
+
init_logger();
|
|
51866
|
+
recentPromptDispatches = new Map;
|
|
51867
|
+
});
|
|
51868
|
+
|
|
51811
51869
|
// src/shared/prompt-async-gate/reservations.ts
|
|
51812
51870
|
function setExpiredReservationHandler(handler) {
|
|
51813
51871
|
expiredReservationHandler = handler;
|
|
@@ -51869,6 +51927,7 @@ async function dispatchAfterSessionIdle(args) {
|
|
|
51869
51927
|
dedupeKey,
|
|
51870
51928
|
settleMs,
|
|
51871
51929
|
postDispatchHoldMs,
|
|
51930
|
+
semanticDedupeHoldMs,
|
|
51872
51931
|
dispatchTimeoutMs,
|
|
51873
51932
|
checkStatus,
|
|
51874
51933
|
checkToolState,
|
|
@@ -51926,10 +51985,25 @@ async function dispatchAfterSessionIdle(args) {
|
|
|
51926
51985
|
log(`[prompt-async-gate] ${sessionName} dispatching`, { sessionID, source });
|
|
51927
51986
|
dispatchAttempted = true;
|
|
51928
51987
|
const response = await withDispatchTimeout(dispatch(input), dispatchTimeoutMs, `[prompt-async-gate] ${sessionName} dispatch`);
|
|
51988
|
+
rememberRecentPromptDispatch({
|
|
51989
|
+
sessionID,
|
|
51990
|
+
dedupeKey,
|
|
51991
|
+
source,
|
|
51992
|
+
holdMs: semanticDedupeHoldMs
|
|
51993
|
+
});
|
|
51929
51994
|
log(`[prompt-async-gate] ${sessionName} dispatched`, { sessionID, source });
|
|
51930
51995
|
return { status: "dispatched", response };
|
|
51931
51996
|
} catch (error) {
|
|
51932
|
-
|
|
51997
|
+
if (dispatchAttempted) {
|
|
51998
|
+
rememberRecentPromptDispatch({
|
|
51999
|
+
sessionID,
|
|
52000
|
+
dedupeKey,
|
|
52001
|
+
source,
|
|
52002
|
+
holdMs: semanticDedupeHoldMs
|
|
52003
|
+
});
|
|
52004
|
+
}
|
|
52005
|
+
const errorText = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
52006
|
+
log(`[prompt-async-gate] ${sessionName} failed`, { sessionID, source, error: errorText });
|
|
51933
52007
|
return { status: "failed", error, dispatchAttempted };
|
|
51934
52008
|
} finally {
|
|
51935
52009
|
finishPromptReservation(sessionID, reservation, dispatchAttempted, postDispatchHoldMs);
|
|
@@ -51939,6 +52013,7 @@ var init_session_idle_dispatch = __esm(() => {
|
|
|
51939
52013
|
init_logger();
|
|
51940
52014
|
init_session_idle_settle();
|
|
51941
52015
|
init_pending_tool_turn();
|
|
52016
|
+
init_recent_dispatches();
|
|
51942
52017
|
init_reservations();
|
|
51943
52018
|
});
|
|
51944
52019
|
|
|
@@ -52038,6 +52113,7 @@ async function drainPromptQueue(sessionID, awaitedEntry) {
|
|
|
52038
52113
|
dedupeKey: entry.dedupeKey,
|
|
52039
52114
|
settleMs: entry.settleMs,
|
|
52040
52115
|
postDispatchHoldMs: entry.postDispatchHoldMs,
|
|
52116
|
+
semanticDedupeHoldMs: entry.semanticDedupeHoldMs,
|
|
52041
52117
|
dispatchTimeoutMs: entry.dispatchTimeoutMs,
|
|
52042
52118
|
checkStatus: entry.checkStatus,
|
|
52043
52119
|
checkToolState: entry.checkToolState,
|
|
@@ -52121,27 +52197,119 @@ var init_queue = __esm(() => {
|
|
|
52121
52197
|
});
|
|
52122
52198
|
});
|
|
52123
52199
|
|
|
52124
|
-
// src/shared/prompt-async-gate.ts
|
|
52200
|
+
// src/shared/prompt-async-gate/semantic-dedupe.ts
|
|
52201
|
+
import { createHash } from "crypto";
|
|
52202
|
+
function isPlainRecord(value) {
|
|
52203
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
52204
|
+
return false;
|
|
52205
|
+
}
|
|
52206
|
+
const prototype = Object.getPrototypeOf(value);
|
|
52207
|
+
return prototype === Object.prototype || prototype === null;
|
|
52208
|
+
}
|
|
52209
|
+
function canonicalizePromptInputForDedupe(key, value, seen = new WeakSet, depth = 0) {
|
|
52210
|
+
if (key === "signal") {
|
|
52211
|
+
return "[AbortSignal]";
|
|
52212
|
+
}
|
|
52213
|
+
if (typeof value === "function") {
|
|
52214
|
+
return `[Function:${value.name}]`;
|
|
52215
|
+
}
|
|
52216
|
+
if (depth > MAX_PROMPT_DEDUPE_DEPTH) {
|
|
52217
|
+
return "[MaxDepth]";
|
|
52218
|
+
}
|
|
52219
|
+
if (Array.isArray(value)) {
|
|
52220
|
+
if (seen.has(value)) {
|
|
52221
|
+
return "[Circular]";
|
|
52222
|
+
}
|
|
52223
|
+
seen.add(value);
|
|
52224
|
+
try {
|
|
52225
|
+
return value.map((entry) => canonicalizePromptInputForDedupe("", entry, seen, depth + 1));
|
|
52226
|
+
} finally {
|
|
52227
|
+
seen.delete(value);
|
|
52228
|
+
}
|
|
52229
|
+
}
|
|
52230
|
+
if (!isPlainRecord(value)) {
|
|
52231
|
+
return value;
|
|
52232
|
+
}
|
|
52233
|
+
if (seen.has(value)) {
|
|
52234
|
+
return "[Circular]";
|
|
52235
|
+
}
|
|
52236
|
+
seen.add(value);
|
|
52237
|
+
try {
|
|
52238
|
+
const canonicalEntries = [];
|
|
52239
|
+
for (const entryKey of Object.keys(value).sort()) {
|
|
52240
|
+
canonicalEntries.push([
|
|
52241
|
+
entryKey,
|
|
52242
|
+
canonicalizePromptInputForDedupe(entryKey, value[entryKey], seen, depth + 1)
|
|
52243
|
+
]);
|
|
52244
|
+
}
|
|
52245
|
+
return Object.fromEntries(canonicalEntries);
|
|
52246
|
+
} finally {
|
|
52247
|
+
seen.delete(value);
|
|
52248
|
+
}
|
|
52249
|
+
}
|
|
52250
|
+
function isContinuationTextPartLike(value) {
|
|
52251
|
+
if (!isPlainRecord(value)) {
|
|
52252
|
+
return false;
|
|
52253
|
+
}
|
|
52254
|
+
if (value.type !== "text" || typeof value.text !== "string") {
|
|
52255
|
+
return false;
|
|
52256
|
+
}
|
|
52257
|
+
if (!hasInternalInitiatorMarker(value.text)) {
|
|
52258
|
+
return false;
|
|
52259
|
+
}
|
|
52260
|
+
if (!isPlainRecord(value.metadata)) {
|
|
52261
|
+
return false;
|
|
52262
|
+
}
|
|
52263
|
+
return value.metadata.compaction_continue === true;
|
|
52264
|
+
}
|
|
52265
|
+
function hasContinuationPromptIntent(input) {
|
|
52266
|
+
if (!isPlainRecord(input) || !isPlainRecord(input.body) || !Array.isArray(input.body.parts)) {
|
|
52267
|
+
return false;
|
|
52268
|
+
}
|
|
52269
|
+
return input.body.parts.some((part) => isContinuationTextPartLike(part));
|
|
52270
|
+
}
|
|
52271
|
+
function normalizePromptInputForSemanticDedupe(input) {
|
|
52272
|
+
if (hasContinuationPromptIntent(input)) {
|
|
52273
|
+
return {
|
|
52274
|
+
__omo_internal_intent: "continuation"
|
|
52275
|
+
};
|
|
52276
|
+
}
|
|
52277
|
+
return canonicalizePromptInputForDedupe("", input);
|
|
52278
|
+
}
|
|
52125
52279
|
function stringifyPromptInputForDedupe(input) {
|
|
52126
52280
|
try {
|
|
52127
|
-
const serialized = JSON.stringify(input
|
|
52128
|
-
if (key === "signal") {
|
|
52129
|
-
return "[AbortSignal]";
|
|
52130
|
-
}
|
|
52131
|
-
if (typeof value === "function") {
|
|
52132
|
-
return `[Function:${value.name}]`;
|
|
52133
|
-
}
|
|
52134
|
-
return value;
|
|
52135
|
-
});
|
|
52281
|
+
const serialized = JSON.stringify(normalizePromptInputForSemanticDedupe(input));
|
|
52136
52282
|
return serialized ?? String(input);
|
|
52137
|
-
} catch {
|
|
52138
|
-
|
|
52283
|
+
} catch (error) {
|
|
52284
|
+
const errorTag = error instanceof Error ? error.name : String(error);
|
|
52285
|
+
return `${String(input)}:[unserializable:${errorTag}]`;
|
|
52139
52286
|
}
|
|
52140
52287
|
}
|
|
52141
|
-
function
|
|
52288
|
+
function createSemanticPromptDedupeKey(input) {
|
|
52142
52289
|
const fingerprint = stringifyPromptInputForDedupe(input);
|
|
52143
|
-
|
|
52290
|
+
const digest = createHash("sha256").update(fingerprint, "utf8").digest("hex");
|
|
52291
|
+
return `semantic:${digest}`;
|
|
52292
|
+
}
|
|
52293
|
+
function coalesceRecentSemanticPromptDispatch(args) {
|
|
52294
|
+
const recentDispatch = getRecentPromptDispatch(args.sessionID, args.dedupeKey);
|
|
52295
|
+
if (!recentDispatch) {
|
|
52296
|
+
return;
|
|
52297
|
+
}
|
|
52298
|
+
log("[prompt-async-gate] prompt coalesced with recent semantic dispatch", {
|
|
52299
|
+
sessionID: args.sessionID,
|
|
52300
|
+
source: args.source,
|
|
52301
|
+
queuedBy: recentDispatch.source
|
|
52302
|
+
});
|
|
52303
|
+
return { status: "queued", queuedBy: recentDispatch.source, position: 0 };
|
|
52144
52304
|
}
|
|
52305
|
+
var MAX_PROMPT_DEDUPE_DEPTH = 64;
|
|
52306
|
+
var init_semantic_dedupe = __esm(() => {
|
|
52307
|
+
init_internal_initiator_marker();
|
|
52308
|
+
init_logger();
|
|
52309
|
+
init_recent_dispatches();
|
|
52310
|
+
});
|
|
52311
|
+
|
|
52312
|
+
// src/shared/prompt-async-gate.ts
|
|
52145
52313
|
function hasObjectSessionPath(input) {
|
|
52146
52314
|
return typeof input === "object" && input !== null && "path" in input && typeof input.path === "object" && input.path !== null && "id" in input.path && typeof input.path.id === "string";
|
|
52147
52315
|
}
|
|
@@ -52171,9 +52339,10 @@ async function dispatchInternalPrompt(args) {
|
|
|
52171
52339
|
source,
|
|
52172
52340
|
settleMs = DEFAULT_SESSION_IDLE_SETTLE_MS
|
|
52173
52341
|
} = args;
|
|
52174
|
-
const dedupeKey = args.dedupeKey ??
|
|
52342
|
+
const dedupeKey = args.dedupeKey ?? createSemanticPromptDedupeKey(input);
|
|
52175
52343
|
const queueRetryMs = args.queueRetryMs ?? DEFAULT_PROMPT_QUEUE_RETRY_MS;
|
|
52176
52344
|
const postDispatchHoldMs = args.postDispatchHoldMs ?? DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS;
|
|
52345
|
+
const semanticDedupeHoldMs = args.semanticDedupeHoldMs ?? (postDispatchHoldMs > 0 ? DEFAULT_PROMPT_SEMANTIC_DEDUPE_HOLD_MS : 0);
|
|
52177
52346
|
const dispatchTimeoutMs = args.dispatchTimeoutMs ?? DEFAULT_PROMPT_DISPATCH_TIMEOUT_MS;
|
|
52178
52347
|
const sessionName = args.mode === "async" ? "promptAsync" : "prompt";
|
|
52179
52348
|
const dispatch = (() => {
|
|
@@ -52206,6 +52375,10 @@ async function dispatchInternalPrompt(args) {
|
|
|
52206
52375
|
if (queuedBy !== undefined || isPromptQueueDraining(sessionID)) {
|
|
52207
52376
|
return { status: "reserved", reservedBy: queuedBy ?? source };
|
|
52208
52377
|
}
|
|
52378
|
+
const recentDispatchResult2 = coalesceRecentSemanticPromptDispatch({ sessionID, dedupeKey, source });
|
|
52379
|
+
if (recentDispatchResult2) {
|
|
52380
|
+
return recentDispatchResult2;
|
|
52381
|
+
}
|
|
52209
52382
|
return dispatchAfterSessionIdle({
|
|
52210
52383
|
sessionName,
|
|
52211
52384
|
client,
|
|
@@ -52215,6 +52388,7 @@ async function dispatchInternalPrompt(args) {
|
|
|
52215
52388
|
dedupeKey,
|
|
52216
52389
|
settleMs,
|
|
52217
52390
|
postDispatchHoldMs,
|
|
52391
|
+
semanticDedupeHoldMs,
|
|
52218
52392
|
dispatchTimeoutMs,
|
|
52219
52393
|
checkStatus: args.checkStatus !== false,
|
|
52220
52394
|
checkToolState: args.checkToolState !== false,
|
|
@@ -52222,6 +52396,10 @@ async function dispatchInternalPrompt(args) {
|
|
|
52222
52396
|
});
|
|
52223
52397
|
}
|
|
52224
52398
|
if (args.queue !== false) {
|
|
52399
|
+
const recentDispatchResult2 = coalesceRecentSemanticPromptDispatch({ sessionID, dedupeKey, source });
|
|
52400
|
+
if (recentDispatchResult2) {
|
|
52401
|
+
return recentDispatchResult2;
|
|
52402
|
+
}
|
|
52225
52403
|
return enqueueInternalPrompt({
|
|
52226
52404
|
id: nextPromptQueueID(),
|
|
52227
52405
|
sessionID,
|
|
@@ -52232,6 +52410,7 @@ async function dispatchInternalPrompt(args) {
|
|
|
52232
52410
|
dedupeKey,
|
|
52233
52411
|
settleMs,
|
|
52234
52412
|
postDispatchHoldMs,
|
|
52413
|
+
semanticDedupeHoldMs,
|
|
52235
52414
|
dispatchTimeoutMs,
|
|
52236
52415
|
queueRetryMs,
|
|
52237
52416
|
checkStatus: args.checkStatus !== false,
|
|
@@ -52239,6 +52418,10 @@ async function dispatchInternalPrompt(args) {
|
|
|
52239
52418
|
dispatch: async (_dispatchInput) => dispatchWithPathCompatibility(dispatch, input)
|
|
52240
52419
|
});
|
|
52241
52420
|
}
|
|
52421
|
+
const recentDispatchResult = coalesceRecentSemanticPromptDispatch({ sessionID, dedupeKey, source });
|
|
52422
|
+
if (recentDispatchResult) {
|
|
52423
|
+
return recentDispatchResult;
|
|
52424
|
+
}
|
|
52242
52425
|
return dispatchAfterSessionIdle({
|
|
52243
52426
|
sessionName,
|
|
52244
52427
|
client,
|
|
@@ -52248,6 +52431,7 @@ async function dispatchInternalPrompt(args) {
|
|
|
52248
52431
|
dedupeKey,
|
|
52249
52432
|
settleMs,
|
|
52250
52433
|
postDispatchHoldMs,
|
|
52434
|
+
semanticDedupeHoldMs,
|
|
52251
52435
|
dispatchTimeoutMs,
|
|
52252
52436
|
checkStatus: args.checkStatus !== false,
|
|
52253
52437
|
checkToolState: args.checkToolState !== false,
|
|
@@ -52261,8 +52445,10 @@ var init_prompt_async_gate = __esm(() => {
|
|
|
52261
52445
|
init_logger();
|
|
52262
52446
|
init_session_idle_settle();
|
|
52263
52447
|
init_queue();
|
|
52448
|
+
init_recent_dispatches();
|
|
52264
52449
|
init_reservations();
|
|
52265
52450
|
init_session_idle_dispatch();
|
|
52451
|
+
init_semantic_dedupe();
|
|
52266
52452
|
});
|
|
52267
52453
|
|
|
52268
52454
|
// src/shared/prompt-failure-classifier.ts
|
|
@@ -53453,18 +53639,10 @@ function generateModelConfig(config) {
|
|
|
53453
53639
|
const categories = {};
|
|
53454
53640
|
for (const [role, req] of Object.entries(CLI_AGENT_MODEL_REQUIREMENTS)) {
|
|
53455
53641
|
if (role === "librarian") {
|
|
53456
|
-
|
|
53457
|
-
if (
|
|
53458
|
-
agentConfig = { model:
|
|
53459
|
-
|
|
53460
|
-
agentConfig = { model: "opencode-go/qwen3.5-plus" };
|
|
53461
|
-
} else if (avail.zai) {
|
|
53462
|
-
agentConfig = { model: ZAI_MODEL };
|
|
53463
|
-
} else if (avail.vercelAiGateway) {
|
|
53464
|
-
agentConfig = { model: "vercel/minimax/minimax-m2.7" };
|
|
53465
|
-
}
|
|
53466
|
-
if (agentConfig) {
|
|
53467
|
-
agents[role] = attachAllFallbackModels(agentConfig, req.fallbackChain, avail);
|
|
53642
|
+
const resolved2 = resolveModelFromChain(req.fallbackChain, avail);
|
|
53643
|
+
if (resolved2) {
|
|
53644
|
+
const agentConfig = resolved2.variant ? { model: resolved2.model, variant: resolved2.variant } : { model: resolved2.model };
|
|
53645
|
+
agents[role] = attachFallbackModels(agentConfig, req.fallbackChain, avail);
|
|
53468
53646
|
}
|
|
53469
53647
|
continue;
|
|
53470
53648
|
}
|
|
@@ -53475,7 +53653,7 @@ function generateModelConfig(config) {
|
|
|
53475
53653
|
} else if (avail.native.claude) {
|
|
53476
53654
|
agentConfig = { model: "anthropic/claude-haiku-4-5" };
|
|
53477
53655
|
} else if (avail.opencodeZen) {
|
|
53478
|
-
agentConfig = { model: "opencode/
|
|
53656
|
+
agentConfig = { model: "opencode/gpt-5-nano" };
|
|
53479
53657
|
} else if (avail.opencodeGo) {
|
|
53480
53658
|
agentConfig = { model: "opencode-go/qwen3.5-plus" };
|
|
53481
53659
|
} else if (avail.copilot) {
|
|
@@ -53540,7 +53718,7 @@ function generateModelConfig(config) {
|
|
|
53540
53718
|
};
|
|
53541
53719
|
return isOpenAiOnlyAvailability(avail) ? applyOpenAiOnlyModelCatalog(generatedConfig) : generatedConfig;
|
|
53542
53720
|
}
|
|
53543
|
-
var
|
|
53721
|
+
var ULTIMATE_FALLBACK = "opencode/gpt-5-nano", SCHEMA_URL = "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json";
|
|
53544
53722
|
var init_model_fallback = __esm(() => {
|
|
53545
53723
|
init_model_fallback_requirements();
|
|
53546
53724
|
init_openai_only_model_catalog();
|
|
@@ -54105,7 +54283,7 @@ var init_config_manager = __esm(() => {
|
|
|
54105
54283
|
});
|
|
54106
54284
|
|
|
54107
54285
|
// node_modules/.bun/posthog-node@5.35.3/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
54108
|
-
import { dirname as
|
|
54286
|
+
import { dirname as dirname14, posix, sep as sep3 } from "path";
|
|
54109
54287
|
function createModulerModifier() {
|
|
54110
54288
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
54111
54289
|
return async (frames) => {
|
|
@@ -54114,7 +54292,7 @@ function createModulerModifier() {
|
|
|
54114
54292
|
return frames;
|
|
54115
54293
|
};
|
|
54116
54294
|
}
|
|
54117
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ?
|
|
54295
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname14(process.argv[1]) : process.cwd(), isWindows = sep3 === "\\") {
|
|
54118
54296
|
const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
|
|
54119
54297
|
return (filename) => {
|
|
54120
54298
|
if (!filename)
|
|
@@ -56919,14 +57097,14 @@ async function addSourceContext(frames) {
|
|
|
56919
57097
|
return frames;
|
|
56920
57098
|
}
|
|
56921
57099
|
function getContextLinesFromFile(path6, ranges, output) {
|
|
56922
|
-
return new Promise((
|
|
57100
|
+
return new Promise((resolve9) => {
|
|
56923
57101
|
const stream = createReadStream(path6);
|
|
56924
57102
|
const lineReaded = createInterface({
|
|
56925
57103
|
input: stream
|
|
56926
57104
|
});
|
|
56927
57105
|
function destroyStreamAndResolve() {
|
|
56928
57106
|
stream.destroy();
|
|
56929
|
-
|
|
57107
|
+
resolve9();
|
|
56930
57108
|
}
|
|
56931
57109
|
let lineNumber = 0;
|
|
56932
57110
|
let currentRangeIndex = 0;
|
|
@@ -58398,9 +58576,9 @@ var init_client = __esm(() => {
|
|
|
58398
58576
|
if (this.disabled || this.optedOut)
|
|
58399
58577
|
return;
|
|
58400
58578
|
if (!this._waitUntilCycle) {
|
|
58401
|
-
let
|
|
58579
|
+
let resolve9;
|
|
58402
58580
|
const promise = new Promise((r) => {
|
|
58403
|
-
|
|
58581
|
+
resolve9 = r;
|
|
58404
58582
|
});
|
|
58405
58583
|
try {
|
|
58406
58584
|
waitUntil(promise);
|
|
@@ -58408,7 +58586,7 @@ var init_client = __esm(() => {
|
|
|
58408
58586
|
return;
|
|
58409
58587
|
}
|
|
58410
58588
|
this._waitUntilCycle = {
|
|
58411
|
-
resolve:
|
|
58589
|
+
resolve: resolve9,
|
|
58412
58590
|
startedAt: Date.now(),
|
|
58413
58591
|
timer: undefined
|
|
58414
58592
|
};
|
|
@@ -58434,11 +58612,11 @@ var init_client = __esm(() => {
|
|
|
58434
58612
|
return cycle?.resolve;
|
|
58435
58613
|
}
|
|
58436
58614
|
async resolveWaitUntilFlush() {
|
|
58437
|
-
const
|
|
58615
|
+
const resolve9 = this._consumeWaitUntilCycle();
|
|
58438
58616
|
try {
|
|
58439
58617
|
await super.flush();
|
|
58440
58618
|
} catch {} finally {
|
|
58441
|
-
|
|
58619
|
+
resolve9?.();
|
|
58442
58620
|
}
|
|
58443
58621
|
}
|
|
58444
58622
|
getPersistedProperty(key) {
|
|
@@ -58538,15 +58716,15 @@ var init_client = __esm(() => {
|
|
|
58538
58716
|
return true;
|
|
58539
58717
|
if (this.featureFlagsPoller === undefined)
|
|
58540
58718
|
return false;
|
|
58541
|
-
return new Promise((
|
|
58719
|
+
return new Promise((resolve9) => {
|
|
58542
58720
|
const timeout = setTimeout(() => {
|
|
58543
58721
|
cleanup();
|
|
58544
|
-
|
|
58722
|
+
resolve9(false);
|
|
58545
58723
|
}, timeoutMs);
|
|
58546
58724
|
const cleanup = this._events.on("localEvaluationFlagsLoaded", (count) => {
|
|
58547
58725
|
clearTimeout(timeout);
|
|
58548
58726
|
cleanup();
|
|
58549
|
-
|
|
58727
|
+
resolve9(count > 0);
|
|
58550
58728
|
});
|
|
58551
58729
|
});
|
|
58552
58730
|
}
|
|
@@ -59033,13 +59211,13 @@ var init_client = __esm(() => {
|
|
|
59033
59211
|
this.context?.enter(data, options);
|
|
59034
59212
|
}
|
|
59035
59213
|
async _shutdown(shutdownTimeoutMs) {
|
|
59036
|
-
const
|
|
59214
|
+
const resolve9 = this._consumeWaitUntilCycle();
|
|
59037
59215
|
await this.featureFlagsPoller?.stopPoller(shutdownTimeoutMs);
|
|
59038
59216
|
this.errorTracking.shutdown();
|
|
59039
59217
|
try {
|
|
59040
59218
|
return await super._shutdown(shutdownTimeoutMs);
|
|
59041
59219
|
} finally {
|
|
59042
|
-
|
|
59220
|
+
resolve9?.();
|
|
59043
59221
|
}
|
|
59044
59222
|
}
|
|
59045
59223
|
async _requestRemoteConfigPayload(flagKey) {
|
|
@@ -59435,7 +59613,10 @@ var init_package = __esm(() => {
|
|
|
59435
59613
|
types: "./index.d.ts",
|
|
59436
59614
|
import: "./src/index.ts"
|
|
59437
59615
|
},
|
|
59438
|
-
"./telemetry":
|
|
59616
|
+
"./telemetry": {
|
|
59617
|
+
types: "./src/telemetry/index.ts",
|
|
59618
|
+
import: "./src/telemetry/index.ts"
|
|
59619
|
+
},
|
|
59439
59620
|
"./marketplace.json": "./marketplace.json"
|
|
59440
59621
|
},
|
|
59441
59622
|
types: "./index.d.ts",
|
|
@@ -59543,10 +59724,10 @@ var init_data_path2 = __esm(() => {
|
|
|
59543
59724
|
});
|
|
59544
59725
|
|
|
59545
59726
|
// packages/omo-codex/src/telemetry/posthog-activity-state.ts
|
|
59546
|
-
import { existsSync as
|
|
59547
|
-
import { join as
|
|
59727
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync8, readFileSync as readFileSync13 } from "fs";
|
|
59728
|
+
import { join as join30 } from "path";
|
|
59548
59729
|
function getPostHogActivityStateFilePath() {
|
|
59549
|
-
return
|
|
59730
|
+
return join30(getActivityStateDir(), POSTHOG_ACTIVITY_STATE_FILE);
|
|
59550
59731
|
}
|
|
59551
59732
|
function getUtcDayString(date) {
|
|
59552
59733
|
return date.toISOString().slice(0, 10);
|
|
@@ -59556,7 +59737,7 @@ function isPostHogActivityState(value) {
|
|
|
59556
59737
|
}
|
|
59557
59738
|
function readPostHogActivityState() {
|
|
59558
59739
|
const stateFilePath = getPostHogActivityStateFilePath();
|
|
59559
|
-
if (!
|
|
59740
|
+
if (!existsSync24(stateFilePath)) {
|
|
59560
59741
|
return {};
|
|
59561
59742
|
}
|
|
59562
59743
|
try {
|
|
@@ -59603,7 +59784,7 @@ var init_posthog_activity_state = __esm(() => {
|
|
|
59603
59784
|
});
|
|
59604
59785
|
|
|
59605
59786
|
// packages/omo-codex/src/telemetry/posthog.ts
|
|
59606
|
-
import { createHash as
|
|
59787
|
+
import { createHash as createHash3 } from "crypto";
|
|
59607
59788
|
import os4 from "os";
|
|
59608
59789
|
function resolveOsProvider() {
|
|
59609
59790
|
return osProviderOverride2 ?? os4;
|
|
@@ -59686,7 +59867,7 @@ function createPostHogClient(source, options) {
|
|
|
59686
59867
|
};
|
|
59687
59868
|
}
|
|
59688
59869
|
function getPostHogDistinctId() {
|
|
59689
|
-
return
|
|
59870
|
+
return createHash3("sha256").update(`omo-codex:${resolveOsProvider().hostname()}`).digest("hex");
|
|
59690
59871
|
}
|
|
59691
59872
|
function createCliPostHog() {
|
|
59692
59873
|
return createPostHogClient("cli", {
|
|
@@ -59910,12 +60091,12 @@ var require_isexe = __commonJS((exports2, module) => {
|
|
|
59910
60091
|
if (typeof Promise !== "function") {
|
|
59911
60092
|
throw new TypeError("callback not provided");
|
|
59912
60093
|
}
|
|
59913
|
-
return new Promise(function(
|
|
60094
|
+
return new Promise(function(resolve11, reject) {
|
|
59914
60095
|
isexe(path8, options || {}, function(er, is) {
|
|
59915
60096
|
if (er) {
|
|
59916
60097
|
reject(er);
|
|
59917
60098
|
} else {
|
|
59918
|
-
|
|
60099
|
+
resolve11(is);
|
|
59919
60100
|
}
|
|
59920
60101
|
});
|
|
59921
60102
|
});
|
|
@@ -59977,27 +60158,27 @@ var require_which = __commonJS((exports2, module) => {
|
|
|
59977
60158
|
opt = {};
|
|
59978
60159
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
59979
60160
|
const found = [];
|
|
59980
|
-
const step = (i2) => new Promise((
|
|
60161
|
+
const step = (i2) => new Promise((resolve11, reject) => {
|
|
59981
60162
|
if (i2 === pathEnv.length)
|
|
59982
|
-
return opt.all && found.length ?
|
|
60163
|
+
return opt.all && found.length ? resolve11(found) : reject(getNotFoundError(cmd));
|
|
59983
60164
|
const ppRaw = pathEnv[i2];
|
|
59984
60165
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
59985
60166
|
const pCmd = path8.join(pathPart, cmd);
|
|
59986
60167
|
const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
59987
|
-
|
|
60168
|
+
resolve11(subStep(p2, i2, 0));
|
|
59988
60169
|
});
|
|
59989
|
-
const subStep = (p2, i2, ii) => new Promise((
|
|
60170
|
+
const subStep = (p2, i2, ii) => new Promise((resolve11, reject) => {
|
|
59990
60171
|
if (ii === pathExt.length)
|
|
59991
|
-
return
|
|
60172
|
+
return resolve11(step(i2 + 1));
|
|
59992
60173
|
const ext = pathExt[ii];
|
|
59993
60174
|
isexe(p2 + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
59994
60175
|
if (!er && is) {
|
|
59995
60176
|
if (opt.all)
|
|
59996
60177
|
found.push(p2 + ext);
|
|
59997
60178
|
else
|
|
59998
|
-
return
|
|
60179
|
+
return resolve11(p2 + ext);
|
|
59999
60180
|
}
|
|
60000
|
-
return
|
|
60181
|
+
return resolve11(subStep(p2, i2, ii + 1));
|
|
60001
60182
|
});
|
|
60002
60183
|
});
|
|
60003
60184
|
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
@@ -60894,8 +61075,8 @@ var init_update_toasts = __esm(() => {
|
|
|
60894
61075
|
});
|
|
60895
61076
|
|
|
60896
61077
|
// src/hooks/auto-update-checker/hook/background-update-check.ts
|
|
60897
|
-
import { existsSync as
|
|
60898
|
-
import { join as
|
|
61078
|
+
import { existsSync as existsSync41 } from "fs";
|
|
61079
|
+
import { join as join47 } from "path";
|
|
60899
61080
|
function getCacheWorkspaceDir(deps) {
|
|
60900
61081
|
return deps.join(deps.getOpenCodeCacheDir(), "packages");
|
|
60901
61082
|
}
|
|
@@ -61013,8 +61194,8 @@ var init_background_update_check = __esm(() => {
|
|
|
61013
61194
|
init_checker();
|
|
61014
61195
|
init_update_toasts();
|
|
61015
61196
|
defaultDeps3 = {
|
|
61016
|
-
existsSync:
|
|
61017
|
-
join:
|
|
61197
|
+
existsSync: existsSync41,
|
|
61198
|
+
join: join47,
|
|
61018
61199
|
runBunInstallWithDetails,
|
|
61019
61200
|
log,
|
|
61020
61201
|
getOpenCodeCacheDir,
|
|
@@ -61173,7 +61354,7 @@ async function showSpinnerToast(ctx, version3, message) {
|
|
|
61173
61354
|
duration: frameInterval + 50
|
|
61174
61355
|
}
|
|
61175
61356
|
}).catch(() => {});
|
|
61176
|
-
await new Promise((
|
|
61357
|
+
await new Promise((resolve12) => setTimeout(resolve12, frameInterval));
|
|
61177
61358
|
}
|
|
61178
61359
|
}
|
|
61179
61360
|
var SISYPHUS_SPINNER;
|
|
@@ -61256,13 +61437,13 @@ v${latestVersion} available. Restart OpenCode to apply.` : "OpenCode is now on S
|
|
|
61256
61437
|
}
|
|
61257
61438
|
};
|
|
61258
61439
|
}
|
|
61259
|
-
var defaultDeps4,
|
|
61440
|
+
var defaultDeps4, isRecord16 = (value) => {
|
|
61260
61441
|
return typeof value === "object" && value !== null;
|
|
61261
61442
|
}, getParentID = (properties) => {
|
|
61262
|
-
if (!
|
|
61443
|
+
if (!isRecord16(properties))
|
|
61263
61444
|
return;
|
|
61264
61445
|
const { info } = properties;
|
|
61265
|
-
if (!
|
|
61446
|
+
if (!isRecord16(info))
|
|
61266
61447
|
return;
|
|
61267
61448
|
const { parentID } = info;
|
|
61268
61449
|
return typeof parentID === "string" && parentID.length > 0 ? parentID : undefined;
|
|
@@ -61326,7 +61507,7 @@ var {
|
|
|
61326
61507
|
// package.json
|
|
61327
61508
|
var package_default = {
|
|
61328
61509
|
name: "oh-my-opencode",
|
|
61329
|
-
version: "4.
|
|
61510
|
+
version: "4.7.0",
|
|
61330
61511
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
61331
61512
|
main: "./dist/index.js",
|
|
61332
61513
|
types: "dist/index.d.ts",
|
|
@@ -61335,6 +61516,7 @@ var package_default = {
|
|
|
61335
61516
|
"packages/rules-engine",
|
|
61336
61517
|
"packages/ast-grep-core",
|
|
61337
61518
|
"packages/ast-grep-mcp",
|
|
61519
|
+
"packages/git-bash-mcp",
|
|
61338
61520
|
"packages/utils",
|
|
61339
61521
|
"packages/model-core",
|
|
61340
61522
|
"packages/prompts-core",
|
|
@@ -61349,7 +61531,8 @@ var package_default = {
|
|
|
61349
61531
|
"oh-my-opencode": "bin/oh-my-opencode.js",
|
|
61350
61532
|
"oh-my-openagent": "bin/oh-my-opencode.js",
|
|
61351
61533
|
omo: "bin/oh-my-opencode.js",
|
|
61352
|
-
lazycodex: "bin/oh-my-opencode.js"
|
|
61534
|
+
lazycodex: "bin/oh-my-opencode.js",
|
|
61535
|
+
"lazycodex-ai": "bin/oh-my-opencode.js"
|
|
61353
61536
|
},
|
|
61354
61537
|
files: [
|
|
61355
61538
|
"dist",
|
|
@@ -61361,6 +61544,7 @@ var package_default = {
|
|
|
61361
61544
|
".agents/skills",
|
|
61362
61545
|
"packages/lsp-tools-mcp/dist",
|
|
61363
61546
|
"packages/ast-grep-mcp/dist",
|
|
61547
|
+
"packages/git-bash-mcp/dist",
|
|
61364
61548
|
"packages/shared-skills/package.json",
|
|
61365
61549
|
"packages/shared-skills/index.mjs",
|
|
61366
61550
|
"packages/shared-skills/skills",
|
|
@@ -61378,7 +61562,7 @@ var package_default = {
|
|
|
61378
61562
|
"./schema.json": "./dist/oh-my-opencode.schema.json"
|
|
61379
61563
|
},
|
|
61380
61564
|
scripts: {
|
|
61381
|
-
build: "bun run build:ast-grep-mcp && bun build src/index.ts --outdir dist --target bun --format esm --external @ast-grep/napi --external zod && bun run build:node-require-shim && tsc --emitDeclarationOnly && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi && bun run build:schema",
|
|
61565
|
+
build: "bun run build:ast-grep-mcp && bun run build:git-bash-mcp && bun build src/index.ts --outdir dist --target bun --format esm --external @ast-grep/napi --external zod && bun run build:node-require-shim && tsc --emitDeclarationOnly && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi && bun run build:schema",
|
|
61382
61566
|
"build:lsp-tools-mcp": "npm --prefix packages/lsp-tools-mcp ci && npm --prefix packages/lsp-tools-mcp run build",
|
|
61383
61567
|
"build:node-require-shim": "bun run script/patch-node-require-shim.ts",
|
|
61384
61568
|
"build:all": "bun run build && bun run build:binaries",
|
|
@@ -61391,12 +61575,13 @@ var package_default = {
|
|
|
61391
61575
|
prepublishOnly: "bun run clean && bun run build:lsp-tools-mcp && bun run build",
|
|
61392
61576
|
"test:model-capabilities": "bun test src/shared/model-capability-aliases.test.ts src/shared/model-capability-guardrails.test.ts src/shared/model-capabilities.test.ts src/cli/doctor/checks/model-resolution.test.ts --bail",
|
|
61393
61577
|
typecheck: "tsgo --noEmit && bun run typecheck:packages",
|
|
61394
|
-
"typecheck:packages": "tsgo --noEmit -p packages/rules-engine/tsconfig.json && tsgo --noEmit -p packages/ast-grep-core/tsconfig.json && tsgo --noEmit -p packages/ast-grep-mcp/tsconfig.json && tsgo --noEmit -p packages/utils/tsconfig.json && tsgo --noEmit -p packages/model-core/tsconfig.json && tsgo --noEmit -p packages/prompts-core/tsconfig.json && tsgo --noEmit -p packages/comment-checker-core/tsconfig.json && tsgo --noEmit -p packages/hashline-core/tsconfig.json && tsgo --noEmit -p packages/boulder-state/tsconfig.json && tsgo --noEmit -p packages/agents-md-core/tsconfig.json && tsgo --noEmit -p packages/omo-codex/tsconfig.json",
|
|
61578
|
+
"typecheck:packages": "tsgo --noEmit -p packages/rules-engine/tsconfig.json && tsgo --noEmit -p packages/ast-grep-core/tsconfig.json && tsgo --noEmit -p packages/ast-grep-mcp/tsconfig.json && tsgo --noEmit -p packages/git-bash-mcp/tsconfig.json && tsgo --noEmit -p packages/utils/tsconfig.json && tsgo --noEmit -p packages/model-core/tsconfig.json && tsgo --noEmit -p packages/prompts-core/tsconfig.json && tsgo --noEmit -p packages/comment-checker-core/tsconfig.json && tsgo --noEmit -p packages/hashline-core/tsconfig.json && tsgo --noEmit -p packages/boulder-state/tsconfig.json && tsgo --noEmit -p packages/agents-md-core/tsconfig.json && tsgo --noEmit -p packages/omo-codex/tsconfig.json",
|
|
61395
61579
|
"typecheck:script": "tsgo --noEmit -p script/tsconfig.json",
|
|
61396
61580
|
test: "bun test",
|
|
61397
|
-
"test:codex": "bun run build:ast-grep-mcp && bun run build:lsp-tools-mcp && npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build && bun test src/cli/cli-installer.platform.test.ts src/cli/install-codex/codex-cache.test.ts src/cli/install-codex/codex-config-agent-cleanup.test.ts src/cli/install-codex/codex-config-toml.test.ts src/cli/install-codex/install-codex.test.ts src/cli/install-codex/link-cached-plugin-agents.test.ts packages/omo-codex/src/**/*.test.ts packages/utils/src/jsonc-parser.test.ts packages/utils/src/frontmatter.test.ts packages/hashline-core/src/hash-computation.test.ts packages/hashline-core/src/smoke-untested-modules.test.ts packages/rules-engine/src/index.test.ts packages/rules-engine/src/security-boundary.test.ts packages/agents-md-core/src/injector.test.ts packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts && node --test packages/omo-codex/plugin/test/*.test.mjs packages/omo-codex/scripts/install-cache-copy.test.mjs packages/omo-codex/scripts/install-config.test.mjs packages/omo-codex/scripts/install-local.test.mjs packages/omo-codex/scripts/install-mcp-runtime.test.mjs packages/omo-codex/scripts/install-agent-links.test.mjs packages/omo-codex/scripts/install-bin-links.test.mjs packages/omo-codex/scripts/sync-telemetry-component.test.mjs",
|
|
61581
|
+
"test:codex": "bun run build:ast-grep-mcp && bun run build:lsp-tools-mcp && npm --prefix packages/omo-codex/plugin ci && bun run --cwd packages/omo-codex/plugin build && bun test src/cli/cli-installer.platform.test.ts src/cli/install-codex/codex-cache.test.ts src/cli/install-codex/codex-cleanup.test.ts src/cli/install-codex/codex-config-agent-cleanup.test.ts src/cli/install-codex/codex-config-reasoning.test.ts src/cli/install-codex/codex-config-toml.test.ts src/cli/install-codex/codex-project-local-cleanup.test.ts src/cli/install-codex/install-codex-project-local-cleanup.test.ts src/cli/install-codex/install-codex.test.ts src/cli/install-codex/install-codex-packaged.test.ts src/cli/install-codex/link-cached-plugin-agents.test.ts packages/omo-codex/src/**/*.test.ts packages/utils/src/jsonc-parser.test.ts packages/utils/src/frontmatter.test.ts packages/hashline-core/src/hash-computation.test.ts packages/hashline-core/src/smoke-untested-modules.test.ts packages/rules-engine/src/index.test.ts packages/rules-engine/src/security-boundary.test.ts packages/agents-md-core/src/injector.test.ts packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts && node --test packages/omo-codex/plugin/test/*.test.mjs packages/omo-codex/scripts/install-cache-copy.test.mjs packages/omo-codex/scripts/install-cli-args.test.mjs packages/omo-codex/scripts/install-config-autonomous.test.mjs packages/omo-codex/scripts/install-config-reasoning.test.mjs packages/omo-codex/scripts/install-config.test.mjs packages/omo-codex/scripts/install-project-local-cleanup.test.mjs packages/omo-codex/scripts/install-local-entrypoint.test.mjs packages/omo-codex/scripts/install-local-git-bash-preflight.test.mjs packages/omo-codex/scripts/install-local.test.mjs packages/omo-codex/scripts/install-mcp-runtime.test.mjs packages/omo-codex/scripts/install-packaged-local.test.mjs packages/omo-codex/scripts/install/git-bash.test.mjs packages/omo-codex/scripts/install-agent-links.test.mjs packages/omo-codex/scripts/install-bin-links.test.mjs packages/omo-codex/scripts/sync-telemetry-component.test.mjs",
|
|
61398
61582
|
"test:windows-codex": "bun run test:codex",
|
|
61399
|
-
"build:ast-grep-mcp": "bun run --cwd packages/ast-grep-mcp build"
|
|
61583
|
+
"build:ast-grep-mcp": "bun run --cwd packages/ast-grep-mcp build",
|
|
61584
|
+
"build:git-bash-mcp": "bun run --cwd packages/git-bash-mcp build"
|
|
61400
61585
|
},
|
|
61401
61586
|
keywords: [
|
|
61402
61587
|
"opencode",
|
|
@@ -61428,7 +61613,6 @@ var package_default = {
|
|
|
61428
61613
|
commander: "^14.0.3",
|
|
61429
61614
|
"detect-libc": "^2.1.2",
|
|
61430
61615
|
diff: "^9.0.0",
|
|
61431
|
-
effect: "4.0.0-beta.65",
|
|
61432
61616
|
"js-yaml": "^4.1.1",
|
|
61433
61617
|
"jsonc-parser": "^3.3.1",
|
|
61434
61618
|
picocolors: "^1.1.1",
|
|
@@ -61439,6 +61623,7 @@ var package_default = {
|
|
|
61439
61623
|
devDependencies: {
|
|
61440
61624
|
"@oh-my-opencode/ast-grep-core": "workspace:*",
|
|
61441
61625
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
61626
|
+
"@oh-my-opencode/git-bash-mcp": "workspace:*",
|
|
61442
61627
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
61443
61628
|
"@oh-my-opencode/boulder-state": "workspace:*",
|
|
61444
61629
|
"@oh-my-opencode/comment-checker-core": "workspace:*",
|
|
@@ -61457,17 +61642,17 @@ var package_default = {
|
|
|
61457
61642
|
zod: "^4.4.3"
|
|
61458
61643
|
},
|
|
61459
61644
|
optionalDependencies: {
|
|
61460
|
-
"oh-my-opencode-darwin-arm64": "4.
|
|
61461
|
-
"oh-my-opencode-darwin-x64": "4.
|
|
61462
|
-
"oh-my-opencode-darwin-x64-baseline": "4.
|
|
61463
|
-
"oh-my-opencode-linux-arm64": "4.
|
|
61464
|
-
"oh-my-opencode-linux-arm64-musl": "4.
|
|
61465
|
-
"oh-my-opencode-linux-x64": "4.
|
|
61466
|
-
"oh-my-opencode-linux-x64-baseline": "4.
|
|
61467
|
-
"oh-my-opencode-linux-x64-musl": "4.
|
|
61468
|
-
"oh-my-opencode-linux-x64-musl-baseline": "4.
|
|
61469
|
-
"oh-my-opencode-windows-x64": "4.
|
|
61470
|
-
"oh-my-opencode-windows-x64-baseline": "4.
|
|
61645
|
+
"oh-my-opencode-darwin-arm64": "4.7.0",
|
|
61646
|
+
"oh-my-opencode-darwin-x64": "4.7.0",
|
|
61647
|
+
"oh-my-opencode-darwin-x64-baseline": "4.7.0",
|
|
61648
|
+
"oh-my-opencode-linux-arm64": "4.7.0",
|
|
61649
|
+
"oh-my-opencode-linux-arm64-musl": "4.7.0",
|
|
61650
|
+
"oh-my-opencode-linux-x64": "4.7.0",
|
|
61651
|
+
"oh-my-opencode-linux-x64-baseline": "4.7.0",
|
|
61652
|
+
"oh-my-opencode-linux-x64-musl": "4.7.0",
|
|
61653
|
+
"oh-my-opencode-linux-x64-musl-baseline": "4.7.0",
|
|
61654
|
+
"oh-my-opencode-windows-x64": "4.7.0",
|
|
61655
|
+
"oh-my-opencode-windows-x64-baseline": "4.7.0"
|
|
61471
61656
|
},
|
|
61472
61657
|
overrides: {
|
|
61473
61658
|
hono: "^4.12.18",
|
|
@@ -61490,6 +61675,7 @@ var package_default = {
|
|
|
61490
61675
|
init_shared();
|
|
61491
61676
|
init_config_manager();
|
|
61492
61677
|
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
61678
|
+
import { createInterface as createInterface2 } from "readline/promises";
|
|
61493
61679
|
|
|
61494
61680
|
// src/cli/install-validators.ts
|
|
61495
61681
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
@@ -61517,6 +61703,9 @@ function formatConfigSummary(config) {
|
|
|
61517
61703
|
if (config.hasCodex) {
|
|
61518
61704
|
lines.push(` ${SYMBOLS.info} Codex autonomous mode: ${config.codexAutonomous ? "enabled" : "disabled"}`);
|
|
61519
61705
|
}
|
|
61706
|
+
if (!config.hasOpenCode)
|
|
61707
|
+
return lines.join(`
|
|
61708
|
+
`);
|
|
61520
61709
|
lines.push("");
|
|
61521
61710
|
const claudeDetail = config.hasClaude ? config.isMax20 ? "max20" : "standard" : undefined;
|
|
61522
61711
|
lines.push(formatProvider("Claude", config.hasClaude, claudeDetail));
|
|
@@ -61524,7 +61713,7 @@ function formatConfigSummary(config) {
|
|
|
61524
61713
|
lines.push(formatProvider("Gemini", config.hasGemini));
|
|
61525
61714
|
lines.push(formatProvider("GitHub Copilot", config.hasCopilot, "fallback"));
|
|
61526
61715
|
lines.push(formatProvider("OpenCode Zen", config.hasOpencodeZen, "opencode/ models"));
|
|
61527
|
-
lines.push(formatProvider("Z.ai Coding Plan", config.hasZaiCodingPlan, "
|
|
61716
|
+
lines.push(formatProvider("Z.ai Coding Plan", config.hasZaiCodingPlan, "GLM fallbacks"));
|
|
61528
61717
|
lines.push(formatProvider("Kimi For Coding", config.hasKimiForCoding, "Sisyphus/Prometheus fallback"));
|
|
61529
61718
|
lines.push(formatProvider("Vercel AI Gateway", config.hasVercelAiGateway, "universal proxy"));
|
|
61530
61719
|
lines.push("");
|
|
@@ -61665,7 +61854,7 @@ function argsToConfig(args) {
|
|
|
61665
61854
|
hasKimiForCoding: hasOpenCode && args.kimiForCoding === "yes",
|
|
61666
61855
|
hasOpencodeGo: hasOpenCode && args.opencodeGo === "yes",
|
|
61667
61856
|
hasVercelAiGateway: hasOpenCode && args.vercelAiGateway === "yes",
|
|
61668
|
-
codexAutonomous: hasCodex && args.codexAutonomous
|
|
61857
|
+
codexAutonomous: hasCodex && args.codexAutonomous !== false
|
|
61669
61858
|
};
|
|
61670
61859
|
}
|
|
61671
61860
|
function detectedToInitialValues(detected) {
|
|
@@ -61742,9 +61931,9 @@ function getUnsupportedOpenCodeVersionMessage(openCodeVersion) {
|
|
|
61742
61931
|
|
|
61743
61932
|
// src/cli/install-codex/install-codex.ts
|
|
61744
61933
|
import { homedir as homedir5 } from "os";
|
|
61745
|
-
import { join as
|
|
61746
|
-
import { existsSync as
|
|
61747
|
-
import { mkdir as mkdir6, writeFile as
|
|
61934
|
+
import { join as join31, resolve as resolve9 } from "path";
|
|
61935
|
+
import { existsSync as existsSync25 } from "fs";
|
|
61936
|
+
import { mkdir as mkdir6, writeFile as writeFile7 } from "fs/promises";
|
|
61748
61937
|
|
|
61749
61938
|
// src/cli/install-codex/codex-cache.ts
|
|
61750
61939
|
import { cp as cp2, lstat as lstat2, mkdir as mkdir2, readFile as readFile4, readdir as readdir2, readlink as readlink2, rename, rm as rm2, symlink, writeFile as writeFile2 } from "fs/promises";
|
|
@@ -61761,6 +61950,13 @@ var BUNDLED_MCP_RUNTIMES = [
|
|
|
61761
61950
|
destinationArg: "./components/ast-grep-mcp/dist/cli.js",
|
|
61762
61951
|
destinationDistFromPlugin: "components/ast-grep-mcp/dist"
|
|
61763
61952
|
},
|
|
61953
|
+
{
|
|
61954
|
+
label: "Git Bash MCP",
|
|
61955
|
+
sourceArg: "../../git-bash-mcp/dist/cli.js",
|
|
61956
|
+
sourceDistFromPlugin: "../../git-bash-mcp/dist",
|
|
61957
|
+
destinationArg: "./components/git-bash-mcp/dist/cli.js",
|
|
61958
|
+
destinationDistFromPlugin: "components/git-bash-mcp/dist"
|
|
61959
|
+
},
|
|
61764
61960
|
{
|
|
61765
61961
|
label: "LSP MCP",
|
|
61766
61962
|
sourceArg: "../../lsp-tools-mcp/dist/cli.js",
|
|
@@ -61833,6 +62029,7 @@ import { lstat, readFile as readFile2, readlink, rm } from "fs/promises";
|
|
|
61833
62029
|
import { join as join20 } from "path";
|
|
61834
62030
|
var LEGACY_CODEX_COMPONENT_BINS = [
|
|
61835
62031
|
{ name: "codex-comment-checker", component: "comment-checker" },
|
|
62032
|
+
{ name: "codex-lsp", component: "lsp" },
|
|
61836
62033
|
{ name: "codex-rules", component: "rules" },
|
|
61837
62034
|
{ name: "codex-start-work-continuation", component: "start-work-continuation" },
|
|
61838
62035
|
{ name: "codex-telemetry", component: "telemetry" },
|
|
@@ -61956,8 +62153,10 @@ function isRecord9(value) {
|
|
|
61956
62153
|
|
|
61957
62154
|
// src/cli/install-codex/codex-cache.ts
|
|
61958
62155
|
async function installCachedPlugin(input) {
|
|
61959
|
-
|
|
61960
|
-
|
|
62156
|
+
if (input.buildSource !== false) {
|
|
62157
|
+
await maybeRunNpmInstall(input.sourcePath, input.runCommand);
|
|
62158
|
+
await maybeRunNpmBuild(input.sourcePath, input.runCommand);
|
|
62159
|
+
}
|
|
61961
62160
|
const targetPath = join22(input.codexHome, "plugins", "cache", input.marketplaceName, input.name, input.version);
|
|
61962
62161
|
await replaceDirectory(input.sourcePath, targetPath);
|
|
61963
62162
|
await rewriteCachedPackageLocalFileDependencies(targetPath, input.sourcePath);
|
|
@@ -62178,11 +62377,38 @@ function isRecord10(value) {
|
|
|
62178
62377
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
62179
62378
|
}
|
|
62180
62379
|
|
|
62380
|
+
// src/cli/install-codex/codex-package-layout.ts
|
|
62381
|
+
import { existsSync as existsSync22 } from "fs";
|
|
62382
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
62383
|
+
import { join as join23 } from "path";
|
|
62384
|
+
var PACKAGED_CODEX_INSTALLER_NAMES = new Set([
|
|
62385
|
+
"@code-yeongyu/lazycodex",
|
|
62386
|
+
"@code-yeongyu/lazycodex-ai",
|
|
62387
|
+
"lazycodex",
|
|
62388
|
+
"lazycodex-ai",
|
|
62389
|
+
"oh-my-opencode",
|
|
62390
|
+
"oh-my-openagent"
|
|
62391
|
+
]);
|
|
62392
|
+
async function shouldBuildSourcePackages(repoRoot) {
|
|
62393
|
+
if (existsSync22(join23(repoRoot, "src", "index.ts")))
|
|
62394
|
+
return true;
|
|
62395
|
+
const packageJsonPath = join23(repoRoot, "package.json");
|
|
62396
|
+
if (!existsSync22(packageJsonPath))
|
|
62397
|
+
return true;
|
|
62398
|
+
const packageJson = JSON.parse(await readFile5(packageJsonPath, "utf8"));
|
|
62399
|
+
if (!isRecord11(packageJson) || typeof packageJson.name !== "string")
|
|
62400
|
+
return true;
|
|
62401
|
+
return !PACKAGED_CODEX_INSTALLER_NAMES.has(packageJson.name);
|
|
62402
|
+
}
|
|
62403
|
+
function isRecord11(value) {
|
|
62404
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
62405
|
+
}
|
|
62406
|
+
|
|
62181
62407
|
// src/cli/install-codex/codex-config-toml.ts
|
|
62182
|
-
import { mkdir as mkdir3, readFile as
|
|
62408
|
+
import { mkdir as mkdir3, readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
|
|
62183
62409
|
import { dirname as dirname12 } from "path";
|
|
62184
62410
|
|
|
62185
|
-
//
|
|
62411
|
+
// packages/omo-codex/scripts/install/toml-editor.mjs
|
|
62186
62412
|
function findTomlSection(config, header) {
|
|
62187
62413
|
const headerLine = `[${header}]`;
|
|
62188
62414
|
const lines = config.match(/[^\n]*\n?|$/g) ?? [];
|
|
@@ -62210,10 +62436,24 @@ function replaceOrInsertSetting(config, section, key, value) {
|
|
|
62210
62436
|
return config.slice(0, section.start) + replacement + config.slice(section.end);
|
|
62211
62437
|
}
|
|
62212
62438
|
function removeSetting(config, section, key) {
|
|
62213
|
-
const linePattern = new RegExp(
|
|
62439
|
+
const linePattern = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=.*(?:\\n|$)`, "m");
|
|
62214
62440
|
const replacement = section.text.replace(linePattern, "");
|
|
62215
62441
|
return config.slice(0, section.start) + replacement + config.slice(section.end);
|
|
62216
62442
|
}
|
|
62443
|
+
function replaceOrInsertRootSetting(config, key, value) {
|
|
62444
|
+
const sectionStart = findFirstTableStart(config);
|
|
62445
|
+
const root = config.slice(0, sectionStart);
|
|
62446
|
+
const suffix = config.slice(sectionStart);
|
|
62447
|
+
const linePattern = new RegExp(`^${escapeRegExp(key)}\\s*=.*$`, "m");
|
|
62448
|
+
const replacement = linePattern.test(root) ? root.replace(linePattern, `${key} = ${value}`) : `${root.trimEnd()}${root.trimEnd().length > 0 ? `
|
|
62449
|
+
` : ""}${key} = ${value}
|
|
62450
|
+
`;
|
|
62451
|
+
if (suffix.length === 0)
|
|
62452
|
+
return replacement;
|
|
62453
|
+
return `${replacement.trimEnd()}
|
|
62454
|
+
|
|
62455
|
+
${suffix.trimStart()}`;
|
|
62456
|
+
}
|
|
62217
62457
|
function appendBlock(config, block) {
|
|
62218
62458
|
const prefix = config.trimEnd();
|
|
62219
62459
|
return `${prefix}${prefix.length > 0 ? `
|
|
@@ -62221,6 +62461,10 @@ function appendBlock(config, block) {
|
|
|
62221
62461
|
` : ""}${block.trimEnd()}
|
|
62222
62462
|
`;
|
|
62223
62463
|
}
|
|
62464
|
+
function findFirstTableStart(config) {
|
|
62465
|
+
const match = config.match(/^[[].*$/m);
|
|
62466
|
+
return match?.index ?? config.length;
|
|
62467
|
+
}
|
|
62224
62468
|
function insertSetting(sectionText, key, value) {
|
|
62225
62469
|
const lines = sectionText.split(`
|
|
62226
62470
|
`);
|
|
@@ -62232,34 +62476,268 @@ function escapeRegExp(value) {
|
|
|
62232
62476
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
62233
62477
|
}
|
|
62234
62478
|
|
|
62479
|
+
// packages/omo-codex/scripts/install/permissions.mjs
|
|
62480
|
+
function ensureAutonomousPermissions(config) {
|
|
62481
|
+
let next = replaceOrInsertRootSetting(config, "approval_policy", JSON.stringify("never"));
|
|
62482
|
+
next = replaceOrInsertRootSetting(next, "sandbox_mode", JSON.stringify("danger-full-access"));
|
|
62483
|
+
next = replaceOrInsertRootSetting(next, "network_access", JSON.stringify("enabled"));
|
|
62484
|
+
next = removeWindowsSandboxSetting(next);
|
|
62485
|
+
next = ensureNoticeEnabled(next, "hide_full_access_warning");
|
|
62486
|
+
return ensureNoticeEnabled(next, "hide_world_writable_warning");
|
|
62487
|
+
}
|
|
62488
|
+
function removeWindowsSandboxSetting(config) {
|
|
62489
|
+
const section = findTomlSection(config, "windows");
|
|
62490
|
+
if (!section)
|
|
62491
|
+
return config;
|
|
62492
|
+
return removeSetting(config, section, "sandbox");
|
|
62493
|
+
}
|
|
62494
|
+
function ensureNoticeEnabled(config, key) {
|
|
62495
|
+
const section = findTomlSection(config, "notice");
|
|
62496
|
+
if (!section)
|
|
62497
|
+
return appendNoticeBlock(config, key);
|
|
62498
|
+
return replaceOrInsertSetting(config, section, key, "true");
|
|
62499
|
+
}
|
|
62500
|
+
function appendNoticeBlock(config, key) {
|
|
62501
|
+
return appendBlock(config, `[notice]
|
|
62502
|
+
${key} = true
|
|
62503
|
+
`);
|
|
62504
|
+
}
|
|
62505
|
+
// src/cli/install-codex/toml-section-editor.ts
|
|
62506
|
+
function findTomlSection2(config, header) {
|
|
62507
|
+
const headerLine = `[${header}]`;
|
|
62508
|
+
const lines = config.match(/[^\n]*\n?|$/g) ?? [];
|
|
62509
|
+
let offset = 0;
|
|
62510
|
+
let start = -1;
|
|
62511
|
+
for (const line of lines) {
|
|
62512
|
+
if (line.length === 0)
|
|
62513
|
+
break;
|
|
62514
|
+
const trimmed = line.trim();
|
|
62515
|
+
if (start === -1) {
|
|
62516
|
+
if (trimmed === headerLine)
|
|
62517
|
+
start = offset;
|
|
62518
|
+
} else if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
62519
|
+
return { start, end: offset, text: config.slice(start, offset) };
|
|
62520
|
+
}
|
|
62521
|
+
offset += line.length;
|
|
62522
|
+
}
|
|
62523
|
+
if (start === -1)
|
|
62524
|
+
return null;
|
|
62525
|
+
return { start, end: config.length, text: config.slice(start) };
|
|
62526
|
+
}
|
|
62527
|
+
function replaceOrInsertSetting2(config, section, key, value) {
|
|
62528
|
+
const linePattern = new RegExp(`^${escapeRegExp2(key)}\\s*=.*$`, "m");
|
|
62529
|
+
const replacement = linePattern.test(section.text) ? section.text.replace(linePattern, `${key} = ${value}`) : insertSetting2(section.text, key, value);
|
|
62530
|
+
return config.slice(0, section.start) + replacement + config.slice(section.end);
|
|
62531
|
+
}
|
|
62532
|
+
function removeSetting2(config, section, key) {
|
|
62533
|
+
const linePattern = new RegExp(`^\\s*${escapeRegExp2(key)}\\s*=.*(?:\\n|$)`, "m");
|
|
62534
|
+
const replacement = section.text.replace(linePattern, "");
|
|
62535
|
+
return config.slice(0, section.start) + replacement + config.slice(section.end);
|
|
62536
|
+
}
|
|
62537
|
+
function replaceOrInsertRootSetting2(config, key, value) {
|
|
62538
|
+
const sectionStart = findFirstTableStart2(config);
|
|
62539
|
+
const root = config.slice(0, sectionStart);
|
|
62540
|
+
const suffix = config.slice(sectionStart);
|
|
62541
|
+
const linePattern = new RegExp(`^${escapeRegExp2(key)}\\s*=.*$`, "m");
|
|
62542
|
+
const replacement = linePattern.test(root) ? root.replace(linePattern, `${key} = ${value}`) : `${root.trimEnd()}${root.trimEnd().length > 0 ? `
|
|
62543
|
+
` : ""}${key} = ${value}
|
|
62544
|
+
`;
|
|
62545
|
+
if (suffix.length === 0)
|
|
62546
|
+
return replacement;
|
|
62547
|
+
return `${replacement.trimEnd()}
|
|
62548
|
+
|
|
62549
|
+
${suffix.trimStart()}`;
|
|
62550
|
+
}
|
|
62551
|
+
function appendBlock2(config, block) {
|
|
62552
|
+
const prefix = config.trimEnd();
|
|
62553
|
+
return `${prefix}${prefix.length > 0 ? `
|
|
62554
|
+
|
|
62555
|
+
` : ""}${block.trimEnd()}
|
|
62556
|
+
`;
|
|
62557
|
+
}
|
|
62558
|
+
function findFirstTableStart2(config) {
|
|
62559
|
+
const match = config.match(/^[[].*$/m);
|
|
62560
|
+
return match?.index ?? config.length;
|
|
62561
|
+
}
|
|
62562
|
+
function insertSetting2(sectionText, key, value) {
|
|
62563
|
+
const lines = sectionText.split(`
|
|
62564
|
+
`);
|
|
62565
|
+
lines.splice(1, 0, `${key} = ${value}`);
|
|
62566
|
+
return lines.join(`
|
|
62567
|
+
`);
|
|
62568
|
+
}
|
|
62569
|
+
function escapeRegExp2(value) {
|
|
62570
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
62571
|
+
}
|
|
62572
|
+
|
|
62573
|
+
// src/cli/install-codex/codex-config-reasoning.ts
|
|
62574
|
+
var MANAGED_KEYS = ["model", "model_context_window", "model_reasoning_effort", "plan_mode_reasoning_effort"];
|
|
62575
|
+
function ensureCodexReasoningConfig(config, catalog) {
|
|
62576
|
+
const current = readRootReasoningSettings(config);
|
|
62577
|
+
if (Object.keys(current).length > 0 && !matchesProfile(current, catalog.current) && !catalog.managedProfiles.some((profile) => matchesProfile(current, profile))) {
|
|
62578
|
+
return config;
|
|
62579
|
+
}
|
|
62580
|
+
let next = replaceOrInsertRootSetting2(config, "model", JSON.stringify(catalog.current.model));
|
|
62581
|
+
next = replaceOrInsertRootSetting2(next, "model_context_window", catalog.current.modelContextWindow.toString());
|
|
62582
|
+
next = replaceOrInsertRootSetting2(next, "model_reasoning_effort", JSON.stringify(catalog.current.modelReasoningEffort));
|
|
62583
|
+
next = replaceOrInsertRootSetting2(next, "plan_mode_reasoning_effort", JSON.stringify(catalog.current.planModeReasoningEffort));
|
|
62584
|
+
return next;
|
|
62585
|
+
}
|
|
62586
|
+
function readRootReasoningSettings(config) {
|
|
62587
|
+
const settings = {};
|
|
62588
|
+
for (const line of config.split(/\n/)) {
|
|
62589
|
+
if (isSectionHeader(line))
|
|
62590
|
+
break;
|
|
62591
|
+
for (const key of MANAGED_KEYS) {
|
|
62592
|
+
if (!isRootSetting(line, key))
|
|
62593
|
+
continue;
|
|
62594
|
+
const value = parseTomlScalar(line.slice(line.indexOf("=") + 1));
|
|
62595
|
+
if (key === "model" && typeof value === "string")
|
|
62596
|
+
settings.model = value;
|
|
62597
|
+
if (key === "model_context_window" && typeof value === "number")
|
|
62598
|
+
settings.modelContextWindow = value;
|
|
62599
|
+
if (key === "model_reasoning_effort" && typeof value === "string")
|
|
62600
|
+
settings.modelReasoningEffort = value;
|
|
62601
|
+
if (key === "plan_mode_reasoning_effort" && typeof value === "string")
|
|
62602
|
+
settings.planModeReasoningEffort = value;
|
|
62603
|
+
}
|
|
62604
|
+
}
|
|
62605
|
+
return settings;
|
|
62606
|
+
}
|
|
62607
|
+
function matchesProfile(current, profile) {
|
|
62608
|
+
for (const [key, value] of Object.entries(profile)) {
|
|
62609
|
+
if (current[key] !== value)
|
|
62610
|
+
return false;
|
|
62611
|
+
}
|
|
62612
|
+
return true;
|
|
62613
|
+
}
|
|
62614
|
+
function parseTomlScalar(value) {
|
|
62615
|
+
const trimmed = value.trim();
|
|
62616
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
62617
|
+
try {
|
|
62618
|
+
return JSON.parse(trimmed);
|
|
62619
|
+
} catch (error) {
|
|
62620
|
+
if (error instanceof SyntaxError)
|
|
62621
|
+
return;
|
|
62622
|
+
throw error;
|
|
62623
|
+
}
|
|
62624
|
+
}
|
|
62625
|
+
const numeric = Number(trimmed);
|
|
62626
|
+
return Number.isFinite(numeric) ? numeric : undefined;
|
|
62627
|
+
}
|
|
62628
|
+
function isSectionHeader(line) {
|
|
62629
|
+
const trimmed = line.trim();
|
|
62630
|
+
return trimmed.startsWith("[") && trimmed.endsWith("]");
|
|
62631
|
+
}
|
|
62632
|
+
function isRootSetting(line, key) {
|
|
62633
|
+
const trimmed = line.trimStart();
|
|
62634
|
+
if (trimmed.startsWith("#") || trimmed.startsWith("["))
|
|
62635
|
+
return false;
|
|
62636
|
+
const match = trimmed.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=/);
|
|
62637
|
+
return match?.[1] === key;
|
|
62638
|
+
}
|
|
62639
|
+
|
|
62640
|
+
// src/cli/install-codex/codex-model-catalog.ts
|
|
62641
|
+
import { readFile as readFile6 } from "fs/promises";
|
|
62642
|
+
import { join as join24 } from "path";
|
|
62643
|
+
var FALLBACK_CODEX_MODEL_CATALOG = {
|
|
62644
|
+
current: {
|
|
62645
|
+
model: "gpt-5.5",
|
|
62646
|
+
modelContextWindow: 400000,
|
|
62647
|
+
modelReasoningEffort: "high",
|
|
62648
|
+
planModeReasoningEffort: "xhigh"
|
|
62649
|
+
},
|
|
62650
|
+
managedProfiles: [{ model: "gpt-5.2" }]
|
|
62651
|
+
};
|
|
62652
|
+
async function readCodexModelCatalog(codexPackageRoot) {
|
|
62653
|
+
const catalogPath = join24(codexPackageRoot, "plugin", "model-catalog.json");
|
|
62654
|
+
try {
|
|
62655
|
+
const parsed = JSON.parse(await readFile6(catalogPath, "utf8"));
|
|
62656
|
+
return parseCodexModelCatalog(parsed) ?? FALLBACK_CODEX_MODEL_CATALOG;
|
|
62657
|
+
} catch (error) {
|
|
62658
|
+
if (error instanceof Error)
|
|
62659
|
+
return FALLBACK_CODEX_MODEL_CATALOG;
|
|
62660
|
+
throw error;
|
|
62661
|
+
}
|
|
62662
|
+
}
|
|
62663
|
+
function parseCodexModelCatalog(value) {
|
|
62664
|
+
if (!isRecord12(value))
|
|
62665
|
+
return null;
|
|
62666
|
+
const current = value["current"];
|
|
62667
|
+
const managedProfiles = value["managedProfiles"];
|
|
62668
|
+
if (!isRecord12(current) || !Array.isArray(managedProfiles))
|
|
62669
|
+
return null;
|
|
62670
|
+
const model = current["model"];
|
|
62671
|
+
const modelContextWindow = current["model_context_window"];
|
|
62672
|
+
const modelReasoningEffort = current["model_reasoning_effort"];
|
|
62673
|
+
const planModeReasoningEffort = current["plan_mode_reasoning_effort"];
|
|
62674
|
+
if (typeof model !== "string" || typeof modelContextWindow !== "number" || typeof modelReasoningEffort !== "string" || typeof planModeReasoningEffort !== "string") {
|
|
62675
|
+
return null;
|
|
62676
|
+
}
|
|
62677
|
+
const parsedManagedProfiles = [];
|
|
62678
|
+
for (const profile of managedProfiles) {
|
|
62679
|
+
if (!isRecord12(profile))
|
|
62680
|
+
return null;
|
|
62681
|
+
const match = profile["match"];
|
|
62682
|
+
if (!isRecord12(match))
|
|
62683
|
+
return null;
|
|
62684
|
+
parsedManagedProfiles.push(parseProfileMatch(match));
|
|
62685
|
+
}
|
|
62686
|
+
return {
|
|
62687
|
+
current: { model, modelContextWindow, modelReasoningEffort, planModeReasoningEffort },
|
|
62688
|
+
managedProfiles: parsedManagedProfiles
|
|
62689
|
+
};
|
|
62690
|
+
}
|
|
62691
|
+
function parseProfileMatch(match) {
|
|
62692
|
+
const profile = {};
|
|
62693
|
+
if (typeof match["model"] === "string")
|
|
62694
|
+
profile.model = match["model"];
|
|
62695
|
+
if (typeof match["model_context_window"] === "number")
|
|
62696
|
+
profile.modelContextWindow = match["model_context_window"];
|
|
62697
|
+
if (typeof match["model_reasoning_effort"] === "string")
|
|
62698
|
+
profile.modelReasoningEffort = match["model_reasoning_effort"];
|
|
62699
|
+
if (typeof match["plan_mode_reasoning_effort"] === "string")
|
|
62700
|
+
profile.planModeReasoningEffort = match["plan_mode_reasoning_effort"];
|
|
62701
|
+
return profile;
|
|
62702
|
+
}
|
|
62703
|
+
function isRecord12(value) {
|
|
62704
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
62705
|
+
}
|
|
62706
|
+
|
|
62235
62707
|
// src/cli/install-codex/codex-multi-agent-v2-config.ts
|
|
62236
62708
|
var CODEX_MULTI_AGENT_V2_HEADER = "features.multi_agent_v2";
|
|
62237
62709
|
var CODEX_MULTI_AGENT_V2_MAX_CONCURRENT_THREADS_PER_SESSION = 1e4;
|
|
62238
62710
|
function ensureCodexMultiAgentV2Config(config) {
|
|
62239
|
-
const normalizedConfig = removeFeatureFlagSetting(config, "multi_agent_v2");
|
|
62240
|
-
const section =
|
|
62711
|
+
const normalizedConfig = removeLegacyAgentsMaxThreadsSetting(removeFeatureFlagSetting(config, "multi_agent_v2"));
|
|
62712
|
+
const section = findTomlSection2(normalizedConfig, CODEX_MULTI_AGENT_V2_HEADER);
|
|
62241
62713
|
const maxThreadsValue = CODEX_MULTI_AGENT_V2_MAX_CONCURRENT_THREADS_PER_SESSION.toString();
|
|
62242
62714
|
if (!section) {
|
|
62243
|
-
return
|
|
62715
|
+
return appendBlock2(normalizedConfig, `[${CODEX_MULTI_AGENT_V2_HEADER}]
|
|
62244
62716
|
enabled = true
|
|
62245
62717
|
max_concurrent_threads_per_session = ${maxThreadsValue}
|
|
62246
62718
|
`);
|
|
62247
62719
|
}
|
|
62248
|
-
const enabledConfig =
|
|
62249
|
-
const updatedSection =
|
|
62720
|
+
const enabledConfig = replaceOrInsertSetting2(normalizedConfig, section, "enabled", "true");
|
|
62721
|
+
const updatedSection = findTomlSection2(enabledConfig, CODEX_MULTI_AGENT_V2_HEADER);
|
|
62250
62722
|
if (!updatedSection) {
|
|
62251
|
-
return
|
|
62723
|
+
return appendBlock2(enabledConfig, `[${CODEX_MULTI_AGENT_V2_HEADER}]
|
|
62252
62724
|
enabled = true
|
|
62253
62725
|
max_concurrent_threads_per_session = ${maxThreadsValue}
|
|
62254
62726
|
`);
|
|
62255
62727
|
}
|
|
62256
|
-
return
|
|
62728
|
+
return replaceOrInsertSetting2(enabledConfig, updatedSection, "max_concurrent_threads_per_session", maxThreadsValue);
|
|
62257
62729
|
}
|
|
62258
62730
|
function removeFeatureFlagSetting(config, featureName) {
|
|
62259
|
-
const section =
|
|
62731
|
+
const section = findTomlSection2(config, "features");
|
|
62732
|
+
if (!section)
|
|
62733
|
+
return config;
|
|
62734
|
+
return removeSetting2(config, section, featureName);
|
|
62735
|
+
}
|
|
62736
|
+
function removeLegacyAgentsMaxThreadsSetting(config) {
|
|
62737
|
+
const section = findTomlSection2(config, "agents");
|
|
62260
62738
|
if (!section)
|
|
62261
62739
|
return config;
|
|
62262
|
-
return
|
|
62740
|
+
return removeSetting2(config, section, "max_threads");
|
|
62263
62741
|
}
|
|
62264
62742
|
|
|
62265
62743
|
// src/cli/install-codex/codex-config-toml.ts
|
|
@@ -62276,7 +62754,7 @@ async function updateCodexConfig(input) {
|
|
|
62276
62754
|
await mkdir3(dirname12(input.configPath), { recursive: true });
|
|
62277
62755
|
let config = "";
|
|
62278
62756
|
if (await exists2(input.configPath))
|
|
62279
|
-
config = await
|
|
62757
|
+
config = await readFile7(input.configPath, "utf8");
|
|
62280
62758
|
const pluginSet = new Set(input.pluginNames);
|
|
62281
62759
|
for (const legacyMarketplaceName of legacyMarketplaceNames(input.marketplaceName)) {
|
|
62282
62760
|
config = removeMarketplaceBlock(config, legacyMarketplaceName);
|
|
@@ -62288,6 +62766,7 @@ async function updateCodexConfig(input) {
|
|
|
62288
62766
|
config = removeStaleManagedAgentBlocks(config, new Set((input.agentConfigs ?? []).map((agentConfig) => agentConfig.name)));
|
|
62289
62767
|
config = ensureFeatureEnabled(config, "plugins");
|
|
62290
62768
|
config = ensureFeatureEnabled(config, "plugin_hooks");
|
|
62769
|
+
config = ensureCodexReasoningConfig(config, await readCodexModelCatalog(input.repoRoot));
|
|
62291
62770
|
config = ensureCodexMultiAgentV2Config(config);
|
|
62292
62771
|
if (input.autonomousPermissions === true)
|
|
62293
62772
|
config = ensureAutonomousPermissions(config);
|
|
@@ -62295,6 +62774,7 @@ async function updateCodexConfig(input) {
|
|
|
62295
62774
|
for (const pluginName of input.pluginNames) {
|
|
62296
62775
|
config = ensurePluginEnabled(config, `${pluginName}@${input.marketplaceName}`);
|
|
62297
62776
|
}
|
|
62777
|
+
config = ensureOmoGitBashMcpPolicy(config, input);
|
|
62298
62778
|
for (const state of input.trustedHookStates ?? []) {
|
|
62299
62779
|
config = ensureHookTrusted(config, state.key, state.trustedHash);
|
|
62300
62780
|
}
|
|
@@ -62353,48 +62833,12 @@ function removeStaleManagedAgentBlocks(config, keepAgentNames) {
|
|
|
62353
62833
|
`);
|
|
62354
62834
|
}
|
|
62355
62835
|
function ensureFeatureEnabled(config, featureName) {
|
|
62356
|
-
const section =
|
|
62836
|
+
const section = findTomlSection2(config, "features");
|
|
62357
62837
|
if (!section)
|
|
62358
|
-
return
|
|
62838
|
+
return appendBlock2(config, `[features]
|
|
62359
62839
|
${featureName} = true
|
|
62360
62840
|
`);
|
|
62361
|
-
return
|
|
62362
|
-
}
|
|
62363
|
-
function ensureAutonomousPermissions(config) {
|
|
62364
|
-
let next = replaceOrInsertRootSetting(config, "approval_policy", JSON.stringify("never"));
|
|
62365
|
-
next = replaceOrInsertRootSetting(next, "sandbox_mode", JSON.stringify("danger-full-access"));
|
|
62366
|
-
next = replaceOrInsertRootSetting(next, "network_access", JSON.stringify("enabled"));
|
|
62367
|
-
next = ensureNoticeEnabled(next, "hide_full_access_warning");
|
|
62368
|
-
return ensureNoticeEnabled(next, "hide_world_writable_warning");
|
|
62369
|
-
}
|
|
62370
|
-
function ensureNoticeEnabled(config, key) {
|
|
62371
|
-
const section = findTomlSection(config, "notice");
|
|
62372
|
-
if (!section)
|
|
62373
|
-
return appendBlock(config, `[notice]
|
|
62374
|
-
${key} = true
|
|
62375
|
-
`);
|
|
62376
|
-
return replaceOrInsertSetting(config, section, key, "true");
|
|
62377
|
-
}
|
|
62378
|
-
function replaceOrInsertRootSetting(config, key, value) {
|
|
62379
|
-
const sectionStart = findFirstTableStart(config);
|
|
62380
|
-
const root = config.slice(0, sectionStart);
|
|
62381
|
-
const suffix = config.slice(sectionStart);
|
|
62382
|
-
const linePattern = new RegExp(`^${escapeRegExp2(key)}\\s*=.*$`, "m");
|
|
62383
|
-
const replacement = linePattern.test(root) ? root.replace(linePattern, `${key} = ${value}`) : `${root.trimEnd()}${root.trimEnd().length > 0 ? `
|
|
62384
|
-
` : ""}${key} = ${value}
|
|
62385
|
-
`;
|
|
62386
|
-
if (suffix.length === 0)
|
|
62387
|
-
return replacement;
|
|
62388
|
-
return `${replacement.trimEnd()}
|
|
62389
|
-
|
|
62390
|
-
${suffix.trimStart()}`;
|
|
62391
|
-
}
|
|
62392
|
-
function findFirstTableStart(config) {
|
|
62393
|
-
const match = config.match(/^[[].*$/m);
|
|
62394
|
-
return match?.index ?? config.length;
|
|
62395
|
-
}
|
|
62396
|
-
function escapeRegExp2(value) {
|
|
62397
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
62841
|
+
return replaceOrInsertSetting2(config, section, featureName, "true");
|
|
62398
62842
|
}
|
|
62399
62843
|
function ensureMarketplaceBlock(config, marketplaceName, source) {
|
|
62400
62844
|
const header = `marketplaces.${marketplaceName}`;
|
|
@@ -62410,38 +62854,54 @@ function ensureMarketplaceBlock(config, marketplaceName, source) {
|
|
|
62410
62854
|
lines.push("");
|
|
62411
62855
|
const block = lines.join(`
|
|
62412
62856
|
`);
|
|
62413
|
-
const section =
|
|
62857
|
+
const section = findTomlSection2(config, header);
|
|
62414
62858
|
if (section)
|
|
62415
62859
|
return config.slice(0, section.start) + block + config.slice(section.end);
|
|
62416
|
-
return
|
|
62860
|
+
return appendBlock2(config, block);
|
|
62417
62861
|
}
|
|
62418
62862
|
function ensurePluginEnabled(config, pluginKey) {
|
|
62419
62863
|
const header = `plugins.${JSON.stringify(pluginKey)}`;
|
|
62420
|
-
const section =
|
|
62864
|
+
const section = findTomlSection2(config, header);
|
|
62421
62865
|
if (!section)
|
|
62422
|
-
return
|
|
62866
|
+
return appendBlock2(config, `[${header}]
|
|
62423
62867
|
enabled = true
|
|
62424
62868
|
`);
|
|
62425
|
-
return
|
|
62869
|
+
return replaceOrInsertSetting2(config, section, "enabled", "true");
|
|
62870
|
+
}
|
|
62871
|
+
function ensurePluginMcpEnabled(config, pluginKey, serverName, enabled) {
|
|
62872
|
+
const header = `plugins.${JSON.stringify(pluginKey)}.mcp_servers.${serverName}`;
|
|
62873
|
+
const section = findTomlSection2(config, header);
|
|
62874
|
+
const enabledValue = enabled ? "true" : "false";
|
|
62875
|
+
if (!section)
|
|
62876
|
+
return appendBlock2(config, `[${header}]
|
|
62877
|
+
enabled = ${enabledValue}
|
|
62878
|
+
`);
|
|
62879
|
+
return replaceOrInsertSetting2(config, section, "enabled", enabledValue);
|
|
62880
|
+
}
|
|
62881
|
+
function ensureOmoGitBashMcpPolicy(config, input) {
|
|
62882
|
+
if (input.marketplaceName !== "sisyphuslabs" || !input.pluginNames.includes("omo"))
|
|
62883
|
+
return config;
|
|
62884
|
+
const enabled = (input.platform ?? process.platform) === "win32";
|
|
62885
|
+
return ensurePluginMcpEnabled(config, "omo@sisyphuslabs", "git_bash", enabled);
|
|
62426
62886
|
}
|
|
62427
62887
|
function ensureHookTrusted(config, key, trustedHash) {
|
|
62428
62888
|
const header = `hooks.state.${JSON.stringify(key)}`;
|
|
62429
|
-
const section =
|
|
62889
|
+
const section = findTomlSection2(config, header);
|
|
62430
62890
|
if (!section)
|
|
62431
|
-
return
|
|
62891
|
+
return appendBlock2(config, `[${header}]
|
|
62432
62892
|
trusted_hash = ${JSON.stringify(trustedHash)}
|
|
62433
62893
|
`);
|
|
62434
|
-
return
|
|
62894
|
+
return replaceOrInsertSetting2(config, section, "trusted_hash", JSON.stringify(trustedHash));
|
|
62435
62895
|
}
|
|
62436
62896
|
function ensureAgentConfig(config, agentConfig) {
|
|
62437
62897
|
const header = `agents.${tomlKeySegment(agentConfig.name)}`;
|
|
62438
|
-
const section =
|
|
62898
|
+
const section = findTomlSection2(config, header);
|
|
62439
62899
|
const configFile = JSON.stringify(agentConfig.configFile);
|
|
62440
62900
|
if (!section)
|
|
62441
|
-
return
|
|
62901
|
+
return appendBlock2(config, `[${header}]
|
|
62442
62902
|
config_file = ${configFile}
|
|
62443
62903
|
`);
|
|
62444
|
-
return
|
|
62904
|
+
return replaceOrInsertSetting2(config, section, "config_file", configFile);
|
|
62445
62905
|
}
|
|
62446
62906
|
function tomlKeySegment(value) {
|
|
62447
62907
|
return /^[A-Za-z0-9_-]+$/.test(value) ? value : JSON.stringify(value);
|
|
@@ -62521,7 +62981,7 @@ function parseJsonString(value) {
|
|
|
62521
62981
|
}
|
|
62522
62982
|
async function exists2(path6) {
|
|
62523
62983
|
try {
|
|
62524
|
-
await
|
|
62984
|
+
await readFile7(path6, "utf8");
|
|
62525
62985
|
return true;
|
|
62526
62986
|
} catch (error) {
|
|
62527
62987
|
if (error instanceof Error)
|
|
@@ -62531,9 +62991,9 @@ async function exists2(path6) {
|
|
|
62531
62991
|
}
|
|
62532
62992
|
|
|
62533
62993
|
// src/cli/install-codex/codex-hook-trust.ts
|
|
62534
|
-
import { createHash } from "crypto";
|
|
62535
|
-
import { readFile as
|
|
62536
|
-
import { join as
|
|
62994
|
+
import { createHash as createHash2 } from "crypto";
|
|
62995
|
+
import { readFile as readFile8 } from "fs/promises";
|
|
62996
|
+
import { join as join25 } from "path";
|
|
62537
62997
|
var EVENT_LABELS = new Map([
|
|
62538
62998
|
["PreToolUse", "pre_tool_use"],
|
|
62539
62999
|
["PermissionRequest", "permission_request"],
|
|
@@ -62547,17 +63007,17 @@ var EVENT_LABELS = new Map([
|
|
|
62547
63007
|
["Stop", "stop"]
|
|
62548
63008
|
]);
|
|
62549
63009
|
async function trustedHookStatesForPlugin(input) {
|
|
62550
|
-
const manifestPath =
|
|
63010
|
+
const manifestPath = join25(input.pluginRoot, ".codex-plugin", "plugin.json");
|
|
62551
63011
|
if (!await exists3(manifestPath))
|
|
62552
63012
|
return [];
|
|
62553
|
-
const manifest = JSON.parse(await
|
|
62554
|
-
if (!
|
|
63013
|
+
const manifest = JSON.parse(await readFile8(manifestPath, "utf8"));
|
|
63014
|
+
if (!isRecord13(manifest) || typeof manifest.hooks !== "string")
|
|
62555
63015
|
return [];
|
|
62556
|
-
const hooksPath =
|
|
63016
|
+
const hooksPath = join25(input.pluginRoot, manifest.hooks);
|
|
62557
63017
|
if (!await exists3(hooksPath))
|
|
62558
63018
|
return [];
|
|
62559
|
-
const parsed = JSON.parse(await
|
|
62560
|
-
if (!
|
|
63019
|
+
const parsed = JSON.parse(await readFile8(hooksPath, "utf8"));
|
|
63020
|
+
if (!isRecord13(parsed) || !isRecord13(parsed.hooks))
|
|
62561
63021
|
return [];
|
|
62562
63022
|
const keySource = `${input.pluginName}@${input.marketplaceName}:${stripDotSlash(manifest.hooks)}`;
|
|
62563
63023
|
const states = [];
|
|
@@ -62568,10 +63028,10 @@ async function trustedHookStatesForPlugin(input) {
|
|
|
62568
63028
|
if (eventLabel === undefined)
|
|
62569
63029
|
continue;
|
|
62570
63030
|
for (const [groupIndex, group] of groups.entries()) {
|
|
62571
|
-
if (!
|
|
63031
|
+
if (!isRecord13(group) || !Array.isArray(group.hooks))
|
|
62572
63032
|
continue;
|
|
62573
63033
|
for (const [handlerIndex, handler] of group.hooks.entries()) {
|
|
62574
|
-
if (!
|
|
63034
|
+
if (!isRecord13(handler) || handler.type !== "command")
|
|
62575
63035
|
continue;
|
|
62576
63036
|
if (handler.async === true)
|
|
62577
63037
|
continue;
|
|
@@ -62598,12 +63058,12 @@ function commandHookHash(eventName, matcher, handler) {
|
|
|
62598
63058
|
if (typeof matcher === "string")
|
|
62599
63059
|
identity.matcher = matcher;
|
|
62600
63060
|
const canonical = JSON.stringify(canonicalJson(identity));
|
|
62601
|
-
return `sha256:${
|
|
63061
|
+
return `sha256:${createHash2("sha256").update(canonical).digest("hex")}`;
|
|
62602
63062
|
}
|
|
62603
63063
|
function canonicalJson(value) {
|
|
62604
63064
|
if (Array.isArray(value))
|
|
62605
63065
|
return value.map(canonicalJson);
|
|
62606
|
-
if (!
|
|
63066
|
+
if (!isRecord13(value))
|
|
62607
63067
|
return value;
|
|
62608
63068
|
const result = {};
|
|
62609
63069
|
for (const key of Object.keys(value).sort()) {
|
|
@@ -62616,19 +63076,113 @@ function stripDotSlash(value) {
|
|
|
62616
63076
|
}
|
|
62617
63077
|
async function exists3(path6) {
|
|
62618
63078
|
try {
|
|
62619
|
-
await
|
|
63079
|
+
await readFile8(path6, "utf8");
|
|
62620
63080
|
return true;
|
|
62621
63081
|
} catch {
|
|
62622
63082
|
return false;
|
|
62623
63083
|
}
|
|
62624
63084
|
}
|
|
62625
|
-
function
|
|
63085
|
+
function isRecord13(value) {
|
|
62626
63086
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
62627
63087
|
}
|
|
62628
63088
|
|
|
63089
|
+
// src/cli/install-codex/git-bash.ts
|
|
63090
|
+
import { execFileSync } from "child_process";
|
|
63091
|
+
import { existsSync as existsSync23 } from "fs";
|
|
63092
|
+
var GIT_BASH_ENV_KEY = "OMO_CODEX_GIT_BASH_PATH";
|
|
63093
|
+
var SKIP_GIT_BASH_AUTO_INSTALL_ENV_KEY = "OMO_CODEX_SKIP_GIT_BASH_AUTO_INSTALL";
|
|
63094
|
+
var PROGRAM_FILES_GIT_BASH = "C:\\Program Files\\Git\\bin\\bash.exe";
|
|
63095
|
+
var PROGRAM_FILES_X86_GIT_BASH = "C:\\Program Files (x86)\\Git\\bin\\bash.exe";
|
|
63096
|
+
var WINGET_INSTALL_ARGS = ["install", "--id", "Git.Git", "-e", "--source", "winget"];
|
|
63097
|
+
function resolveGitBash(input) {
|
|
63098
|
+
if (input.platform !== "win32")
|
|
63099
|
+
return { found: true, path: null, source: "not-required" };
|
|
63100
|
+
const checkedPaths = [];
|
|
63101
|
+
const envPath = nonEmptyEnvValue(input.env, GIT_BASH_ENV_KEY);
|
|
63102
|
+
if (envPath !== undefined) {
|
|
63103
|
+
checkedPaths.push(envPath);
|
|
63104
|
+
if (isBashExePath(envPath) && input.exists(envPath))
|
|
63105
|
+
return { found: true, path: envPath, source: "env" };
|
|
63106
|
+
return missingGitBash(checkedPaths);
|
|
63107
|
+
}
|
|
63108
|
+
for (const candidate of [
|
|
63109
|
+
{ path: PROGRAM_FILES_GIT_BASH, source: "program-files" },
|
|
63110
|
+
{ path: PROGRAM_FILES_X86_GIT_BASH, source: "program-files-x86" }
|
|
63111
|
+
]) {
|
|
63112
|
+
checkedPaths.push(candidate.path);
|
|
63113
|
+
if (input.exists(candidate.path))
|
|
63114
|
+
return { found: true, path: candidate.path, source: candidate.source };
|
|
63115
|
+
}
|
|
63116
|
+
for (const pathCandidate of input.where("bash")) {
|
|
63117
|
+
const candidate = pathCandidate.trim();
|
|
63118
|
+
if (candidate.length === 0)
|
|
63119
|
+
continue;
|
|
63120
|
+
checkedPaths.push(candidate);
|
|
63121
|
+
if (isBashExePath(candidate) && input.exists(candidate))
|
|
63122
|
+
return { found: true, path: candidate, source: "path" };
|
|
63123
|
+
}
|
|
63124
|
+
return missingGitBash(checkedPaths);
|
|
63125
|
+
}
|
|
63126
|
+
function resolveGitBashForCurrentProcess(input = {}) {
|
|
63127
|
+
return resolveGitBash({
|
|
63128
|
+
platform: input.platform ?? process.platform,
|
|
63129
|
+
env: input.env ?? process.env,
|
|
63130
|
+
exists: existsSync23,
|
|
63131
|
+
where: whereCommand
|
|
63132
|
+
});
|
|
63133
|
+
}
|
|
63134
|
+
async function prepareGitBashForInstall(input) {
|
|
63135
|
+
const resolve8 = input.resolveGitBash ?? (() => resolveGitBashForCurrentProcess({ platform: input.platform, env: input.env }));
|
|
63136
|
+
const initialResolution = resolve8();
|
|
63137
|
+
if (input.platform !== "win32" || initialResolution.found)
|
|
63138
|
+
return initialResolution;
|
|
63139
|
+
if (input.env[SKIP_GIT_BASH_AUTO_INSTALL_ENV_KEY] === "1")
|
|
63140
|
+
return initialResolution;
|
|
63141
|
+
try {
|
|
63142
|
+
await input.runCommand("winget", WINGET_INSTALL_ARGS, { cwd: input.cwd });
|
|
63143
|
+
} catch (error) {
|
|
63144
|
+
if (!(error instanceof Error))
|
|
63145
|
+
throw error;
|
|
63146
|
+
return initialResolution;
|
|
63147
|
+
}
|
|
63148
|
+
return resolve8();
|
|
63149
|
+
}
|
|
63150
|
+
function missingGitBash(checkedPaths) {
|
|
63151
|
+
return {
|
|
63152
|
+
found: false,
|
|
63153
|
+
checkedPaths,
|
|
63154
|
+
installHint: [
|
|
63155
|
+
"Git Bash is required for native Windows Codex profile installs.",
|
|
63156
|
+
"Install it with: winget install --id Git.Git -e --source winget",
|
|
63157
|
+
`For a custom install, set ${GIT_BASH_ENV_KEY}=C:\\path\\to\\bash.exe`,
|
|
63158
|
+
"Then rerun `npx lazycodex-ai install`."
|
|
63159
|
+
].join(`
|
|
63160
|
+
`)
|
|
63161
|
+
};
|
|
63162
|
+
}
|
|
63163
|
+
function nonEmptyEnvValue(env, key) {
|
|
63164
|
+
const value = env[key];
|
|
63165
|
+
if (value === undefined)
|
|
63166
|
+
return;
|
|
63167
|
+
const trimmed = value.trim();
|
|
63168
|
+
return trimmed.length === 0 ? undefined : trimmed;
|
|
63169
|
+
}
|
|
63170
|
+
function isBashExePath(path6) {
|
|
63171
|
+
return path6.toLowerCase().endsWith("bash.exe");
|
|
63172
|
+
}
|
|
63173
|
+
function whereCommand(command) {
|
|
63174
|
+
try {
|
|
63175
|
+
return execFileSync("where", [command], { encoding: "utf8" }).split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
63176
|
+
} catch (error) {
|
|
63177
|
+
if (error instanceof Error)
|
|
63178
|
+
return [];
|
|
63179
|
+
throw error;
|
|
63180
|
+
}
|
|
63181
|
+
}
|
|
63182
|
+
|
|
62629
63183
|
// src/cli/install-codex/link-cached-plugin-agents.ts
|
|
62630
63184
|
import { copyFile, lstat as lstat3, mkdir as mkdir4, readdir as readdir3, rm as rm3, symlink as symlink2, writeFile as writeFile4 } from "fs/promises";
|
|
62631
|
-
import { basename as basename6, join as
|
|
63185
|
+
import { basename as basename6, join as join26 } from "path";
|
|
62632
63186
|
var MANIFEST_FILE = ".installed-agents.json";
|
|
62633
63187
|
async function linkCachedPluginAgents(input) {
|
|
62634
63188
|
const platform = input.platform ?? process.platform;
|
|
@@ -62637,11 +63191,11 @@ async function linkCachedPluginAgents(input) {
|
|
|
62637
63191
|
await writeManifest(input.pluginRoot, []);
|
|
62638
63192
|
return [];
|
|
62639
63193
|
}
|
|
62640
|
-
const agentsDir =
|
|
63194
|
+
const agentsDir = join26(input.codexHome, "agents");
|
|
62641
63195
|
await mkdir4(agentsDir, { recursive: true });
|
|
62642
63196
|
const linked = [];
|
|
62643
63197
|
for (const agentPath of bundledAgents) {
|
|
62644
|
-
const linkPath =
|
|
63198
|
+
const linkPath = join26(agentsDir, basename6(agentPath));
|
|
62645
63199
|
if (platform === "win32") {
|
|
62646
63200
|
await replaceWithCopy(linkPath, agentPath);
|
|
62647
63201
|
} else {
|
|
@@ -62653,7 +63207,7 @@ async function linkCachedPluginAgents(input) {
|
|
|
62653
63207
|
return linked;
|
|
62654
63208
|
}
|
|
62655
63209
|
async function discoverBundledAgents(pluginRoot) {
|
|
62656
|
-
const componentsRoot =
|
|
63210
|
+
const componentsRoot = join26(pluginRoot, "components");
|
|
62657
63211
|
if (!await exists4(componentsRoot))
|
|
62658
63212
|
return [];
|
|
62659
63213
|
const componentEntries = await readdir3(componentsRoot, { withFileTypes: true });
|
|
@@ -62661,14 +63215,14 @@ async function discoverBundledAgents(pluginRoot) {
|
|
|
62661
63215
|
for (const entry of componentEntries) {
|
|
62662
63216
|
if (!entry.isDirectory())
|
|
62663
63217
|
continue;
|
|
62664
|
-
const agentsRoot =
|
|
63218
|
+
const agentsRoot = join26(componentsRoot, entry.name, "agents");
|
|
62665
63219
|
if (!await exists4(agentsRoot))
|
|
62666
63220
|
continue;
|
|
62667
63221
|
const agentEntries = await readdir3(agentsRoot, { withFileTypes: true });
|
|
62668
63222
|
for (const file of agentEntries) {
|
|
62669
63223
|
if (!file.isFile() || !file.name.endsWith(".toml"))
|
|
62670
63224
|
continue;
|
|
62671
|
-
agents.push(
|
|
63225
|
+
agents.push(join26(agentsRoot, file.name));
|
|
62672
63226
|
}
|
|
62673
63227
|
}
|
|
62674
63228
|
agents.sort();
|
|
@@ -62692,7 +63246,7 @@ async function prepareReplacement(linkPath) {
|
|
|
62692
63246
|
await rm3(linkPath, { force: true });
|
|
62693
63247
|
}
|
|
62694
63248
|
async function writeManifest(pluginRoot, agentPaths) {
|
|
62695
|
-
const manifestPath =
|
|
63249
|
+
const manifestPath = join26(pluginRoot, MANIFEST_FILE);
|
|
62696
63250
|
const payload = { agents: [...agentPaths].sort() };
|
|
62697
63251
|
await writeFile4(manifestPath, `${JSON.stringify(payload, null, "\t")}
|
|
62698
63252
|
`);
|
|
@@ -62707,14 +63261,14 @@ async function exists4(path6) {
|
|
|
62707
63261
|
}
|
|
62708
63262
|
|
|
62709
63263
|
// src/cli/install-codex/codex-marketplace.ts
|
|
62710
|
-
import { readFile as
|
|
62711
|
-
import { join as
|
|
63264
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
63265
|
+
import { join as join27 } from "path";
|
|
62712
63266
|
var DEFAULT_MARKETPLACE_PATH = "packages/omo-codex/marketplace.json";
|
|
62713
63267
|
async function readMarketplace(repoRoot, options) {
|
|
62714
|
-
const marketplacePath = options?.marketplacePath ??
|
|
62715
|
-
const raw = await
|
|
63268
|
+
const marketplacePath = options?.marketplacePath ?? join27(repoRoot, DEFAULT_MARKETPLACE_PATH);
|
|
63269
|
+
const raw = await readFile9(marketplacePath, "utf8");
|
|
62716
63270
|
const parsed = JSON.parse(raw);
|
|
62717
|
-
if (!
|
|
63271
|
+
if (!isRecord14(parsed))
|
|
62718
63272
|
throw new Error("marketplace.json must be an object");
|
|
62719
63273
|
if (typeof parsed.name !== "string" || parsed.name.trim() === "") {
|
|
62720
63274
|
throw new Error("marketplace.json name must be a non-empty string");
|
|
@@ -62730,12 +63284,12 @@ async function readMarketplace(repoRoot, options) {
|
|
|
62730
63284
|
function resolvePluginSource(repoRoot, plugin, options) {
|
|
62731
63285
|
const sourcePath = localSourcePath(options?.pathOverride ?? plugin.source);
|
|
62732
63286
|
const relativePath = sourcePath.slice(2);
|
|
62733
|
-
return
|
|
63287
|
+
return join27(repoRoot, ...relativePath.split(/[\\/]/));
|
|
62734
63288
|
}
|
|
62735
63289
|
async function readPluginManifest(pluginRoot) {
|
|
62736
|
-
const raw = await
|
|
63290
|
+
const raw = await readFile9(join27(pluginRoot, ".codex-plugin", "plugin.json"), "utf8");
|
|
62737
63291
|
const parsed = JSON.parse(raw);
|
|
62738
|
-
if (!
|
|
63292
|
+
if (!isRecord14(parsed))
|
|
62739
63293
|
throw new Error(`${pluginRoot} plugin.json must be an object`);
|
|
62740
63294
|
if (typeof parsed.name !== "string" || parsed.name.trim() === "") {
|
|
62741
63295
|
throw new Error(`${pluginRoot} plugin.json name must be a non-empty string`);
|
|
@@ -62761,7 +63315,7 @@ function validatePathSegment(value, label) {
|
|
|
62761
63315
|
}
|
|
62762
63316
|
}
|
|
62763
63317
|
function normalizeMarketplacePlugin(plugin, index) {
|
|
62764
|
-
if (!
|
|
63318
|
+
if (!isRecord14(plugin))
|
|
62765
63319
|
throw new Error(`marketplace plugin ${index} must be an object`);
|
|
62766
63320
|
if (typeof plugin.name !== "string" || plugin.name.trim() === "") {
|
|
62767
63321
|
throw new Error(`marketplace plugin ${index} name must be a non-empty string`);
|
|
@@ -62773,7 +63327,7 @@ function normalizeMarketplacePlugin(plugin, index) {
|
|
|
62773
63327
|
}
|
|
62774
63328
|
return { name: plugin.name, source: plugin.source };
|
|
62775
63329
|
}
|
|
62776
|
-
if (
|
|
63330
|
+
if (isRecord14(plugin.source) && plugin.source.source === "local" && typeof plugin.source.path === "string") {
|
|
62777
63331
|
validateLocalSourcePath(plugin.source.path);
|
|
62778
63332
|
const local = { source: "local", path: plugin.source.path };
|
|
62779
63333
|
return { name: plugin.name, source: local };
|
|
@@ -62800,13 +63354,13 @@ function validateLocalSourcePath(path6) {
|
|
|
62800
63354
|
}
|
|
62801
63355
|
return path6;
|
|
62802
63356
|
}
|
|
62803
|
-
function
|
|
63357
|
+
function isRecord14(value) {
|
|
62804
63358
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
62805
63359
|
}
|
|
62806
63360
|
|
|
62807
63361
|
// src/cli/install-codex/codex-marketplace-snapshot.ts
|
|
62808
63362
|
import { cp as cp3, mkdir as mkdir5, rename as rename2, rm as rm4, writeFile as writeFile5 } from "fs/promises";
|
|
62809
|
-
import { join as
|
|
63363
|
+
import { join as join28, sep as sep2 } from "path";
|
|
62810
63364
|
var INSTALLED_MARKETPLACES_DIR = ".tmp/marketplaces";
|
|
62811
63365
|
async function writeInstalledMarketplaceSnapshot(input) {
|
|
62812
63366
|
const marketplaceRoot = installedMarketplaceRoot(input.codexHome, input.marketplace.name);
|
|
@@ -62819,21 +63373,21 @@ async function writeInstalledMarketplaceSnapshot(input) {
|
|
|
62819
63373
|
return snapshotPlugins;
|
|
62820
63374
|
}
|
|
62821
63375
|
function installedMarketplaceRoot(codexHome, marketplaceName) {
|
|
62822
|
-
return
|
|
63376
|
+
return join28(codexHome, INSTALLED_MARKETPLACES_DIR, marketplaceName);
|
|
62823
63377
|
}
|
|
62824
63378
|
async function writeMarketplaceManifest(marketplaceRoot, marketplace) {
|
|
62825
|
-
const manifestDir =
|
|
63379
|
+
const manifestDir = join28(marketplaceRoot, ".agents", "plugins");
|
|
62826
63380
|
await mkdir5(manifestDir, { recursive: true });
|
|
62827
|
-
const tempPath =
|
|
63381
|
+
const tempPath = join28(manifestDir, `.marketplace-${process.pid}-${Date.now()}.json.tmp`);
|
|
62828
63382
|
await writeFile5(tempPath, `${JSON.stringify(marketplace, null, "\t")}
|
|
62829
63383
|
`);
|
|
62830
|
-
await rename2(tempPath,
|
|
63384
|
+
await rename2(tempPath, join28(manifestDir, "marketplace.json"));
|
|
62831
63385
|
}
|
|
62832
63386
|
async function writeSnapshotPlugin(marketplaceRoot, plugin) {
|
|
62833
|
-
const pluginsDir =
|
|
63387
|
+
const pluginsDir = join28(marketplaceRoot, "plugins");
|
|
62834
63388
|
await mkdir5(pluginsDir, { recursive: true });
|
|
62835
|
-
const targetPath =
|
|
62836
|
-
const tempPath =
|
|
63389
|
+
const targetPath = join28(pluginsDir, plugin.name);
|
|
63390
|
+
const tempPath = join28(pluginsDir, `.tmp-${plugin.name}-${process.pid}-${Date.now()}`);
|
|
62837
63391
|
await rm4(tempPath, { recursive: true, force: true });
|
|
62838
63392
|
await cp3(plugin.sourcePath, tempPath, {
|
|
62839
63393
|
recursive: true,
|
|
@@ -62871,19 +63425,260 @@ var defaultRunCommand = async (command, args, options) => {
|
|
|
62871
63425
|
}
|
|
62872
63426
|
};
|
|
62873
63427
|
|
|
63428
|
+
// src/cli/install-codex/codex-project-local-cleanup.ts
|
|
63429
|
+
import { copyFile as copyFile2, lstat as lstat4, readFile as readFile10, writeFile as writeFile6 } from "fs/promises";
|
|
63430
|
+
import { dirname as dirname13, join as join29, resolve as resolve8 } from "path";
|
|
63431
|
+
var LEGACY_AGENT_CONFLICT_KEYS = ["max_threads"];
|
|
63432
|
+
var PROJECT_LOCAL_ARTIFACT_PATHS = [
|
|
63433
|
+
".omx",
|
|
63434
|
+
".codex/hooks.json",
|
|
63435
|
+
".codex/agents",
|
|
63436
|
+
".codex/prompts",
|
|
63437
|
+
".codex/skills"
|
|
63438
|
+
];
|
|
63439
|
+
async function repairNearestProjectLocalCodexArtifacts(input) {
|
|
63440
|
+
const project = await findProjectLocalCodexConfigs(input.startDirectory, input.codexHome);
|
|
63441
|
+
if (project === null) {
|
|
63442
|
+
return emptyProjectLocalCodexCleanupResult();
|
|
63443
|
+
}
|
|
63444
|
+
const artifacts = await collectProjectLocalArtifacts(project.artifactRoots);
|
|
63445
|
+
const configs = [];
|
|
63446
|
+
for (const configPath of project.configPaths) {
|
|
63447
|
+
const original = await readFile10(configPath, "utf8");
|
|
63448
|
+
const repair = repairProjectLocalCodexConfigText(original);
|
|
63449
|
+
if (!repair.changed) {
|
|
63450
|
+
configs.push({
|
|
63451
|
+
projectRoot: project.projectRoot,
|
|
63452
|
+
configPath,
|
|
63453
|
+
changed: false,
|
|
63454
|
+
removedKeys: repair.removedKeys
|
|
63455
|
+
});
|
|
63456
|
+
continue;
|
|
63457
|
+
}
|
|
63458
|
+
const backupPath = `${configPath}.backup-${formatBackupTimestamp(input.now?.() ?? new Date)}`;
|
|
63459
|
+
await copyFile2(configPath, backupPath);
|
|
63460
|
+
await writeFile6(configPath, `${repair.config.trimEnd()}
|
|
63461
|
+
`);
|
|
63462
|
+
configs.push({
|
|
63463
|
+
projectRoot: project.projectRoot,
|
|
63464
|
+
configPath,
|
|
63465
|
+
changed: true,
|
|
63466
|
+
removedKeys: repair.removedKeys,
|
|
63467
|
+
backupPath
|
|
63468
|
+
});
|
|
63469
|
+
}
|
|
63470
|
+
const changedConfigs = configs.filter((config) => config.changed);
|
|
63471
|
+
const nearestChangedConfig = lastValue(changedConfigs);
|
|
63472
|
+
const nearestConfig = lastValue(configs);
|
|
63473
|
+
return {
|
|
63474
|
+
projectRoot: project.projectRoot,
|
|
63475
|
+
configPath: nearestChangedConfig?.configPath ?? nearestConfig?.configPath ?? null,
|
|
63476
|
+
changed: changedConfigs.length > 0,
|
|
63477
|
+
removedKeys: uniqueRemovedKeys(changedConfigs),
|
|
63478
|
+
backupPath: nearestChangedConfig?.backupPath,
|
|
63479
|
+
configs,
|
|
63480
|
+
artifacts
|
|
63481
|
+
};
|
|
63482
|
+
}
|
|
63483
|
+
function emptyProjectLocalCodexCleanupResult() {
|
|
63484
|
+
return {
|
|
63485
|
+
projectRoot: null,
|
|
63486
|
+
configPath: null,
|
|
63487
|
+
changed: false,
|
|
63488
|
+
removedKeys: [],
|
|
63489
|
+
configs: [],
|
|
63490
|
+
artifacts: []
|
|
63491
|
+
};
|
|
63492
|
+
}
|
|
63493
|
+
function uniqueRemovedKeys(configs) {
|
|
63494
|
+
const keys = [];
|
|
63495
|
+
for (const config of configs) {
|
|
63496
|
+
for (const key of config.removedKeys) {
|
|
63497
|
+
if (!keys.includes(key))
|
|
63498
|
+
keys.push(key);
|
|
63499
|
+
}
|
|
63500
|
+
}
|
|
63501
|
+
return keys;
|
|
63502
|
+
}
|
|
63503
|
+
function lastValue(values) {
|
|
63504
|
+
return values.length > 0 ? values[values.length - 1] ?? null : null;
|
|
63505
|
+
}
|
|
63506
|
+
function repairProjectLocalCodexConfigText(config) {
|
|
63507
|
+
if (!isMultiAgentV2Enabled(config))
|
|
63508
|
+
return { config, changed: false, removedKeys: [] };
|
|
63509
|
+
let nextConfig = config;
|
|
63510
|
+
const removedKeys = [];
|
|
63511
|
+
for (const key of LEGACY_AGENT_CONFLICT_KEYS) {
|
|
63512
|
+
const section = findTomlSection2(nextConfig, "agents");
|
|
63513
|
+
if (section === null || !hasSetting(section.text, key))
|
|
63514
|
+
continue;
|
|
63515
|
+
nextConfig = removeSetting2(nextConfig, section, key);
|
|
63516
|
+
removedKeys.push(key);
|
|
63517
|
+
}
|
|
63518
|
+
return {
|
|
63519
|
+
config: nextConfig,
|
|
63520
|
+
changed: removedKeys.length > 0,
|
|
63521
|
+
removedKeys
|
|
63522
|
+
};
|
|
63523
|
+
}
|
|
63524
|
+
async function findProjectLocalCodexConfigs(startDirectory, codexHome) {
|
|
63525
|
+
if (startDirectory.includes("\x00"))
|
|
63526
|
+
return null;
|
|
63527
|
+
const startDirectoryStat = await maybeLstat(startDirectory);
|
|
63528
|
+
if (startDirectoryStat !== null && !startDirectoryStat.isDirectory()) {
|
|
63529
|
+
throw new ProjectLocalCleanupStartDirectoryError(startDirectory);
|
|
63530
|
+
}
|
|
63531
|
+
const codexHomeConfigPath = codexHome === undefined ? null : join29(resolve8(codexHome), "config.toml");
|
|
63532
|
+
let current = resolve8(startDirectory);
|
|
63533
|
+
const configPathsFromCwd = [];
|
|
63534
|
+
while (true) {
|
|
63535
|
+
const configPath = join29(current, ".codex", "config.toml");
|
|
63536
|
+
if (await isRegularProjectLocalConfig(current, configPath)) {
|
|
63537
|
+
if (codexHomeConfigPath === null || resolve8(configPath) !== codexHomeConfigPath) {
|
|
63538
|
+
configPathsFromCwd.push(configPath);
|
|
63539
|
+
}
|
|
63540
|
+
}
|
|
63541
|
+
if (await exists5(join29(current, ".git"))) {
|
|
63542
|
+
return configPathsFromCwd.length === 0 ? null : {
|
|
63543
|
+
projectRoot: current,
|
|
63544
|
+
configPaths: [...configPathsFromCwd].reverse(),
|
|
63545
|
+
artifactRoots: artifactRootsForConfigPaths(configPathsFromCwd)
|
|
63546
|
+
};
|
|
63547
|
+
}
|
|
63548
|
+
const parent = dirname13(current);
|
|
63549
|
+
if (parent === current) {
|
|
63550
|
+
const nearestConfigPath = configPathsFromCwd[0];
|
|
63551
|
+
return nearestConfigPath === undefined ? null : {
|
|
63552
|
+
projectRoot: dirname13(dirname13(nearestConfigPath)),
|
|
63553
|
+
configPaths: [nearestConfigPath],
|
|
63554
|
+
artifactRoots: [dirname13(dirname13(nearestConfigPath))]
|
|
63555
|
+
};
|
|
63556
|
+
}
|
|
63557
|
+
current = parent;
|
|
63558
|
+
}
|
|
63559
|
+
}
|
|
63560
|
+
async function isRegularProjectLocalConfig(directory, configPath) {
|
|
63561
|
+
const codexDirStat = await maybeLstat(join29(directory, ".codex"));
|
|
63562
|
+
if (codexDirStat === null || !codexDirStat.isDirectory() || codexDirStat.isSymbolicLink())
|
|
63563
|
+
return false;
|
|
63564
|
+
const configStat = await maybeLstat(configPath);
|
|
63565
|
+
return configStat !== null && configStat.isFile() && !configStat.isSymbolicLink();
|
|
63566
|
+
}
|
|
63567
|
+
function artifactRootsForConfigPaths(configPaths) {
|
|
63568
|
+
const roots = [];
|
|
63569
|
+
for (const configPath of configPaths) {
|
|
63570
|
+
const root = dirname13(dirname13(configPath));
|
|
63571
|
+
if (!roots.includes(root))
|
|
63572
|
+
roots.push(root);
|
|
63573
|
+
}
|
|
63574
|
+
return roots.reverse();
|
|
63575
|
+
}
|
|
63576
|
+
async function collectProjectLocalArtifacts(projectRoots) {
|
|
63577
|
+
const artifacts = [];
|
|
63578
|
+
const seenPaths = new Set;
|
|
63579
|
+
for (const projectRoot of projectRoots) {
|
|
63580
|
+
for (const relativePath of PROJECT_LOCAL_ARTIFACT_PATHS) {
|
|
63581
|
+
const artifactPath = join29(projectRoot, relativePath);
|
|
63582
|
+
if (seenPaths.has(artifactPath))
|
|
63583
|
+
continue;
|
|
63584
|
+
const entryStat = await maybeLstat(artifactPath);
|
|
63585
|
+
if (entryStat === null)
|
|
63586
|
+
continue;
|
|
63587
|
+
seenPaths.add(artifactPath);
|
|
63588
|
+
artifacts.push({
|
|
63589
|
+
relativePath,
|
|
63590
|
+
path: artifactPath,
|
|
63591
|
+
kind: entryStat.isDirectory() ? "directory" : entryStat.isFile() ? "file" : "other"
|
|
63592
|
+
});
|
|
63593
|
+
}
|
|
63594
|
+
}
|
|
63595
|
+
return artifacts;
|
|
63596
|
+
}
|
|
63597
|
+
function isMultiAgentV2Enabled(config) {
|
|
63598
|
+
const featuresSection = findTomlSection2(config, "features");
|
|
63599
|
+
if (featuresSection !== null && settingIsBooleanTrue(featuresSection.text, "multi_agent_v2"))
|
|
63600
|
+
return true;
|
|
63601
|
+
const multiAgentSection = findTomlSection2(config, "features.multi_agent_v2");
|
|
63602
|
+
return multiAgentSection !== null && settingIsBooleanTrue(multiAgentSection.text, "enabled");
|
|
63603
|
+
}
|
|
63604
|
+
function settingIsBooleanTrue(sectionText, key) {
|
|
63605
|
+
return new RegExp(`^\\s*${escapeRegExp2(key)}\\s*=\\s*true\\s*(?:#.*)?$`, "m").test(sectionText);
|
|
63606
|
+
}
|
|
63607
|
+
function hasSetting(sectionText, key) {
|
|
63608
|
+
return new RegExp(`^\\s*${escapeRegExp2(key)}\\s*=`, "m").test(sectionText);
|
|
63609
|
+
}
|
|
63610
|
+
function formatBackupTimestamp(date) {
|
|
63611
|
+
return date.toISOString().replace(/[:.]/g, "-");
|
|
63612
|
+
}
|
|
63613
|
+
async function maybeLstat(path6) {
|
|
63614
|
+
try {
|
|
63615
|
+
return await lstat4(path6);
|
|
63616
|
+
} catch (error) {
|
|
63617
|
+
if (nodeErrorCode(error) === "ENOENT")
|
|
63618
|
+
return null;
|
|
63619
|
+
throw error;
|
|
63620
|
+
}
|
|
63621
|
+
}
|
|
63622
|
+
async function exists5(path6) {
|
|
63623
|
+
return await maybeLstat(path6) !== null;
|
|
63624
|
+
}
|
|
63625
|
+
function nodeErrorCode(error) {
|
|
63626
|
+
if (!(error instanceof Error) || !("code" in error))
|
|
63627
|
+
return null;
|
|
63628
|
+
return typeof error.code === "string" ? error.code : null;
|
|
63629
|
+
}
|
|
63630
|
+
|
|
63631
|
+
class ProjectLocalCleanupStartDirectoryError extends Error {
|
|
63632
|
+
constructor(startDirectory) {
|
|
63633
|
+
super(`Project-local Codex cleanup start path is not a directory: ${startDirectory}`);
|
|
63634
|
+
this.name = "ProjectLocalCleanupStartDirectoryError";
|
|
63635
|
+
}
|
|
63636
|
+
}
|
|
63637
|
+
|
|
63638
|
+
// src/cli/install-codex/codex-project-local-cleanup-best-effort.ts
|
|
63639
|
+
async function repairProjectLocalCodexArtifactsBestEffort(input) {
|
|
63640
|
+
try {
|
|
63641
|
+
return await repairNearestProjectLocalCodexArtifacts({
|
|
63642
|
+
startDirectory: input.startDirectory,
|
|
63643
|
+
codexHome: input.codexHome,
|
|
63644
|
+
now: input.now
|
|
63645
|
+
});
|
|
63646
|
+
} catch (error) {
|
|
63647
|
+
input.log(`Skipped project-local Codex cleanup: ${formatUnknownError(error)}`);
|
|
63648
|
+
return emptyProjectLocalCodexCleanupResult();
|
|
63649
|
+
}
|
|
63650
|
+
}
|
|
63651
|
+
function formatUnknownError(error) {
|
|
63652
|
+
return error instanceof Error ? error.message : String(error);
|
|
63653
|
+
}
|
|
63654
|
+
|
|
62874
63655
|
// src/cli/install-codex/install-codex.ts
|
|
62875
63656
|
var SISYPHUS_LEGACY_CACHE_MARKETPLACES = ["lazycodex", "code-yeongyu-codex-plugins"];
|
|
62876
63657
|
async function runCodexInstaller(options = {}) {
|
|
62877
|
-
const
|
|
62878
|
-
const
|
|
62879
|
-
const
|
|
63658
|
+
const env = options.env ?? process.env;
|
|
63659
|
+
const platform = options.platform ?? process.platform;
|
|
63660
|
+
const repoRoot = resolve9(options.repoRoot ?? findRepoRoot({ importerDir: import.meta.dir, env }));
|
|
63661
|
+
const codexHome = resolve9(options.codexHome ?? env.CODEX_HOME ?? join31(homedir5(), ".codex"));
|
|
63662
|
+
const projectDirectory = resolve9(options.projectDirectory ?? env.OMO_CODEX_PROJECT ?? process.cwd());
|
|
63663
|
+
const binDir = resolveCodexInstallerBinDir({ binDir: options.binDir, codexHome, env });
|
|
62880
63664
|
const runCommand = options.runCommand ?? defaultRunCommand;
|
|
62881
63665
|
const log2 = options.log ?? (() => {
|
|
62882
63666
|
return;
|
|
62883
63667
|
});
|
|
62884
|
-
const
|
|
63668
|
+
const buildSource = await shouldBuildSourcePackages(repoRoot);
|
|
63669
|
+
const gitBashResolution = await prepareGitBashForInstall({
|
|
63670
|
+
platform,
|
|
63671
|
+
env,
|
|
63672
|
+
cwd: repoRoot,
|
|
63673
|
+
runCommand,
|
|
63674
|
+
resolveGitBash: platform === "win32" ? options.gitBashResolver ?? (() => resolveGitBashForCurrentProcess({ platform, env })) : undefined
|
|
63675
|
+
});
|
|
63676
|
+
if (!gitBashResolution.found) {
|
|
63677
|
+
throw new Error(gitBashResolution.installHint);
|
|
63678
|
+
}
|
|
63679
|
+
const codexPackageRoot = join31(repoRoot, "packages", "omo-codex");
|
|
62885
63680
|
const marketplace = await readMarketplace(repoRoot, {
|
|
62886
|
-
marketplacePath:
|
|
63681
|
+
marketplacePath: join31(codexPackageRoot, "marketplace.json")
|
|
62887
63682
|
});
|
|
62888
63683
|
const installed = [];
|
|
62889
63684
|
const pluginSources = [];
|
|
@@ -62898,6 +63693,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
62898
63693
|
validatePathSegment(version2, "plugin version");
|
|
62899
63694
|
log2(`Building ${entry.name}@${version2}`);
|
|
62900
63695
|
const plugin = await installCachedPlugin({
|
|
63696
|
+
buildSource,
|
|
62901
63697
|
codexHome,
|
|
62902
63698
|
marketplaceName: marketplace.name,
|
|
62903
63699
|
name: entry.name,
|
|
@@ -62905,7 +63701,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
62905
63701
|
sourcePath,
|
|
62906
63702
|
version: version2
|
|
62907
63703
|
});
|
|
62908
|
-
const links = await linkCachedPluginBins({ binDir, pluginRoot: plugin.path });
|
|
63704
|
+
const links = await linkCachedPluginBins({ binDir, pluginRoot: plugin.path, platform });
|
|
62909
63705
|
for (const link of links) {
|
|
62910
63706
|
log2(`Linked ${link.name} -> ${link.target}`);
|
|
62911
63707
|
}
|
|
@@ -62920,7 +63716,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
62920
63716
|
});
|
|
62921
63717
|
for (const plugin of installed) {
|
|
62922
63718
|
const pluginRoot = agentSourceRoots.get(plugin.name) ?? plugin.path;
|
|
62923
|
-
const agentLinks = await linkCachedPluginAgents({ codexHome, pluginRoot });
|
|
63719
|
+
const agentLinks = await linkCachedPluginAgents({ codexHome, pluginRoot, platform });
|
|
62924
63720
|
for (const link of agentLinks) {
|
|
62925
63721
|
log2(`Linked agent ${link.name} -> ${link.target}`);
|
|
62926
63722
|
const agentName = agentNameFromToml(link.name);
|
|
@@ -62944,41 +63740,57 @@ async function runCodexInstaller(options = {}) {
|
|
|
62944
63740
|
pluginNames: marketplace.plugins.map((plugin) => plugin.name)
|
|
62945
63741
|
});
|
|
62946
63742
|
}
|
|
62947
|
-
const marketplaceRoot =
|
|
63743
|
+
const marketplaceRoot = join31(codexHome, "plugins", "cache", marketplace.name);
|
|
62948
63744
|
await writeCachedMarketplaceManifest({
|
|
62949
63745
|
marketplaceName: marketplace.name,
|
|
62950
63746
|
marketplaceRoot,
|
|
62951
63747
|
plugins: installed
|
|
62952
63748
|
});
|
|
62953
|
-
const configPath =
|
|
63749
|
+
const configPath = join31(codexHome, "config.toml");
|
|
62954
63750
|
await updateCodexConfig({
|
|
62955
63751
|
configPath,
|
|
62956
63752
|
repoRoot: codexPackageRoot,
|
|
62957
63753
|
marketplaceName: marketplace.name,
|
|
62958
63754
|
marketplaceSource: codexMarketplaceSource(marketplaceRoot),
|
|
62959
63755
|
pluginNames: marketplace.plugins.map((plugin) => plugin.name),
|
|
63756
|
+
platform,
|
|
62960
63757
|
trustedHookStates,
|
|
62961
63758
|
agentConfigs: [...agentConfigs.values()].sort((left, right) => left.name.localeCompare(right.name)),
|
|
62962
|
-
autonomousPermissions: options.autonomousPermissions
|
|
63759
|
+
autonomousPermissions: options.autonomousPermissions !== false
|
|
63760
|
+
});
|
|
63761
|
+
const projectCleanup = await repairProjectLocalCodexArtifactsBestEffort({
|
|
63762
|
+
startDirectory: projectDirectory,
|
|
63763
|
+
codexHome,
|
|
63764
|
+
log: log2
|
|
62963
63765
|
});
|
|
63766
|
+
for (const configCleanup of projectCleanup.configs) {
|
|
63767
|
+
if (!configCleanup.changed)
|
|
63768
|
+
continue;
|
|
63769
|
+
log2(`Repaired project Codex config ${configCleanup.configPath} (backup: ${configCleanup.backupPath})`);
|
|
63770
|
+
}
|
|
63771
|
+
for (const artifact of projectCleanup.artifacts) {
|
|
63772
|
+
log2(`Found project-local legacy artifact ${artifact.path}; left in place`);
|
|
63773
|
+
}
|
|
62964
63774
|
await trackCodexInstallTelemetry();
|
|
62965
63775
|
return {
|
|
62966
63776
|
marketplaceName: marketplace.name,
|
|
62967
63777
|
installed,
|
|
62968
63778
|
configPath,
|
|
62969
|
-
codexHome
|
|
63779
|
+
codexHome,
|
|
63780
|
+
gitBashPath: gitBashResolution.path,
|
|
63781
|
+
projectCleanup
|
|
62970
63782
|
};
|
|
62971
63783
|
}
|
|
62972
63784
|
function resolveCodexInstallerBinDir(input) {
|
|
62973
63785
|
const explicitBinDir = input.binDir ?? input.env?.CODEX_LOCAL_BIN_DIR;
|
|
62974
63786
|
if (explicitBinDir !== undefined && explicitBinDir.trim().length > 0)
|
|
62975
|
-
return
|
|
63787
|
+
return resolve9(explicitBinDir);
|
|
62976
63788
|
const homeDir = input.homeDir ?? homedir5();
|
|
62977
|
-
const defaultCodexHome =
|
|
62978
|
-
const resolvedCodexHome =
|
|
63789
|
+
const defaultCodexHome = resolve9(homeDir, ".codex");
|
|
63790
|
+
const resolvedCodexHome = resolve9(input.codexHome);
|
|
62979
63791
|
if (resolvedCodexHome !== defaultCodexHome)
|
|
62980
|
-
return
|
|
62981
|
-
return
|
|
63792
|
+
return join31(resolvedCodexHome, "bin");
|
|
63793
|
+
return resolve9(homeDir, ".local", "bin");
|
|
62982
63794
|
}
|
|
62983
63795
|
function agentNameFromToml(fileName) {
|
|
62984
63796
|
return fileName.endsWith(".toml") ? fileName.slice(0, -".toml".length) : fileName;
|
|
@@ -62995,9 +63807,9 @@ async function agentSourceRootsForInstall(input) {
|
|
|
62995
63807
|
return new Map(snapshotPlugins.map((plugin) => [plugin.name, plugin.path]));
|
|
62996
63808
|
}
|
|
62997
63809
|
async function writeCachedMarketplaceManifest(input) {
|
|
62998
|
-
const marketplaceDir =
|
|
63810
|
+
const marketplaceDir = join31(input.marketplaceRoot, ".agents", "plugins");
|
|
62999
63811
|
await mkdir6(marketplaceDir, { recursive: true });
|
|
63000
|
-
await
|
|
63812
|
+
await writeFile7(join31(marketplaceDir, "marketplace.json"), `${JSON.stringify({
|
|
63001
63813
|
name: input.marketplaceName,
|
|
63002
63814
|
plugins: input.plugins.map((plugin) => ({
|
|
63003
63815
|
name: plugin.name,
|
|
@@ -63009,36 +63821,33 @@ async function writeCachedMarketplaceManifest(input) {
|
|
|
63009
63821
|
function legacyCacheMarketplaces(marketplaceName) {
|
|
63010
63822
|
return marketplaceName === "sisyphuslabs" ? SISYPHUS_LEGACY_CACHE_MARKETPLACES : [];
|
|
63011
63823
|
}
|
|
63012
|
-
function codexMarketplaceSource(marketplaceRoot) {
|
|
63013
|
-
return { sourceType: "local", source: marketplaceRoot };
|
|
63014
|
-
}
|
|
63015
63824
|
function findRepoRootFromImporter(importerDir) {
|
|
63016
63825
|
let current = importerDir;
|
|
63017
63826
|
for (let depth = 0;depth <= 5; depth += 1) {
|
|
63018
63827
|
if (isRepoRootWithCodexPlugin(current))
|
|
63019
63828
|
return current;
|
|
63020
|
-
for (const wrapperPackageRoot of [
|
|
63829
|
+
for (const wrapperPackageRoot of [join31(current, "node_modules", "oh-my-openagent"), join31(current, "oh-my-openagent")]) {
|
|
63021
63830
|
if (isRepoRootWithCodexPlugin(wrapperPackageRoot))
|
|
63022
63831
|
return wrapperPackageRoot;
|
|
63023
63832
|
}
|
|
63024
|
-
current =
|
|
63833
|
+
current = resolve9(current, "..");
|
|
63025
63834
|
}
|
|
63026
63835
|
throw new Error("Unable to locate vendored Codex plugin: expected packages/omo-codex/plugin/.codex-plugin/plugin.json in this package or sibling oh-my-openagent package within 5 parent levels");
|
|
63027
63836
|
}
|
|
63028
63837
|
function findRepoRoot(input) {
|
|
63029
63838
|
const wrapperPackageRoot = input.env?.OMO_WRAPPER_PACKAGE_ROOT;
|
|
63030
63839
|
if (wrapperPackageRoot !== undefined && wrapperPackageRoot.trim().length > 0) {
|
|
63031
|
-
const resolvedWrapperPackageRoot =
|
|
63840
|
+
const resolvedWrapperPackageRoot = resolve9(wrapperPackageRoot);
|
|
63032
63841
|
if (isRepoRootWithCodexPlugin(resolvedWrapperPackageRoot))
|
|
63033
63842
|
return resolvedWrapperPackageRoot;
|
|
63034
63843
|
}
|
|
63035
63844
|
return findRepoRootFromImporter(input.importerDir);
|
|
63036
63845
|
}
|
|
63037
63846
|
function isRepoRootWithCodexPlugin(repoRoot) {
|
|
63038
|
-
return
|
|
63847
|
+
return existsSync25(join31(repoRoot, "packages", "omo-codex", "plugin", ".codex-plugin", "plugin.json"));
|
|
63039
63848
|
}
|
|
63040
|
-
function
|
|
63041
|
-
return
|
|
63849
|
+
function codexMarketplaceSource(marketplaceRoot) {
|
|
63850
|
+
return { sourceType: "local", source: marketplaceRoot };
|
|
63042
63851
|
}
|
|
63043
63852
|
async function trackCodexInstallTelemetry() {
|
|
63044
63853
|
try {
|
|
@@ -63052,13 +63861,507 @@ async function trackCodexInstallTelemetry() {
|
|
|
63052
63861
|
return;
|
|
63053
63862
|
}
|
|
63054
63863
|
}
|
|
63864
|
+
// src/cli/install-codex/codex-installation-detection.ts
|
|
63865
|
+
import { execFile } from "child_process";
|
|
63866
|
+
import { existsSync as existsSync26 } from "fs";
|
|
63867
|
+
import { homedir as homedir6 } from "os";
|
|
63868
|
+
import { join as join33, win32 as win322 } from "path";
|
|
63869
|
+
|
|
63870
|
+
// src/shared/bun-which-shim.ts
|
|
63871
|
+
import { accessSync as accessSync3, constants as constants4 } from "fs";
|
|
63872
|
+
import { delimiter, join as join32 } from "path";
|
|
63873
|
+
var runtime3 = globalThis;
|
|
63874
|
+
var IS_BUN2 = typeof runtime3.Bun !== "undefined";
|
|
63875
|
+
function isUnsafeCommandName(commandName) {
|
|
63876
|
+
if (commandName.includes("/") || commandName.includes("\\"))
|
|
63877
|
+
return true;
|
|
63878
|
+
if (commandName === "." || commandName === ".." || commandName.includes(".."))
|
|
63879
|
+
return true;
|
|
63880
|
+
if (/^[a-zA-Z]:/.test(commandName))
|
|
63881
|
+
return true;
|
|
63882
|
+
if (commandName.includes("\x00"))
|
|
63883
|
+
return true;
|
|
63884
|
+
return false;
|
|
63885
|
+
}
|
|
63886
|
+
function isExecutable(filePath) {
|
|
63887
|
+
try {
|
|
63888
|
+
accessSync3(filePath, constants4.X_OK);
|
|
63889
|
+
return true;
|
|
63890
|
+
} catch {
|
|
63891
|
+
return false;
|
|
63892
|
+
}
|
|
63893
|
+
}
|
|
63894
|
+
function resolvePathValue() {
|
|
63895
|
+
if (process.platform === "win32")
|
|
63896
|
+
return process.env.Path ?? process.env.PATH;
|
|
63897
|
+
return process.env.PATH;
|
|
63898
|
+
}
|
|
63899
|
+
function getWindowsCandidates(commandName) {
|
|
63900
|
+
if (process.platform !== "win32")
|
|
63901
|
+
return [commandName];
|
|
63902
|
+
return [commandName, `${commandName}.exe`, `${commandName}.cmd`, `${commandName}.bat`, `${commandName}.com`];
|
|
63903
|
+
}
|
|
63904
|
+
function bunWhich(commandName) {
|
|
63905
|
+
if (!commandName)
|
|
63906
|
+
return null;
|
|
63907
|
+
if (isUnsafeCommandName(commandName))
|
|
63908
|
+
return null;
|
|
63909
|
+
if (IS_BUN2)
|
|
63910
|
+
return runtime3.Bun?.which(commandName) ?? null;
|
|
63911
|
+
const pathValue = resolvePathValue();
|
|
63912
|
+
if (!pathValue)
|
|
63913
|
+
return null;
|
|
63914
|
+
const pathEntries = pathValue.split(delimiter).filter((pathEntry) => pathEntry.length > 0);
|
|
63915
|
+
if (pathEntries.length === 0)
|
|
63916
|
+
return null;
|
|
63917
|
+
const candidateNames = getWindowsCandidates(commandName);
|
|
63918
|
+
for (const pathEntry of pathEntries) {
|
|
63919
|
+
for (const candidateName of candidateNames) {
|
|
63920
|
+
const candidatePath = join32(pathEntry, candidateName);
|
|
63921
|
+
if (isExecutable(candidatePath))
|
|
63922
|
+
return candidatePath;
|
|
63923
|
+
}
|
|
63924
|
+
}
|
|
63925
|
+
return null;
|
|
63926
|
+
}
|
|
63927
|
+
|
|
63928
|
+
// src/cli/install-codex/codex-installation-detection.ts
|
|
63929
|
+
var CODEX_PATH_CHECK_LABEL = "codex (PATH)";
|
|
63930
|
+
var WINDOWS_START_APPS_ARGS = [
|
|
63931
|
+
"-NoProfile",
|
|
63932
|
+
"-Command",
|
|
63933
|
+
"Get-StartApps -Name 'Codex' | Select-Object -First 1 -ExpandProperty AppID"
|
|
63934
|
+
];
|
|
63935
|
+
async function detectCodexInstallation(input = {}) {
|
|
63936
|
+
const platform = input.platform ?? process.platform;
|
|
63937
|
+
const env = input.env ?? process.env;
|
|
63938
|
+
const homeDir = input.homeDir ?? homedir6();
|
|
63939
|
+
const exists6 = input.exists ?? existsSync26;
|
|
63940
|
+
const which = input.which ?? bunWhich;
|
|
63941
|
+
const checkedPaths = [CODEX_PATH_CHECK_LABEL];
|
|
63942
|
+
const cliPath = nonEmptyValue(which("codex"));
|
|
63943
|
+
if (cliPath !== undefined)
|
|
63944
|
+
return { found: true, source: "cli", path: cliPath };
|
|
63945
|
+
if (platform === "darwin") {
|
|
63946
|
+
return detectMacCodexInstallation({ homeDir, exists: exists6, checkedPaths });
|
|
63947
|
+
}
|
|
63948
|
+
if (platform === "win32") {
|
|
63949
|
+
return detectWindowsCodexInstallation({
|
|
63950
|
+
env,
|
|
63951
|
+
exists: exists6,
|
|
63952
|
+
checkedPaths,
|
|
63953
|
+
runCommand: input.runCommand ?? defaultRunCommand2
|
|
63954
|
+
});
|
|
63955
|
+
}
|
|
63956
|
+
return missingCodexInstallation(checkedPaths, "Install OpenAI Codex CLI and make sure `codex` is on PATH.");
|
|
63957
|
+
}
|
|
63958
|
+
function formatCodexInstallationWarning(detection) {
|
|
63959
|
+
return [
|
|
63960
|
+
"Codex CLI or desktop app was not detected. LazyCodex will still install the Codex plugin, but Codex itself must be installed to use it.",
|
|
63961
|
+
detection.hint,
|
|
63962
|
+
`Checked: ${detection.checkedPaths.join(", ")}`
|
|
63963
|
+
].join(`
|
|
63964
|
+
`);
|
|
63965
|
+
}
|
|
63966
|
+
function detectMacCodexInstallation(input) {
|
|
63967
|
+
for (const appPath of macCodexAppPaths(input.homeDir)) {
|
|
63968
|
+
input.checkedPaths.push(appPath);
|
|
63969
|
+
if (input.exists(appPath))
|
|
63970
|
+
return { found: true, source: "mac-app", path: appPath };
|
|
63971
|
+
}
|
|
63972
|
+
for (const dmgPath of macCodexDmgPaths(input.homeDir)) {
|
|
63973
|
+
input.checkedPaths.push(dmgPath);
|
|
63974
|
+
if (input.exists(dmgPath)) {
|
|
63975
|
+
return missingCodexInstallation(input.checkedPaths, `Open ${dmgPath} to install Codex Desktop, or install OpenAI Codex CLI and make sure \`codex\` is on PATH.`, dmgPath);
|
|
63976
|
+
}
|
|
63977
|
+
}
|
|
63978
|
+
return missingCodexInstallation(input.checkedPaths, "Install OpenAI Codex CLI, or install Codex Desktop for macOS.");
|
|
63979
|
+
}
|
|
63980
|
+
async function detectWindowsCodexInstallation(input) {
|
|
63981
|
+
for (const candidate of windowsCodexCliPaths(input.env)) {
|
|
63982
|
+
input.checkedPaths.push(candidate);
|
|
63983
|
+
if (input.exists(candidate))
|
|
63984
|
+
return { found: true, source: "windows-standard-cli", path: candidate };
|
|
63985
|
+
}
|
|
63986
|
+
input.checkedPaths.push("Windows Start Apps: Codex");
|
|
63987
|
+
const appId = await findWindowsCodexStartApp(input.runCommand);
|
|
63988
|
+
if (appId !== null)
|
|
63989
|
+
return { found: true, source: "windows-start-app", appId };
|
|
63990
|
+
return missingCodexInstallation(input.checkedPaths, "Install OpenAI Codex CLI, or install Codex Desktop from Microsoft Store.");
|
|
63991
|
+
}
|
|
63992
|
+
async function findWindowsCodexStartApp(runCommand) {
|
|
63993
|
+
try {
|
|
63994
|
+
const result = await runCommand("powershell.exe", WINDOWS_START_APPS_ARGS);
|
|
63995
|
+
if (!result.success)
|
|
63996
|
+
return null;
|
|
63997
|
+
return nonEmptyValue(result.stdout.trim()) ?? null;
|
|
63998
|
+
} catch (error) {
|
|
63999
|
+
if (error instanceof Error)
|
|
64000
|
+
return null;
|
|
64001
|
+
throw error;
|
|
64002
|
+
}
|
|
64003
|
+
}
|
|
64004
|
+
function macCodexAppPaths(homeDir) {
|
|
64005
|
+
return ["/Applications/Codex.app", join33(homeDir, "Applications", "Codex.app")];
|
|
64006
|
+
}
|
|
64007
|
+
function macCodexDmgPaths(homeDir) {
|
|
64008
|
+
const downloads = join33(homeDir, "Downloads");
|
|
64009
|
+
return [join33(downloads, "codex.dmg"), join33(downloads, "Codex.dmg")];
|
|
64010
|
+
}
|
|
64011
|
+
function windowsCodexCliPaths(env) {
|
|
64012
|
+
const candidates = [];
|
|
64013
|
+
const explicitInstallDir = nonEmptyValue(env.CODEX_INSTALL_DIR);
|
|
64014
|
+
if (explicitInstallDir !== undefined)
|
|
64015
|
+
candidates.push(win322.join(explicitInstallDir, "codex.exe"));
|
|
64016
|
+
const localAppData = nonEmptyValue(env.LOCALAPPDATA) ?? nonEmptyValue(env.LocalAppData);
|
|
64017
|
+
if (localAppData !== undefined) {
|
|
64018
|
+
candidates.push(win322.join(localAppData, "Programs", "OpenAI", "Codex", "bin", "codex.exe"));
|
|
64019
|
+
}
|
|
64020
|
+
return dedupe(candidates);
|
|
64021
|
+
}
|
|
64022
|
+
function missingCodexInstallation(checkedPaths, hint, downloadedInstallerPath) {
|
|
64023
|
+
if (downloadedInstallerPath !== undefined) {
|
|
64024
|
+
return { found: false, checkedPaths, hint, downloadedInstallerPath };
|
|
64025
|
+
}
|
|
64026
|
+
return { found: false, checkedPaths, hint };
|
|
64027
|
+
}
|
|
64028
|
+
function nonEmptyValue(value) {
|
|
64029
|
+
if (value === null || value === undefined)
|
|
64030
|
+
return;
|
|
64031
|
+
const trimmed = value.trim();
|
|
64032
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
64033
|
+
}
|
|
64034
|
+
function dedupe(values) {
|
|
64035
|
+
const seen = new Set;
|
|
64036
|
+
const deduped = [];
|
|
64037
|
+
for (const value of values) {
|
|
64038
|
+
if (seen.has(value))
|
|
64039
|
+
continue;
|
|
64040
|
+
seen.add(value);
|
|
64041
|
+
deduped.push(value);
|
|
64042
|
+
}
|
|
64043
|
+
return deduped;
|
|
64044
|
+
}
|
|
64045
|
+
function defaultRunCommand2(command, args) {
|
|
64046
|
+
return new Promise((resolve10) => {
|
|
64047
|
+
execFile(command, [...args], { encoding: "utf8", windowsHide: true }, (error, stdout) => {
|
|
64048
|
+
resolve10({ success: error === null, stdout });
|
|
64049
|
+
});
|
|
64050
|
+
});
|
|
64051
|
+
}
|
|
64052
|
+
// src/cli/install-codex/codex-cleanup.ts
|
|
64053
|
+
import { lstat as lstat6, readFile as readFile12, readdir as readdir4, rm as rm5 } from "fs/promises";
|
|
64054
|
+
import { homedir as homedir7 } from "os";
|
|
64055
|
+
import { isAbsolute as isAbsolute6, join as join34, relative as relative5, resolve as resolve10 } from "path";
|
|
64056
|
+
|
|
64057
|
+
// src/cli/install-codex/codex-cleanup-config.ts
|
|
64058
|
+
import { lstat as lstat5, mkdir as mkdir7, readFile as readFile11, writeFile as writeFile8 } from "fs/promises";
|
|
64059
|
+
import { dirname as dirname15 } from "path";
|
|
64060
|
+
var MANAGED_MARKETPLACES = ["sisyphuslabs", "lazycodex", "code-yeongyu-codex-plugins"];
|
|
64061
|
+
var MANAGED_CODEX_AGENT_NAMES2 = [
|
|
64062
|
+
"codex-ultrawork-reviewer",
|
|
64063
|
+
"explorer",
|
|
64064
|
+
"librarian",
|
|
64065
|
+
"metis",
|
|
64066
|
+
"momus",
|
|
64067
|
+
"plan"
|
|
64068
|
+
];
|
|
64069
|
+
function cleanupCodexLightConfigText(config) {
|
|
64070
|
+
let nextConfig = config;
|
|
64071
|
+
for (const marketplace of MANAGED_MARKETPLACES) {
|
|
64072
|
+
nextConfig = removeTomlSections2(nextConfig, (header) => header === `marketplaces.${marketplace}`);
|
|
64073
|
+
nextConfig = removeTomlSections2(nextConfig, (header) => isManagedPluginHeader(header, marketplace));
|
|
64074
|
+
nextConfig = removeTomlSections2(nextConfig, (header) => isManagedHookStateHeader(header, marketplace));
|
|
64075
|
+
}
|
|
64076
|
+
nextConfig = removeManagedAgentBlocks(nextConfig);
|
|
64077
|
+
return nextConfig.replace(/\n{3,}/g, `
|
|
64078
|
+
|
|
64079
|
+
`);
|
|
64080
|
+
}
|
|
64081
|
+
async function cleanupCodexConfig(configPath, now) {
|
|
64082
|
+
if (!await configExists(configPath))
|
|
64083
|
+
return { changed: false };
|
|
64084
|
+
const original = await readFile11(configPath, "utf8");
|
|
64085
|
+
const next = cleanupCodexLightConfigText(original);
|
|
64086
|
+
if (next === original)
|
|
64087
|
+
return { changed: false };
|
|
64088
|
+
const backupPath = `${configPath}.backup-${formatBackupTimestamp2(now?.() ?? new Date)}`;
|
|
64089
|
+
await mkdir7(dirname15(configPath), { recursive: true });
|
|
64090
|
+
await writeFile8(backupPath, original);
|
|
64091
|
+
await writeFile8(configPath, `${next.trimEnd()}
|
|
64092
|
+
`);
|
|
64093
|
+
return { changed: true, backupPath };
|
|
64094
|
+
}
|
|
64095
|
+
function removeManagedAgentBlocks(config) {
|
|
64096
|
+
const managedAgentNames = new Set(MANAGED_CODEX_AGENT_NAMES2);
|
|
64097
|
+
return splitTomlSections2(config).filter((section) => {
|
|
64098
|
+
if (section.header === null)
|
|
64099
|
+
return true;
|
|
64100
|
+
const agentName = parseAgentHeaderName2(section.header);
|
|
64101
|
+
if (agentName === null || !managedAgentNames.has(agentName))
|
|
64102
|
+
return true;
|
|
64103
|
+
return !section.text.includes(`config_file = ${JSON.stringify(`./agents/${agentName}.toml`)}`);
|
|
64104
|
+
}).map((section) => section.text).join("");
|
|
64105
|
+
}
|
|
64106
|
+
function isManagedPluginHeader(header, marketplace) {
|
|
64107
|
+
const pluginKey = parsePluginHeaderKey2(header);
|
|
64108
|
+
return pluginKey !== null && pluginKey.endsWith(`@${marketplace}`);
|
|
64109
|
+
}
|
|
64110
|
+
function isManagedHookStateHeader(header, marketplace) {
|
|
64111
|
+
const prefix = "hooks.state.";
|
|
64112
|
+
if (!header.startsWith(prefix))
|
|
64113
|
+
return false;
|
|
64114
|
+
const hookKey = parseJsonString2(header.slice(prefix.length));
|
|
64115
|
+
if (hookKey === null)
|
|
64116
|
+
return false;
|
|
64117
|
+
const separator = hookKey.indexOf(":");
|
|
64118
|
+
if (separator === -1)
|
|
64119
|
+
return false;
|
|
64120
|
+
return hookKey.slice(0, separator).endsWith(`@${marketplace}`);
|
|
64121
|
+
}
|
|
64122
|
+
function removeTomlSections2(config, shouldRemove) {
|
|
64123
|
+
return splitTomlSections2(config).filter((section) => section.header === null || !shouldRemove(section.header)).map((section) => section.text).join("");
|
|
64124
|
+
}
|
|
64125
|
+
function splitTomlSections2(config) {
|
|
64126
|
+
const lines = config.match(/[^\n]*\n?|$/g) ?? [];
|
|
64127
|
+
const sections = [];
|
|
64128
|
+
let current = { header: null, text: "" };
|
|
64129
|
+
for (const line of lines) {
|
|
64130
|
+
if (line.length === 0)
|
|
64131
|
+
break;
|
|
64132
|
+
const header = parseTomlHeader2(line);
|
|
64133
|
+
if (header !== null) {
|
|
64134
|
+
if (current.text.length > 0)
|
|
64135
|
+
sections.push(current);
|
|
64136
|
+
current = { header, text: line };
|
|
64137
|
+
} else {
|
|
64138
|
+
current.text += line;
|
|
64139
|
+
}
|
|
64140
|
+
}
|
|
64141
|
+
if (current.text.length > 0)
|
|
64142
|
+
sections.push(current);
|
|
64143
|
+
return sections;
|
|
64144
|
+
}
|
|
64145
|
+
function parseTomlHeader2(line) {
|
|
64146
|
+
const trimmed = line.trim();
|
|
64147
|
+
if (!trimmed.startsWith("[") || !trimmed.endsWith("]") || trimmed.startsWith("[["))
|
|
64148
|
+
return null;
|
|
64149
|
+
return trimmed.slice(1, -1);
|
|
64150
|
+
}
|
|
64151
|
+
function parsePluginHeaderKey2(header) {
|
|
64152
|
+
const prefix = "plugins.";
|
|
64153
|
+
if (!header.startsWith(prefix))
|
|
64154
|
+
return null;
|
|
64155
|
+
return parseLeadingJsonString2(header.slice(prefix.length));
|
|
64156
|
+
}
|
|
64157
|
+
function parseAgentHeaderName2(header) {
|
|
64158
|
+
const prefix = "agents.";
|
|
64159
|
+
if (!header.startsWith(prefix))
|
|
64160
|
+
return null;
|
|
64161
|
+
const key = header.slice(prefix.length);
|
|
64162
|
+
return key.startsWith('"') ? parseLeadingJsonString2(key) : key;
|
|
64163
|
+
}
|
|
64164
|
+
function parseLeadingJsonString2(value) {
|
|
64165
|
+
if (!value.startsWith('"'))
|
|
64166
|
+
return parseJsonString2(value);
|
|
64167
|
+
let escaped = false;
|
|
64168
|
+
for (let index = 1;index < value.length; index += 1) {
|
|
64169
|
+
const char = value[index];
|
|
64170
|
+
if (escaped) {
|
|
64171
|
+
escaped = false;
|
|
64172
|
+
continue;
|
|
64173
|
+
}
|
|
64174
|
+
if (char === "\\") {
|
|
64175
|
+
escaped = true;
|
|
64176
|
+
continue;
|
|
64177
|
+
}
|
|
64178
|
+
if (char === '"')
|
|
64179
|
+
return parseJsonString2(value.slice(0, index + 1));
|
|
64180
|
+
}
|
|
64181
|
+
return null;
|
|
64182
|
+
}
|
|
64183
|
+
function parseJsonString2(value) {
|
|
64184
|
+
try {
|
|
64185
|
+
const parsed = JSON.parse(value);
|
|
64186
|
+
return typeof parsed === "string" ? parsed : null;
|
|
64187
|
+
} catch (error) {
|
|
64188
|
+
if (error instanceof Error)
|
|
64189
|
+
return null;
|
|
64190
|
+
return null;
|
|
64191
|
+
}
|
|
64192
|
+
}
|
|
64193
|
+
function formatBackupTimestamp2(date) {
|
|
64194
|
+
return date.toISOString().replace(/[:.]/g, "-");
|
|
64195
|
+
}
|
|
64196
|
+
async function configExists(path7) {
|
|
64197
|
+
try {
|
|
64198
|
+
await lstat5(path7);
|
|
64199
|
+
return true;
|
|
64200
|
+
} catch (error) {
|
|
64201
|
+
if (nodeErrorCode2(error) === "ENOENT")
|
|
64202
|
+
return false;
|
|
64203
|
+
throw error;
|
|
64204
|
+
}
|
|
64205
|
+
}
|
|
64206
|
+
function nodeErrorCode2(error) {
|
|
64207
|
+
if (!(error instanceof Error) || !("code" in error))
|
|
64208
|
+
return null;
|
|
64209
|
+
return typeof error.code === "string" ? error.code : null;
|
|
64210
|
+
}
|
|
64211
|
+
|
|
64212
|
+
// src/cli/install-codex/codex-cleanup.ts
|
|
64213
|
+
var INSTALLED_AGENTS_MANIFEST = ".installed-agents.json";
|
|
64214
|
+
async function cleanupCodexLight(input = {}) {
|
|
64215
|
+
const env = input.env ?? process.env;
|
|
64216
|
+
const codexHome = resolve10(input.codexHome ?? env.CODEX_HOME ?? join34(homedir7(), ".codex"));
|
|
64217
|
+
const configPath = join34(codexHome, "config.toml");
|
|
64218
|
+
const agentPaths = await collectInstalledAgentPaths(codexHome);
|
|
64219
|
+
const configCleanup = await cleanupCodexConfig(configPath, input.now);
|
|
64220
|
+
const agentCleanup = await removeManifestListedAgentLinks(codexHome, agentPaths);
|
|
64221
|
+
const removedPaths = [];
|
|
64222
|
+
for (const path7 of managedGlobalStatePaths(codexHome)) {
|
|
64223
|
+
if (await removePathIfExists(path7))
|
|
64224
|
+
removedPaths.push(path7);
|
|
64225
|
+
}
|
|
64226
|
+
const projectDirectory = input.projectDirectory ?? env.OMO_CODEX_PROJECT ?? process.cwd();
|
|
64227
|
+
const projectCleanup = await repairProjectLocalCodexArtifactsBestEffort({
|
|
64228
|
+
startDirectory: projectDirectory,
|
|
64229
|
+
codexHome,
|
|
64230
|
+
now: input.now,
|
|
64231
|
+
log: () => {
|
|
64232
|
+
return;
|
|
64233
|
+
}
|
|
64234
|
+
});
|
|
64235
|
+
return {
|
|
64236
|
+
codexHome,
|
|
64237
|
+
configPath,
|
|
64238
|
+
configChanged: configCleanup.changed,
|
|
64239
|
+
configBackupPath: configCleanup.backupPath,
|
|
64240
|
+
removedPaths,
|
|
64241
|
+
removedAgentLinks: agentCleanup.removed,
|
|
64242
|
+
skippedAgentLinks: agentCleanup.skipped,
|
|
64243
|
+
projectCleanup
|
|
64244
|
+
};
|
|
64245
|
+
}
|
|
64246
|
+
function managedGlobalStatePaths(codexHome) {
|
|
64247
|
+
return [
|
|
64248
|
+
join34(codexHome, "plugins", "cache", "sisyphuslabs"),
|
|
64249
|
+
join34(codexHome, ".tmp", "marketplaces", "sisyphuslabs")
|
|
64250
|
+
];
|
|
64251
|
+
}
|
|
64252
|
+
async function collectInstalledAgentPaths(codexHome) {
|
|
64253
|
+
const manifestPaths = [
|
|
64254
|
+
join34(codexHome, ".tmp", "marketplaces", "sisyphuslabs", "plugins", "omo", INSTALLED_AGENTS_MANIFEST)
|
|
64255
|
+
];
|
|
64256
|
+
const versionRoot = join34(codexHome, "plugins", "cache", "sisyphuslabs", "omo");
|
|
64257
|
+
if (await exists6(versionRoot)) {
|
|
64258
|
+
const entries = await readdir4(versionRoot, { withFileTypes: true });
|
|
64259
|
+
for (const entry of entries) {
|
|
64260
|
+
if (entry.isDirectory())
|
|
64261
|
+
manifestPaths.push(join34(versionRoot, entry.name, INSTALLED_AGENTS_MANIFEST));
|
|
64262
|
+
}
|
|
64263
|
+
}
|
|
64264
|
+
const paths = new Set;
|
|
64265
|
+
for (const manifestPath of manifestPaths) {
|
|
64266
|
+
for (const path7 of await readInstalledAgentManifest(manifestPath)) {
|
|
64267
|
+
paths.add(path7);
|
|
64268
|
+
}
|
|
64269
|
+
}
|
|
64270
|
+
return [...paths].sort();
|
|
64271
|
+
}
|
|
64272
|
+
async function readInstalledAgentManifest(manifestPath) {
|
|
64273
|
+
if (!await exists6(manifestPath))
|
|
64274
|
+
return [];
|
|
64275
|
+
const parsed = JSON.parse(await readFile12(manifestPath, "utf8"));
|
|
64276
|
+
if (!isRecord15(parsed) || !Array.isArray(parsed.agents))
|
|
64277
|
+
return [];
|
|
64278
|
+
return parsed.agents.filter((path7) => typeof path7 === "string");
|
|
64279
|
+
}
|
|
64280
|
+
async function removeManifestListedAgentLinks(codexHome, paths) {
|
|
64281
|
+
const agentsDir = join34(codexHome, "agents");
|
|
64282
|
+
const removed = [];
|
|
64283
|
+
const skipped = [];
|
|
64284
|
+
for (const path7 of paths) {
|
|
64285
|
+
if (!isSafeManagedAgentPath(agentsDir, path7)) {
|
|
64286
|
+
skipped.push(path7);
|
|
64287
|
+
continue;
|
|
64288
|
+
}
|
|
64289
|
+
const entryStat = await maybeLstat2(path7);
|
|
64290
|
+
if (entryStat === null)
|
|
64291
|
+
continue;
|
|
64292
|
+
if (entryStat.isDirectory() && !entryStat.isSymbolicLink()) {
|
|
64293
|
+
skipped.push(path7);
|
|
64294
|
+
continue;
|
|
64295
|
+
}
|
|
64296
|
+
await rm5(path7, { force: true });
|
|
64297
|
+
removed.push(path7);
|
|
64298
|
+
}
|
|
64299
|
+
return { removed, skipped };
|
|
64300
|
+
}
|
|
64301
|
+
function isSafeManagedAgentPath(agentsDir, path7) {
|
|
64302
|
+
if (!isAbsolute6(path7))
|
|
64303
|
+
return false;
|
|
64304
|
+
const relativePath = relative5(agentsDir, path7);
|
|
64305
|
+
if (relativePath === "" || relativePath.startsWith("..") || isAbsolute6(relativePath))
|
|
64306
|
+
return false;
|
|
64307
|
+
const fileName = relativePath.split(/[\\/]/).pop();
|
|
64308
|
+
if (fileName === undefined)
|
|
64309
|
+
return false;
|
|
64310
|
+
return MANAGED_CODEX_AGENT_NAMES2.some((agentName) => fileName === `${agentName}.toml`);
|
|
64311
|
+
}
|
|
64312
|
+
async function removePathIfExists(path7) {
|
|
64313
|
+
if (!await exists6(path7))
|
|
64314
|
+
return false;
|
|
64315
|
+
await rm5(path7, { recursive: true, force: true });
|
|
64316
|
+
return true;
|
|
64317
|
+
}
|
|
64318
|
+
async function exists6(path7) {
|
|
64319
|
+
return await maybeLstat2(path7) !== null;
|
|
64320
|
+
}
|
|
64321
|
+
async function maybeLstat2(path7) {
|
|
64322
|
+
try {
|
|
64323
|
+
return await lstat6(path7);
|
|
64324
|
+
} catch (error) {
|
|
64325
|
+
if (nodeErrorCode3(error) === "ENOENT")
|
|
64326
|
+
return null;
|
|
64327
|
+
throw error;
|
|
64328
|
+
}
|
|
64329
|
+
}
|
|
64330
|
+
function nodeErrorCode3(error) {
|
|
64331
|
+
if (!(error instanceof Error) || !("code" in error))
|
|
64332
|
+
return null;
|
|
64333
|
+
return typeof error.code === "string" ? error.code : null;
|
|
64334
|
+
}
|
|
64335
|
+
function isRecord15(value) {
|
|
64336
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
64337
|
+
}
|
|
63055
64338
|
// src/cli/star-request.ts
|
|
64339
|
+
import { execFile as execFile2 } from "child_process";
|
|
64340
|
+
import { promisify as promisify2 } from "util";
|
|
63056
64341
|
var STAR_REPOSITORIES = [
|
|
63057
64342
|
"code-yeongyu/oh-my-openagent",
|
|
63058
64343
|
"code-yeongyu/lazycodex"
|
|
63059
64344
|
];
|
|
63060
|
-
|
|
63061
|
-
|
|
64345
|
+
var PLATFORM_REPOSITORIES = {
|
|
64346
|
+
opencode: ["code-yeongyu/oh-my-openagent"],
|
|
64347
|
+
codex: STAR_REPOSITORIES,
|
|
64348
|
+
both: STAR_REPOSITORIES
|
|
64349
|
+
};
|
|
64350
|
+
var execFileAsync = promisify2(execFile2);
|
|
64351
|
+
async function runGitHubStarCommand(repository) {
|
|
64352
|
+
await execFileAsync("gh", ["api", "--silent", "--method", "PUT", `/user/starred/${repository}`]);
|
|
64353
|
+
}
|
|
64354
|
+
async function starGitHubRepositories(platform = "both", runCommand = runGitHubStarCommand) {
|
|
64355
|
+
const results = [];
|
|
64356
|
+
for (const repository of PLATFORM_REPOSITORIES[platform]) {
|
|
64357
|
+
try {
|
|
64358
|
+
await runCommand(repository);
|
|
64359
|
+
results.push({ repository, ok: true });
|
|
64360
|
+
} catch (error) {
|
|
64361
|
+
results.push({ repository, ok: false, error: error instanceof Error ? error.message : String(error) });
|
|
64362
|
+
}
|
|
64363
|
+
}
|
|
64364
|
+
return results;
|
|
63062
64365
|
}
|
|
63063
64366
|
|
|
63064
64367
|
// src/cli/cli-installer.ts
|
|
@@ -63133,10 +64436,10 @@ async function runCliInstaller(args, version2) {
|
|
|
63133
64436
|
printSuccess(`Config written ${SYMBOLS.arrow} ${import_picocolors3.default.dim(omoResult.configPath)}`);
|
|
63134
64437
|
}
|
|
63135
64438
|
printBox(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
|
|
63136
|
-
if (!config.hasClaude) {
|
|
64439
|
+
if (config.hasOpenCode && !config.hasClaude) {
|
|
63137
64440
|
printInfo("Note: Sisyphus agent performs best with Claude Opus 4.5+. " + "Other models work but may have reduced orchestration quality.");
|
|
63138
64441
|
}
|
|
63139
|
-
if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen && !config.hasVercelAiGateway) {
|
|
64442
|
+
if (config.hasOpenCode && !config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen && !config.hasVercelAiGateway) {
|
|
63140
64443
|
printWarning("No model providers configured. Using opencode/big-pickle as fallback.");
|
|
63141
64444
|
}
|
|
63142
64445
|
console.log(`${SYMBOLS.star} ${import_picocolors3.default.bold(import_picocolors3.default.green(isUpdate ? "Configuration updated!" : "Installation complete!"))}`);
|
|
@@ -63165,11 +64468,9 @@ async function runCliInstaller(args, version2) {
|
|
|
63165
64468
|
printBox(`${import_picocolors3.default.bold("Pro Tip:")} Include ${import_picocolors3.default.cyan("ultrawork")} (or ${import_picocolors3.default.cyan("ulw")}) in your prompt.
|
|
63166
64469
|
` + `All features work like magic-parallel agents, background tasks,
|
|
63167
64470
|
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
63168
|
-
|
|
63169
|
-
|
|
63170
|
-
console.log(` ${import_picocolors3.default.dim(formatGitHubStarCommand(repository))}`);
|
|
64471
|
+
if (args.tui) {
|
|
64472
|
+
await maybePromptForGitHubStars(config.platform);
|
|
63171
64473
|
}
|
|
63172
|
-
console.log();
|
|
63173
64474
|
console.log(import_picocolors3.default.dim("oMoMoMoMo... Enjoy!"));
|
|
63174
64475
|
console.log();
|
|
63175
64476
|
if (hasOpenCode && (config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
@@ -63180,6 +64481,34 @@ async function runCliInstaller(args, version2) {
|
|
|
63180
64481
|
}
|
|
63181
64482
|
return 0;
|
|
63182
64483
|
}
|
|
64484
|
+
async function maybePromptForGitHubStars(platform) {
|
|
64485
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY)
|
|
64486
|
+
return;
|
|
64487
|
+
const readline = createInterface2({ input: process.stdin, output: process.stdout });
|
|
64488
|
+
try {
|
|
64489
|
+
const answer = await readline.question(`${SYMBOLS.star} ${import_picocolors3.default.yellow("Star the repos on GitHub?")} ${import_picocolors3.default.dim("[y/N]")} `);
|
|
64490
|
+
if (!isYes(answer))
|
|
64491
|
+
return;
|
|
64492
|
+
} finally {
|
|
64493
|
+
readline.close();
|
|
64494
|
+
}
|
|
64495
|
+
const results = await starGitHubRepositories(platform);
|
|
64496
|
+
const failed = results.filter((result) => !result.ok);
|
|
64497
|
+
if (failed.length === 0) {
|
|
64498
|
+
printSuccess("Starred GitHub repositories");
|
|
64499
|
+
console.log();
|
|
64500
|
+
return;
|
|
64501
|
+
}
|
|
64502
|
+
printWarning("Could not star every repository. Make sure GitHub CLI is installed and authenticated.");
|
|
64503
|
+
for (const result of failed) {
|
|
64504
|
+
console.log(` ${SYMBOLS.bullet} ${result.repository}`);
|
|
64505
|
+
}
|
|
64506
|
+
console.log();
|
|
64507
|
+
}
|
|
64508
|
+
function isYes(value) {
|
|
64509
|
+
const normalized = value.trim().toLowerCase();
|
|
64510
|
+
return normalized === "y" || normalized === "yes";
|
|
64511
|
+
}
|
|
63183
64512
|
|
|
63184
64513
|
// node_modules/.bun/@clack+core@1.3.1/node_modules/@clack/core/dist/index.mjs
|
|
63185
64514
|
import { styleText as v } from "util";
|
|
@@ -63828,6 +65157,24 @@ var Q = class extends m {
|
|
|
63828
65157
|
}
|
|
63829
65158
|
}
|
|
63830
65159
|
};
|
|
65160
|
+
|
|
65161
|
+
class X extends m {
|
|
65162
|
+
get cursor() {
|
|
65163
|
+
return this.value ? 0 : 1;
|
|
65164
|
+
}
|
|
65165
|
+
get _value() {
|
|
65166
|
+
return this.cursor === 0;
|
|
65167
|
+
}
|
|
65168
|
+
constructor(t) {
|
|
65169
|
+
super(t, false), this.value = !!t.initialValue, this.on("userInput", () => {
|
|
65170
|
+
this.value = this._value;
|
|
65171
|
+
}), this.on("confirm", (s) => {
|
|
65172
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = s, this.state = "submit", this.close();
|
|
65173
|
+
}), this.on("cursor", () => {
|
|
65174
|
+
this.value = !this.value;
|
|
65175
|
+
});
|
|
65176
|
+
}
|
|
65177
|
+
}
|
|
63831
65178
|
var Z = { Y: { type: "year", len: 4 }, M: { type: "month", len: 2 }, D: { type: "day", len: 2 } };
|
|
63832
65179
|
function P(r) {
|
|
63833
65180
|
return [...r].map((t) => Z[t]);
|
|
@@ -64265,6 +65612,33 @@ var F2 = ({ cursor: t, options: i2, style: s, output: r = process.stdout, maxIte
|
|
|
64265
65612
|
S2.push(G2);
|
|
64266
65613
|
return h2 && S2.push(l), S2;
|
|
64267
65614
|
};
|
|
65615
|
+
var ue = (t) => {
|
|
65616
|
+
const i2 = t.active ?? "Yes", s = t.inactive ?? "No";
|
|
65617
|
+
return new X({ active: i2, inactive: s, signal: t.signal, input: t.input, output: t.output, initialValue: t.initialValue ?? true, render() {
|
|
65618
|
+
const r = t.withGuide ?? h.withGuide, u = `${P2(this.state)} `, n = r ? `${e("gray", $2)} ` : "", a = W(t.output, t.message, n, u), c = `${r ? `${e("gray", $2)}
|
|
65619
|
+
` : ""}${a}
|
|
65620
|
+
`, o = this.value ? i2 : s;
|
|
65621
|
+
switch (this.state) {
|
|
65622
|
+
case "submit": {
|
|
65623
|
+
const l = r ? `${e("gray", $2)} ` : "";
|
|
65624
|
+
return `${c}${l}${e("dim", o)}`;
|
|
65625
|
+
}
|
|
65626
|
+
case "cancel": {
|
|
65627
|
+
const l = r ? `${e("gray", $2)} ` : "";
|
|
65628
|
+
return `${c}${l}${e(["strikethrough", "dim"], o)}${r ? `
|
|
65629
|
+
${e("gray", $2)}` : ""}`;
|
|
65630
|
+
}
|
|
65631
|
+
default: {
|
|
65632
|
+
const l = r ? `${e("cyan", $2)} ` : "", d = r ? e("cyan", x2) : "";
|
|
65633
|
+
return `${c}${l}${this.value ? `${e("green", z2)} ${i2}` : `${e("dim", U2)} ${e("dim", i2)}`}${t.vertical ? r ? `
|
|
65634
|
+
${e("cyan", $2)} ` : `
|
|
65635
|
+
` : ` ${e("dim", "/")} `}${this.value ? `${e("dim", U2)} ${e("dim", s)}` : `${e("green", z2)} ${s}`}
|
|
65636
|
+
${d}
|
|
65637
|
+
`;
|
|
65638
|
+
}
|
|
65639
|
+
}
|
|
65640
|
+
} }).prompt();
|
|
65641
|
+
};
|
|
64268
65642
|
var R2 = { message: (t = [], { symbol: i2 = e("gray", $2), secondarySymbol: s = e("gray", $2), output: r = process.stdout, spacing: u = 1, withGuide: n } = {}) => {
|
|
64269
65643
|
const a = [], c = n ?? h.withGuide, o = c ? s : "", l = c ? `${i2} ` : "", d = c ? `${s} ` : "";
|
|
64270
65644
|
for (let p2 = 0;p2 < u; p2++)
|
|
@@ -64606,14 +65980,7 @@ async function resolveCodexAutonomous(hasCodex, override) {
|
|
|
64606
65980
|
return false;
|
|
64607
65981
|
if (override !== undefined)
|
|
64608
65982
|
return override;
|
|
64609
|
-
return
|
|
64610
|
-
message: "Configure Codex for autonomous full-permissions mode?",
|
|
64611
|
-
options: [
|
|
64612
|
-
{ value: true, label: "Yes", hint: "Recommended: approval never, danger-full-access, network enabled" },
|
|
64613
|
-
{ value: false, label: "No", hint: "Leave existing Codex permissions unchanged" }
|
|
64614
|
-
],
|
|
64615
|
-
initialValue: true
|
|
64616
|
-
});
|
|
65983
|
+
return true;
|
|
64617
65984
|
}
|
|
64618
65985
|
|
|
64619
65986
|
// src/cli/tui-installer.ts
|
|
@@ -64687,15 +66054,19 @@ async function runTuiInstaller(args, version2) {
|
|
|
64687
66054
|
}
|
|
64688
66055
|
spinner.stop(`Config written to ${import_picocolors4.default.cyan(omoResult.configPath)}`);
|
|
64689
66056
|
}
|
|
64690
|
-
if (!config.hasClaude) {
|
|
66057
|
+
if (config.hasOpenCode && !config.hasClaude) {
|
|
64691
66058
|
R2.info(`${import_picocolors4.default.bold("Note:")} Sisyphus agent performs best with Claude Opus 4.5+.
|
|
64692
66059
|
` + `Other models work but may have reduced orchestration quality.`);
|
|
64693
66060
|
}
|
|
64694
|
-
if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen && !config.hasVercelAiGateway) {
|
|
66061
|
+
if (config.hasOpenCode && !config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen && !config.hasVercelAiGateway) {
|
|
64695
66062
|
R2.warn("No model providers configured. Using opencode/big-pickle as fallback.");
|
|
64696
66063
|
}
|
|
64697
66064
|
Se(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
|
|
64698
66065
|
if (config.hasCodex) {
|
|
66066
|
+
const codexInstallation = await detectCodexInstallation();
|
|
66067
|
+
if (!codexInstallation.found) {
|
|
66068
|
+
R2.warn(formatCodexInstallationWarning(codexInstallation));
|
|
66069
|
+
}
|
|
64699
66070
|
spinner.start("Installing Codex harness adapter");
|
|
64700
66071
|
try {
|
|
64701
66072
|
const codexResult = await runCodexInstaller({ autonomousPermissions: config.codexAutonomous });
|
|
@@ -64720,9 +66091,20 @@ async function runTuiInstaller(args, version2) {
|
|
|
64720
66091
|
Se(`Include ${import_picocolors4.default.cyan("ultrawork")} (or ${import_picocolors4.default.cyan("ulw")}) in your prompt.
|
|
64721
66092
|
` + `All features work like magic-parallel agents, background tasks,
|
|
64722
66093
|
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
64723
|
-
|
|
64724
|
-
|
|
64725
|
-
|
|
66094
|
+
const shouldStar = await ue({
|
|
66095
|
+
message: "Star the repos on GitHub?",
|
|
66096
|
+
initialValue: false
|
|
66097
|
+
});
|
|
66098
|
+
if (!q(shouldStar) && shouldStar) {
|
|
66099
|
+
spinner.start("Starring GitHub repositories");
|
|
66100
|
+
const results = await starGitHubRepositories(selectedPlatform);
|
|
66101
|
+
const failed = results.filter((result) => !result.ok);
|
|
66102
|
+
if (failed.length === 0) {
|
|
66103
|
+
spinner.stop("GitHub repositories starred");
|
|
66104
|
+
} else {
|
|
66105
|
+
spinner.stop("Could not star every repository");
|
|
66106
|
+
R2.warn("Make sure GitHub CLI is installed and authenticated.");
|
|
66107
|
+
}
|
|
64726
66108
|
}
|
|
64727
66109
|
ye(import_picocolors4.default.green("oMoMoMoMo... Enjoy!"));
|
|
64728
66110
|
if (config.hasOpenCode && (config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
@@ -64751,6 +66133,71 @@ async function install(args) {
|
|
|
64751
66133
|
return args.tui ? runTuiInstaller(args, VERSION) : runCliInstaller(args, VERSION);
|
|
64752
66134
|
}
|
|
64753
66135
|
|
|
66136
|
+
// src/cli/cleanup.ts
|
|
66137
|
+
function resolveCleanupPlatform(options, invocationName = process.env.OMO_INVOCATION_NAME) {
|
|
66138
|
+
if (options.platform !== undefined)
|
|
66139
|
+
return options.platform;
|
|
66140
|
+
return invocationName === "lazycodex" || invocationName === "lazycodex-ai" ? "codex" : undefined;
|
|
66141
|
+
}
|
|
66142
|
+
async function cleanup(options) {
|
|
66143
|
+
if (options.platform !== "codex") {
|
|
66144
|
+
console.error("Error: cleanup currently supports only --platform=codex");
|
|
66145
|
+
return 1;
|
|
66146
|
+
}
|
|
66147
|
+
const result = await cleanupCodexLight({
|
|
66148
|
+
codexHome: options.codexHome,
|
|
66149
|
+
projectDirectory: options.project
|
|
66150
|
+
});
|
|
66151
|
+
if (options.json === true) {
|
|
66152
|
+
console.log(JSON.stringify(result, null, 2));
|
|
66153
|
+
return 0;
|
|
66154
|
+
}
|
|
66155
|
+
console.log(`Codex Light cleanup complete: ${result.codexHome}`);
|
|
66156
|
+
if (result.configChanged) {
|
|
66157
|
+
console.log(`- Updated ${result.configPath}`);
|
|
66158
|
+
if (result.configBackupPath !== undefined)
|
|
66159
|
+
console.log(`- Backup ${result.configBackupPath}`);
|
|
66160
|
+
} else {
|
|
66161
|
+
console.log(`- No managed Codex config blocks found in ${result.configPath}`);
|
|
66162
|
+
}
|
|
66163
|
+
for (const path7 of result.removedPaths) {
|
|
66164
|
+
console.log(`- Removed ${path7}`);
|
|
66165
|
+
}
|
|
66166
|
+
for (const path7 of result.removedAgentLinks) {
|
|
66167
|
+
console.log(`- Removed managed agent link ${path7}`);
|
|
66168
|
+
}
|
|
66169
|
+
for (const path7 of result.skippedAgentLinks) {
|
|
66170
|
+
console.log(`- Skipped agent path outside managed scope ${path7}`);
|
|
66171
|
+
}
|
|
66172
|
+
if (result.projectCleanup.changed) {
|
|
66173
|
+
console.log(`- Repaired project-local Codex config ${result.projectCleanup.configPath}`);
|
|
66174
|
+
}
|
|
66175
|
+
for (const artifact of result.projectCleanup.artifacts) {
|
|
66176
|
+
console.log(`- Left project-local artifact in place ${artifact.path}`);
|
|
66177
|
+
}
|
|
66178
|
+
return 0;
|
|
66179
|
+
}
|
|
66180
|
+
|
|
66181
|
+
// src/cli/cleanup-command.ts
|
|
66182
|
+
function configureCleanupCommand(program2) {
|
|
66183
|
+
program2.command("cleanup").description("Clean managed Codex Light state and repair project-local legacy Codex artifacts").addOption(new Option("--platform <platform>", "Cleanup target platform: codex").choices(["codex"])).option("--codex-home <path>", "Codex home to clean (defaults to CODEX_HOME or ~/.codex)").option("--project <path>", "Project directory to inspect for project-local .codex/.omx artifacts").option("--json", "Output structured JSON result").addHelpText("after", `
|
|
66184
|
+
Examples:
|
|
66185
|
+
$ npx lazycodex-ai cleanup
|
|
66186
|
+
$ omo cleanup --platform=codex
|
|
66187
|
+
$ omo cleanup --platform=codex --project /path/to/project
|
|
66188
|
+
`).action(async (options) => {
|
|
66189
|
+
const rootOptions = program2.opts();
|
|
66190
|
+
const platform = resolveCleanupPlatform({ platform: options.platform ?? rootOptions.platform });
|
|
66191
|
+
const exitCode = await cleanup({
|
|
66192
|
+
platform,
|
|
66193
|
+
codexHome: options.codexHome,
|
|
66194
|
+
project: options.project,
|
|
66195
|
+
json: options.json ?? false
|
|
66196
|
+
});
|
|
66197
|
+
process.exit(exitCode);
|
|
66198
|
+
});
|
|
66199
|
+
}
|
|
66200
|
+
|
|
64754
66201
|
// src/cli/run/runner.ts
|
|
64755
66202
|
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
64756
66203
|
|
|
@@ -64758,6 +66205,7 @@ var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
|
64758
66205
|
function createEventState() {
|
|
64759
66206
|
return {
|
|
64760
66207
|
mainSessionIdle: false,
|
|
66208
|
+
mainSessionStarted: false,
|
|
64761
66209
|
mainSessionError: false,
|
|
64762
66210
|
lastError: null,
|
|
64763
66211
|
lastOutput: "",
|
|
@@ -65173,10 +66621,12 @@ function handleSessionStatus(ctx, payload, state) {
|
|
|
65173
66621
|
return;
|
|
65174
66622
|
if (props?.status?.type === "busy") {
|
|
65175
66623
|
state.mainSessionIdle = false;
|
|
66624
|
+
state.mainSessionStarted = true;
|
|
65176
66625
|
} else if (props?.status?.type === "idle") {
|
|
65177
66626
|
state.mainSessionIdle = true;
|
|
65178
66627
|
} else if (props?.status?.type === "retry") {
|
|
65179
66628
|
state.mainSessionIdle = false;
|
|
66629
|
+
state.mainSessionStarted = true;
|
|
65180
66630
|
}
|
|
65181
66631
|
}
|
|
65182
66632
|
function handleSessionError(ctx, payload, state) {
|
|
@@ -65216,6 +66666,7 @@ function handleMessagePartUpdated(ctx, payload, state) {
|
|
|
65216
66666
|
const padded = writePaddedText(newText, state.thinkingAtLineStart);
|
|
65217
66667
|
process.stdout.write(import_picocolors7.default.dim(padded.output));
|
|
65218
66668
|
state.thinkingAtLineStart = padded.atLineStart;
|
|
66669
|
+
state.mainSessionStarted = true;
|
|
65219
66670
|
state.hasReceivedMeaningfulWork = true;
|
|
65220
66671
|
}
|
|
65221
66672
|
state.lastReasoningText = reasoningText;
|
|
@@ -65228,6 +66679,7 @@ function handleMessagePartUpdated(ctx, payload, state) {
|
|
|
65228
66679
|
const padded = writePaddedText(newText, state.textAtLineStart);
|
|
65229
66680
|
process.stdout.write(padded.output);
|
|
65230
66681
|
state.textAtLineStart = padded.atLineStart;
|
|
66682
|
+
state.mainSessionStarted = true;
|
|
65231
66683
|
state.hasReceivedMeaningfulWork = true;
|
|
65232
66684
|
}
|
|
65233
66685
|
state.lastPartText = part.text;
|
|
@@ -65239,6 +66691,7 @@ function handleMessagePartUpdated(ctx, payload, state) {
|
|
|
65239
66691
|
}
|
|
65240
66692
|
}
|
|
65241
66693
|
if (part.type === "tool") {
|
|
66694
|
+
state.mainSessionStarted = true;
|
|
65242
66695
|
handleToolPart(ctx, part, state);
|
|
65243
66696
|
}
|
|
65244
66697
|
}
|
|
@@ -65264,6 +66717,7 @@ function handleMessagePartDelta(ctx, payload, state) {
|
|
|
65264
66717
|
process.stdout.write(import_picocolors7.default.dim(padded2.output));
|
|
65265
66718
|
state.thinkingAtLineStart = padded2.atLineStart;
|
|
65266
66719
|
state.lastReasoningText += delta;
|
|
66720
|
+
state.mainSessionStarted = true;
|
|
65267
66721
|
state.hasReceivedMeaningfulWork = true;
|
|
65268
66722
|
return;
|
|
65269
66723
|
}
|
|
@@ -65272,6 +66726,7 @@ function handleMessagePartDelta(ctx, payload, state) {
|
|
|
65272
66726
|
process.stdout.write(padded.output);
|
|
65273
66727
|
state.textAtLineStart = padded.atLineStart;
|
|
65274
66728
|
state.lastPartText += delta;
|
|
66729
|
+
state.mainSessionStarted = true;
|
|
65275
66730
|
state.hasReceivedMeaningfulWork = true;
|
|
65276
66731
|
}
|
|
65277
66732
|
function handleToolPart(_ctx, part, state) {
|
|
@@ -65317,11 +66772,15 @@ function handleMessageUpdated(ctx, payload, state) {
|
|
|
65317
66772
|
if (messageID && role) {
|
|
65318
66773
|
state.messageRoleById[messageID] = role;
|
|
65319
66774
|
}
|
|
66775
|
+
if (messageID) {
|
|
66776
|
+
state.mainSessionStarted = true;
|
|
66777
|
+
}
|
|
65320
66778
|
if (props?.info?.role !== "assistant")
|
|
65321
66779
|
return;
|
|
65322
66780
|
const isNewMessage = !messageID || messageID !== state.currentMessageId;
|
|
65323
66781
|
if (isNewMessage) {
|
|
65324
66782
|
state.currentMessageId = messageID;
|
|
66783
|
+
state.mainSessionStarted = true;
|
|
65325
66784
|
state.hasReceivedMeaningfulWork = true;
|
|
65326
66785
|
state.messageCount++;
|
|
65327
66786
|
state.lastPartText = "";
|
|
@@ -65357,6 +66816,7 @@ function handleToolExecute(ctx, payload, state) {
|
|
|
65357
66816
|
return;
|
|
65358
66817
|
const toolName = props?.name || "unknown";
|
|
65359
66818
|
state.currentTool = toolName;
|
|
66819
|
+
state.mainSessionStarted = true;
|
|
65360
66820
|
const header = formatToolHeader(toolName, props?.input ?? {});
|
|
65361
66821
|
const suffix = header.description ? ` ${import_picocolors7.default.dim(header.description)}` : "";
|
|
65362
66822
|
state.hasReceivedMeaningfulWork = true;
|
|
@@ -65451,7 +66911,7 @@ async function processEvents(ctx, stream, state) {
|
|
|
65451
66911
|
}
|
|
65452
66912
|
// src/plugin-config.ts
|
|
65453
66913
|
import * as fs4 from "fs";
|
|
65454
|
-
import { homedir as
|
|
66914
|
+
import { homedir as homedir8 } from "os";
|
|
65455
66915
|
import * as path7 from "path";
|
|
65456
66916
|
|
|
65457
66917
|
// node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
@@ -67065,8 +68525,8 @@ function emoji() {
|
|
|
67065
68525
|
}
|
|
67066
68526
|
var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
|
|
67067
68527
|
var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
|
|
67068
|
-
var mac = (
|
|
67069
|
-
const escapedDelim = escapeRegex(
|
|
68528
|
+
var mac = (delimiter2) => {
|
|
68529
|
+
const escapedDelim = escapeRegex(delimiter2 ?? ":");
|
|
67070
68530
|
return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
|
|
67071
68531
|
};
|
|
67072
68532
|
var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
|
|
@@ -71813,9 +73273,9 @@ var error17 = () => {
|
|
|
71813
73273
|
if (issue2.values.length === 2) {
|
|
71814
73274
|
return `\u05E2\u05E8\u05DA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF: \u05D4\u05D0\u05E4\u05E9\u05E8\u05D5\u05D9\u05D5\u05EA \u05D4\u05DE\u05EA\u05D0\u05D9\u05DE\u05D5\u05EA \u05D4\u05DF ${stringified[0]} \u05D0\u05D5 ${stringified[1]}`;
|
|
71815
73275
|
}
|
|
71816
|
-
const
|
|
73276
|
+
const lastValue2 = stringified[stringified.length - 1];
|
|
71817
73277
|
const restValues = stringified.slice(0, -1).join(", ");
|
|
71818
|
-
return `\u05E2\u05E8\u05DA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF: \u05D4\u05D0\u05E4\u05E9\u05E8\u05D5\u05D9\u05D5\u05EA \u05D4\u05DE\u05EA\u05D0\u05D9\u05DE\u05D5\u05EA \u05D4\u05DF ${restValues} \u05D0\u05D5 ${
|
|
73278
|
+
return `\u05E2\u05E8\u05DA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF: \u05D4\u05D0\u05E4\u05E9\u05E8\u05D5\u05D9\u05D5\u05EA \u05D4\u05DE\u05EA\u05D0\u05D9\u05DE\u05D5\u05EA \u05D4\u05DF ${restValues} \u05D0\u05D5 ${lastValue2}`;
|
|
71819
73279
|
}
|
|
71820
73280
|
case "too_big": {
|
|
71821
73281
|
const sizing = getSizing(issue2.origin);
|
|
@@ -80025,7 +81485,6 @@ var GitMasterConfigSchema = exports_external.object({
|
|
|
80025
81485
|
// src/config/schema/hooks.ts
|
|
80026
81486
|
var HookNameSchema = exports_external.enum([
|
|
80027
81487
|
"todo-continuation-enforcer",
|
|
80028
|
-
"context-window-monitor",
|
|
80029
81488
|
"session-recovery",
|
|
80030
81489
|
"session-notification",
|
|
80031
81490
|
"comment-checker",
|
|
@@ -80480,7 +81939,7 @@ function addAgentOrderWarnings(configPath, agentOrder) {
|
|
|
80480
81939
|
});
|
|
80481
81940
|
}
|
|
80482
81941
|
function resolveHomeDirectory() {
|
|
80483
|
-
return process.env.HOME ?? process.env.USERPROFILE ??
|
|
81942
|
+
return process.env.HOME ?? process.env.USERPROFILE ?? homedir8();
|
|
80484
81943
|
}
|
|
80485
81944
|
function resolveConfigPathAfterLegacyMigration(detectedPath) {
|
|
80486
81945
|
if (!path7.basename(detectedPath).startsWith(LEGACY_CONFIG_BASENAME)) {
|
|
@@ -80776,7 +82235,7 @@ function loadPluginConfig(directory, ctx) {
|
|
|
80776
82235
|
// node_modules/.bun/@opencode-ai+sdk@1.15.10/node_modules/@opencode-ai/sdk/dist/gen/core/serverSentEvents.gen.js
|
|
80777
82236
|
var createSseClient = ({ onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url: url2, ...options }) => {
|
|
80778
82237
|
let lastEventId;
|
|
80779
|
-
const sleep = sseSleepFn ?? ((ms) => new Promise((
|
|
82238
|
+
const sleep = sseSleepFn ?? ((ms) => new Promise((resolve11) => setTimeout(resolve11, ms)));
|
|
80780
82239
|
const createStream = async function* () {
|
|
80781
82240
|
let retryDelay = sseDefaultRetryDelay ?? 3000;
|
|
80782
82241
|
let attempt = 0;
|
|
@@ -82239,7 +83698,7 @@ async function createOpencodeServer(options) {
|
|
|
82239
83698
|
}
|
|
82240
83699
|
});
|
|
82241
83700
|
let clear = () => {};
|
|
82242
|
-
const url2 = await new Promise((
|
|
83701
|
+
const url2 = await new Promise((resolve11, reject) => {
|
|
82243
83702
|
const id = setTimeout(() => {
|
|
82244
83703
|
clear();
|
|
82245
83704
|
stop(proc);
|
|
@@ -82265,7 +83724,7 @@ async function createOpencodeServer(options) {
|
|
|
82265
83724
|
}
|
|
82266
83725
|
clearTimeout(id);
|
|
82267
83726
|
resolved = true;
|
|
82268
|
-
|
|
83727
|
+
resolve11(match[1]);
|
|
82269
83728
|
return;
|
|
82270
83729
|
}
|
|
82271
83730
|
}
|
|
@@ -82320,7 +83779,7 @@ var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
|
82320
83779
|
|
|
82321
83780
|
// src/cli/run/opencode-binary-resolver.ts
|
|
82322
83781
|
init_spawn_with_windows_hide();
|
|
82323
|
-
import { delimiter, dirname as
|
|
83782
|
+
import { delimiter as delimiter2, dirname as dirname17, join as join36 } from "path";
|
|
82324
83783
|
var OPENCODE_COMMANDS = ["opencode", "opencode-desktop"];
|
|
82325
83784
|
var WINDOWS_SUFFIXES = ["", ".exe", ".cmd", ".bat", ".ps1"];
|
|
82326
83785
|
function getCommandCandidates(platform) {
|
|
@@ -82341,9 +83800,9 @@ function collectCandidateBinaryPaths(pathEnv, which = Bun.which, platform = proc
|
|
|
82341
83800
|
for (const command of commandCandidates) {
|
|
82342
83801
|
addCandidate(which(command));
|
|
82343
83802
|
}
|
|
82344
|
-
for (const entry of (pathEnv ?? "").split(
|
|
83803
|
+
for (const entry of (pathEnv ?? "").split(delimiter2).filter(Boolean)) {
|
|
82345
83804
|
for (const command of commandCandidates) {
|
|
82346
|
-
addCandidate(
|
|
83805
|
+
addCandidate(join36(entry, command));
|
|
82347
83806
|
}
|
|
82348
83807
|
}
|
|
82349
83808
|
return candidates;
|
|
@@ -82370,9 +83829,9 @@ async function findWorkingOpencodeBinary(pathEnv = process.env.PATH, probe = can
|
|
|
82370
83829
|
return null;
|
|
82371
83830
|
}
|
|
82372
83831
|
function buildPathWithBinaryFirst(pathEnv, binaryPath) {
|
|
82373
|
-
const preferredDir =
|
|
82374
|
-
const existing = (pathEnv ?? "").split(
|
|
82375
|
-
return [preferredDir, ...existing].join(
|
|
83832
|
+
const preferredDir = dirname17(binaryPath);
|
|
83833
|
+
const existing = (pathEnv ?? "").split(delimiter2).filter((entry) => entry.length > 0 && entry !== preferredDir);
|
|
83834
|
+
return [preferredDir, ...existing].join(delimiter2);
|
|
82376
83835
|
}
|
|
82377
83836
|
async function withWorkingOpencodePath(startServer, finder = findWorkingOpencodeBinary) {
|
|
82378
83837
|
const originalPath = process.env.PATH;
|
|
@@ -82421,6 +83880,7 @@ function isPortRangeExhausted(error51) {
|
|
|
82421
83880
|
async function startServer(options, deps) {
|
|
82422
83881
|
const { signal, port } = options;
|
|
82423
83882
|
const { client: client3, server: server2 } = await deps.withWorkingOpencodePath(() => deps.createOpencode({ signal, port, hostname: "127.0.0.1" }));
|
|
83883
|
+
deps.injectServerAuthIntoClient(client3);
|
|
82424
83884
|
console.log(import_picocolors9.default.dim("Server listening at"), import_picocolors9.default.cyan(server2.url));
|
|
82425
83885
|
return { client: client3, cleanup: () => server2.close() };
|
|
82426
83886
|
}
|
|
@@ -82534,7 +83994,7 @@ async function resolveSession(options) {
|
|
|
82534
83994
|
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
82535
83995
|
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
82536
83996
|
console.log(import_picocolors10.default.dim(` Retrying in ${delay}ms...`));
|
|
82537
|
-
await new Promise((
|
|
83997
|
+
await new Promise((resolve11) => setTimeout(resolve11, delay));
|
|
82538
83998
|
}
|
|
82539
83999
|
continue;
|
|
82540
84000
|
}
|
|
@@ -82545,7 +84005,7 @@ async function resolveSession(options) {
|
|
|
82545
84005
|
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
82546
84006
|
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
82547
84007
|
console.log(import_picocolors10.default.dim(` Retrying in ${delay}ms...`));
|
|
82548
|
-
await new Promise((
|
|
84008
|
+
await new Promise((resolve11) => setTimeout(resolve11, delay));
|
|
82549
84009
|
}
|
|
82550
84010
|
}
|
|
82551
84011
|
throw new Error("Failed to create session after all retries");
|
|
@@ -82674,11 +84134,10 @@ var normalizeAgentName = (agent) => {
|
|
|
82674
84134
|
return;
|
|
82675
84135
|
const configKey = getAgentConfigKey(trimmed);
|
|
82676
84136
|
const displayName = getAgentDisplayName(configKey);
|
|
82677
|
-
const runtimeName = getAgentDisplayName(configKey);
|
|
82678
84137
|
const isKnownAgent = displayName !== configKey;
|
|
82679
84138
|
return {
|
|
82680
84139
|
configKey,
|
|
82681
|
-
resolvedName: isKnownAgent ?
|
|
84140
|
+
resolvedName: isKnownAgent ? configKey : trimmed
|
|
82682
84141
|
};
|
|
82683
84142
|
};
|
|
82684
84143
|
var isAgentDisabled = (agentConfigKey, config2) => {
|
|
@@ -82702,19 +84161,18 @@ var resolveRunAgent = (options, pluginConfig, env = process.env) => {
|
|
|
82702
84161
|
const configAgent = normalizeAgentName(pluginConfig.default_run_agent);
|
|
82703
84162
|
const resolved = cliAgent ?? envAgent ?? configAgent ?? {
|
|
82704
84163
|
configKey: DEFAULT_AGENT,
|
|
82705
|
-
resolvedName:
|
|
84164
|
+
resolvedName: DEFAULT_AGENT
|
|
82706
84165
|
};
|
|
82707
84166
|
if (isAgentDisabled(resolved.configKey, pluginConfig)) {
|
|
82708
84167
|
const fallback = pickFallbackAgent(pluginConfig);
|
|
82709
84168
|
const fallbackDisplayName = getAgentDisplayName(fallback);
|
|
82710
|
-
const fallbackRuntimeName = getAgentDisplayName(fallback);
|
|
82711
84169
|
const fallbackDisabled = isAgentDisabled(fallback, pluginConfig);
|
|
82712
84170
|
if (fallbackDisabled) {
|
|
82713
84171
|
console.log(import_picocolors11.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled and no enabled core agent was found. Proceeding with "${fallbackDisplayName}".`));
|
|
82714
|
-
return
|
|
84172
|
+
return fallback;
|
|
82715
84173
|
}
|
|
82716
84174
|
console.log(import_picocolors11.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled. Falling back to "${fallbackDisplayName}".`));
|
|
82717
|
-
return
|
|
84175
|
+
return fallback;
|
|
82718
84176
|
}
|
|
82719
84177
|
return resolved.resolvedName;
|
|
82720
84178
|
};
|
|
@@ -82756,7 +84214,7 @@ var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
|
|
|
82756
84214
|
var NOTEPAD_DIR = "notepads";
|
|
82757
84215
|
var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
|
|
82758
84216
|
// packages/boulder-state/src/top-level-task.ts
|
|
82759
|
-
import { existsSync as
|
|
84217
|
+
import { existsSync as existsSync28, readFileSync as readFileSync15 } from "fs";
|
|
82760
84218
|
var TODO_HEADING_PATTERN = /^##\s+TODOs\b/i;
|
|
82761
84219
|
var FINAL_VERIFICATION_HEADING_PATTERN = /^##\s+Final Verification Wave\b/i;
|
|
82762
84220
|
var SECOND_LEVEL_HEADING_PATTERN = /^##\s+/;
|
|
@@ -82779,7 +84237,7 @@ function buildTaskRef(section, taskLabel) {
|
|
|
82779
84237
|
};
|
|
82780
84238
|
}
|
|
82781
84239
|
function readCurrentTopLevelTask(planPath) {
|
|
82782
|
-
if (!
|
|
84240
|
+
if (!existsSync28(planPath)) {
|
|
82783
84241
|
return null;
|
|
82784
84242
|
}
|
|
82785
84243
|
try {
|
|
@@ -82808,13 +84266,13 @@ function readCurrentTopLevelTask(planPath) {
|
|
|
82808
84266
|
}
|
|
82809
84267
|
}
|
|
82810
84268
|
// packages/boulder-state/src/storage/path.ts
|
|
82811
|
-
import { existsSync as
|
|
82812
|
-
import { isAbsolute as
|
|
84269
|
+
import { existsSync as existsSync29 } from "fs";
|
|
84270
|
+
import { isAbsolute as isAbsolute7, join as join37, relative as relative6, resolve as resolve11 } from "path";
|
|
82813
84271
|
function getBoulderFilePath(directory) {
|
|
82814
|
-
return
|
|
84272
|
+
return join37(directory, BOULDER_DIR, BOULDER_FILE);
|
|
82815
84273
|
}
|
|
82816
84274
|
function resolveTrackedPath(baseDirectory, trackedPath) {
|
|
82817
|
-
return
|
|
84275
|
+
return isAbsolute7(trackedPath) ? resolve11(trackedPath) : resolve11(baseDirectory, trackedPath);
|
|
82818
84276
|
}
|
|
82819
84277
|
function resolveBoulderPlanPath(directory, state) {
|
|
82820
84278
|
const absolutePlanPath = resolveTrackedPath(directory, state.active_plan);
|
|
@@ -82822,20 +84280,20 @@ function resolveBoulderPlanPath(directory, state) {
|
|
|
82822
84280
|
if (!worktreePath) {
|
|
82823
84281
|
return absolutePlanPath;
|
|
82824
84282
|
}
|
|
82825
|
-
const absoluteDirectory =
|
|
82826
|
-
const relativePlanPath =
|
|
82827
|
-
if (relativePlanPath.length === 0 || relativePlanPath.startsWith("..") ||
|
|
84283
|
+
const absoluteDirectory = resolve11(directory);
|
|
84284
|
+
const relativePlanPath = relative6(absoluteDirectory, absolutePlanPath);
|
|
84285
|
+
if (relativePlanPath.length === 0 || relativePlanPath.startsWith("..") || isAbsolute7(relativePlanPath)) {
|
|
82828
84286
|
return absolutePlanPath;
|
|
82829
84287
|
}
|
|
82830
84288
|
const absoluteWorktreePath = resolveTrackedPath(directory, worktreePath);
|
|
82831
|
-
const worktreePlanPath =
|
|
82832
|
-
return
|
|
84289
|
+
const worktreePlanPath = resolve11(absoluteWorktreePath, relativePlanPath);
|
|
84290
|
+
return existsSync29(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
|
|
82833
84291
|
}
|
|
82834
84292
|
function resolveBoulderPlanPathForWork(directory, work) {
|
|
82835
84293
|
return resolveBoulderPlanPath(directory, work);
|
|
82836
84294
|
}
|
|
82837
84295
|
// packages/boulder-state/src/storage/plan-progress.ts
|
|
82838
|
-
import { existsSync as
|
|
84296
|
+
import { existsSync as existsSync30, readFileSync as readFileSync16, readdirSync as readdirSync4, statSync as statSync4 } from "fs";
|
|
82839
84297
|
var TODO_HEADING_PATTERN2 = /^##\s+TODOs\b/i;
|
|
82840
84298
|
var FINAL_VERIFICATION_HEADING_PATTERN2 = /^##\s+Final Verification Wave\b/i;
|
|
82841
84299
|
var SECOND_LEVEL_HEADING_PATTERN2 = /^##\s+/;
|
|
@@ -82844,7 +84302,7 @@ var CHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[[xX]\]\s*(.+)$/;
|
|
|
82844
84302
|
var TODO_TASK_PATTERN2 = /^\d+\.\s+/;
|
|
82845
84303
|
var FINAL_WAVE_TASK_PATTERN2 = /^F\d+\.\s+/i;
|
|
82846
84304
|
function getPlanProgress(planPath) {
|
|
82847
|
-
if (!
|
|
84305
|
+
if (!existsSync30(planPath)) {
|
|
82848
84306
|
return { total: 0, completed: 0, isComplete: false };
|
|
82849
84307
|
}
|
|
82850
84308
|
try {
|
|
@@ -82964,10 +84422,10 @@ function selectMirrorWork(state) {
|
|
|
82964
84422
|
return sorted[0] ?? null;
|
|
82965
84423
|
}
|
|
82966
84424
|
// packages/boulder-state/src/storage/read-state.ts
|
|
82967
|
-
import { existsSync as
|
|
84425
|
+
import { existsSync as existsSync31, readFileSync as readFileSync17 } from "fs";
|
|
82968
84426
|
function readBoulderState(directory) {
|
|
82969
84427
|
const filePath = getBoulderFilePath(directory);
|
|
82970
|
-
if (!
|
|
84428
|
+
if (!existsSync31(filePath)) {
|
|
82971
84429
|
return null;
|
|
82972
84430
|
}
|
|
82973
84431
|
try {
|
|
@@ -83047,14 +84505,14 @@ function getSessionAgent(sessionID) {
|
|
|
83047
84505
|
// src/features/run-continuation-state/constants.ts
|
|
83048
84506
|
var CONTINUATION_MARKER_DIR = ".omo/run-continuation";
|
|
83049
84507
|
// src/features/run-continuation-state/storage.ts
|
|
83050
|
-
import { existsSync as
|
|
83051
|
-
import { join as
|
|
84508
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync9, readFileSync as readFileSync18, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
84509
|
+
import { join as join38 } from "path";
|
|
83052
84510
|
function getMarkerPath(directory, sessionID) {
|
|
83053
|
-
return
|
|
84511
|
+
return join38(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
|
|
83054
84512
|
}
|
|
83055
84513
|
function readContinuationMarker(directory, sessionID) {
|
|
83056
84514
|
const markerPath = getMarkerPath(directory, sessionID);
|
|
83057
|
-
if (!
|
|
84515
|
+
if (!existsSync32(markerPath))
|
|
83058
84516
|
return null;
|
|
83059
84517
|
try {
|
|
83060
84518
|
const raw = readFileSync18(markerPath, "utf-8");
|
|
@@ -83120,7 +84578,7 @@ async function isSessionInBoulderLineage(input) {
|
|
|
83120
84578
|
init_shared();
|
|
83121
84579
|
init_compaction_marker();
|
|
83122
84580
|
import { readFileSync as readFileSync19, readdirSync as readdirSync5 } from "fs";
|
|
83123
|
-
import { join as
|
|
84581
|
+
import { join as join39 } from "path";
|
|
83124
84582
|
var defaultSessionLastAgentDeps = {
|
|
83125
84583
|
getMessageDir,
|
|
83126
84584
|
isSqliteBackend,
|
|
@@ -83174,7 +84632,7 @@ async function getLastAgentFromSession(sessionID, client3, deps = {}) {
|
|
|
83174
84632
|
try {
|
|
83175
84633
|
const messages = readdirSync5(messageDir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => {
|
|
83176
84634
|
try {
|
|
83177
|
-
const content = readFileSync19(
|
|
84635
|
+
const content = readFileSync19(join39(messageDir, fileName), "utf-8");
|
|
83178
84636
|
const parsed = JSON.parse(content);
|
|
83179
84637
|
return {
|
|
83180
84638
|
fileName,
|
|
@@ -83210,8 +84668,8 @@ init_agent_display_names();
|
|
|
83210
84668
|
|
|
83211
84669
|
// src/hooks/ralph-loop/storage.ts
|
|
83212
84670
|
init_frontmatter2();
|
|
83213
|
-
import { existsSync as
|
|
83214
|
-
import { dirname as
|
|
84671
|
+
import { existsSync as existsSync33, readFileSync as readFileSync20, writeFileSync as writeFileSync7, unlinkSync as unlinkSync5, mkdirSync as mkdirSync10 } from "fs";
|
|
84672
|
+
import { dirname as dirname18, join as join40 } from "path";
|
|
83215
84673
|
|
|
83216
84674
|
// src/hooks/ralph-loop/constants.ts
|
|
83217
84675
|
var DEFAULT_STATE_FILE = ".omo/ralph-loop.local.md";
|
|
@@ -83220,11 +84678,11 @@ var DEFAULT_COMPLETION_PROMISE = "DONE";
|
|
|
83220
84678
|
|
|
83221
84679
|
// src/hooks/ralph-loop/storage.ts
|
|
83222
84680
|
function getStateFilePath(directory, customPath) {
|
|
83223
|
-
return customPath ?
|
|
84681
|
+
return customPath ? join40(directory, customPath) : join40(directory, DEFAULT_STATE_FILE);
|
|
83224
84682
|
}
|
|
83225
84683
|
function readState(directory, customPath) {
|
|
83226
84684
|
const filePath = getStateFilePath(directory, customPath);
|
|
83227
|
-
if (!
|
|
84685
|
+
if (!existsSync33(filePath)) {
|
|
83228
84686
|
return null;
|
|
83229
84687
|
}
|
|
83230
84688
|
try {
|
|
@@ -83449,13 +84907,14 @@ async function pollForCompletion(ctx, eventState, abortController, options = {})
|
|
|
83449
84907
|
const minStabilizationMs = rawMinStabilizationMs > 0 ? rawMinStabilizationMs : MIN_STABILIZATION_MS;
|
|
83450
84908
|
const eventWatchdogMs = options.eventWatchdogMs ?? DEFAULT_EVENT_WATCHDOG_MS;
|
|
83451
84909
|
const secondaryMeaningfulWorkTimeoutMs = options.secondaryMeaningfulWorkTimeoutMs ?? DEFAULT_SECONDARY_MEANINGFUL_WORK_TIMEOUT_MS;
|
|
84910
|
+
const requireMeaningfulWork = options.requireMeaningfulWork ?? false;
|
|
83452
84911
|
let consecutiveCompleteChecks = 0;
|
|
83453
84912
|
let errorCycleCount = 0;
|
|
83454
84913
|
let firstWorkTimestamp = null;
|
|
83455
84914
|
let secondaryTimeoutChecked = false;
|
|
83456
84915
|
const pollStartTimestamp = Date.now();
|
|
83457
84916
|
while (!abortController.signal.aborted) {
|
|
83458
|
-
await new Promise((
|
|
84917
|
+
await new Promise((resolve12) => setTimeout(resolve12, pollIntervalMs));
|
|
83459
84918
|
if (abortController.signal.aborted) {
|
|
83460
84919
|
return 130;
|
|
83461
84920
|
}
|
|
@@ -83508,21 +84967,24 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
83508
84967
|
consecutiveCompleteChecks = 0;
|
|
83509
84968
|
continue;
|
|
83510
84969
|
}
|
|
84970
|
+
if (requireMeaningfulWork) {
|
|
84971
|
+
if (Date.now() - pollStartTimestamp <= secondaryMeaningfulWorkTimeoutMs) {
|
|
84972
|
+
consecutiveCompleteChecks = 0;
|
|
84973
|
+
continue;
|
|
84974
|
+
}
|
|
84975
|
+
const hasActiveWork = await hasActiveSessionWork(ctx);
|
|
84976
|
+
if (hasActiveWork) {
|
|
84977
|
+
consecutiveCompleteChecks = 0;
|
|
84978
|
+
continue;
|
|
84979
|
+
}
|
|
84980
|
+
console.error(import_picocolors13.default.red(`
|
|
84981
|
+
|
|
84982
|
+
Session never produced assistant output, tool activity, or reasoning after the prompt started.`));
|
|
84983
|
+
return 1;
|
|
84984
|
+
}
|
|
83511
84985
|
if (Date.now() - pollStartTimestamp > secondaryMeaningfulWorkTimeoutMs && !secondaryTimeoutChecked) {
|
|
83512
84986
|
secondaryTimeoutChecked = true;
|
|
83513
|
-
const
|
|
83514
|
-
path: { id: ctx.sessionID },
|
|
83515
|
-
query: { directory: ctx.directory }
|
|
83516
|
-
});
|
|
83517
|
-
const children = normalizeSDKResponse(childrenRes, []);
|
|
83518
|
-
const todosRes = await ctx.client.session.todo({
|
|
83519
|
-
path: { id: ctx.sessionID },
|
|
83520
|
-
query: { directory: ctx.directory }
|
|
83521
|
-
});
|
|
83522
|
-
const todos = normalizeSDKResponse(todosRes, []);
|
|
83523
|
-
const hasActiveChildren = Array.isArray(children) && children.length > 0;
|
|
83524
|
-
const hasActiveTodos = Array.isArray(todos) && todos.some(isIncompleteTodo);
|
|
83525
|
-
const hasActiveWork = hasActiveChildren || hasActiveTodos;
|
|
84987
|
+
const hasActiveWork = await hasActiveSessionWork(ctx);
|
|
83526
84988
|
if (hasActiveWork) {
|
|
83527
84989
|
eventState.hasReceivedMeaningfulWork = true;
|
|
83528
84990
|
console.log(import_picocolors13.default.yellow(`
|
|
@@ -83556,6 +85018,21 @@ All tasks completed.`));
|
|
|
83556
85018
|
}
|
|
83557
85019
|
return 130;
|
|
83558
85020
|
}
|
|
85021
|
+
async function hasActiveSessionWork(ctx) {
|
|
85022
|
+
const childrenRes = await ctx.client.session.children({
|
|
85023
|
+
path: { id: ctx.sessionID },
|
|
85024
|
+
query: { directory: ctx.directory }
|
|
85025
|
+
});
|
|
85026
|
+
const children = normalizeSDKResponse(childrenRes, []);
|
|
85027
|
+
const todosRes = await ctx.client.session.todo({
|
|
85028
|
+
path: { id: ctx.sessionID },
|
|
85029
|
+
query: { directory: ctx.directory }
|
|
85030
|
+
});
|
|
85031
|
+
const todos = normalizeSDKResponse(todosRes, []);
|
|
85032
|
+
const hasActiveChildren = Array.isArray(children) && children.length > 0;
|
|
85033
|
+
const hasActiveTodos = Array.isArray(todos) && todos.some(isIncompleteTodo);
|
|
85034
|
+
return hasActiveChildren || hasActiveTodos;
|
|
85035
|
+
}
|
|
83559
85036
|
async function getMainSessionStatus(ctx) {
|
|
83560
85037
|
try {
|
|
83561
85038
|
const statusesRes = await ctx.client.session.status({
|
|
@@ -83575,6 +85052,88 @@ async function getMainSessionStatus(ctx) {
|
|
|
83575
85052
|
}
|
|
83576
85053
|
}
|
|
83577
85054
|
|
|
85055
|
+
// src/cli/run/prompt-start.ts
|
|
85056
|
+
init_shared();
|
|
85057
|
+
var DEFAULT_PROMPT_START_TIMEOUT_MS = 30000;
|
|
85058
|
+
var DEFAULT_PROMPT_START_POLL_INTERVAL_MS = 100;
|
|
85059
|
+
function createAbortError() {
|
|
85060
|
+
const error51 = new Error("Prompt start wait aborted");
|
|
85061
|
+
error51.name = "AbortError";
|
|
85062
|
+
return error51;
|
|
85063
|
+
}
|
|
85064
|
+
function sleep(delayMs) {
|
|
85065
|
+
return new Promise((resolve12) => setTimeout(resolve12, delayMs));
|
|
85066
|
+
}
|
|
85067
|
+
function hasPromptStartEvidence(eventState) {
|
|
85068
|
+
return eventState.mainSessionStarted || eventState.hasReceivedMeaningfulWork || eventState.messageCount > 0 || eventState.currentTool !== null;
|
|
85069
|
+
}
|
|
85070
|
+
async function readMainSessionStatus(ctx) {
|
|
85071
|
+
if (typeof ctx.client.session.status !== "function") {
|
|
85072
|
+
return null;
|
|
85073
|
+
}
|
|
85074
|
+
try {
|
|
85075
|
+
const statusRes = await ctx.client.session.status({
|
|
85076
|
+
query: { directory: ctx.directory }
|
|
85077
|
+
});
|
|
85078
|
+
const statuses = normalizeSDKResponse(statusRes, {});
|
|
85079
|
+
return statuses[ctx.sessionID]?.type ?? "idle";
|
|
85080
|
+
} catch (error51) {
|
|
85081
|
+
if (ctx.verbose) {
|
|
85082
|
+
console.error(`[run] failed to read session status while waiting for prompt start: ${String(error51)}`);
|
|
85083
|
+
}
|
|
85084
|
+
return null;
|
|
85085
|
+
}
|
|
85086
|
+
}
|
|
85087
|
+
async function hasPersistedMessages(ctx) {
|
|
85088
|
+
if (typeof ctx.client.session.messages !== "function") {
|
|
85089
|
+
return false;
|
|
85090
|
+
}
|
|
85091
|
+
try {
|
|
85092
|
+
const messagesRes = await ctx.client.session.messages({
|
|
85093
|
+
path: { id: ctx.sessionID },
|
|
85094
|
+
query: { directory: ctx.directory }
|
|
85095
|
+
});
|
|
85096
|
+
const messages = normalizeSDKResponse(messagesRes, []);
|
|
85097
|
+
return messages.length > 0;
|
|
85098
|
+
} catch (error51) {
|
|
85099
|
+
if (ctx.verbose) {
|
|
85100
|
+
console.error(`[run] failed to read session messages while waiting for prompt start: ${String(error51)}`);
|
|
85101
|
+
}
|
|
85102
|
+
return false;
|
|
85103
|
+
}
|
|
85104
|
+
}
|
|
85105
|
+
async function waitForPromptStart(ctx, eventState, abortController, options = {}) {
|
|
85106
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_PROMPT_START_TIMEOUT_MS;
|
|
85107
|
+
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_PROMPT_START_POLL_INTERVAL_MS;
|
|
85108
|
+
const startedAt = Date.now();
|
|
85109
|
+
while (!abortController.signal.aborted) {
|
|
85110
|
+
if (hasPromptStartEvidence(eventState)) {
|
|
85111
|
+
return;
|
|
85112
|
+
}
|
|
85113
|
+
if (eventState.mainSessionError) {
|
|
85114
|
+
throw new Error(`Session errored before prompt started: ${eventState.lastError ?? "unknown error"}`);
|
|
85115
|
+
}
|
|
85116
|
+
const status = await readMainSessionStatus(ctx);
|
|
85117
|
+
if (status === "busy" || status === "retry") {
|
|
85118
|
+
eventState.mainSessionStarted = true;
|
|
85119
|
+
eventState.mainSessionIdle = false;
|
|
85120
|
+
return;
|
|
85121
|
+
}
|
|
85122
|
+
if (status === "idle") {
|
|
85123
|
+
eventState.mainSessionIdle = true;
|
|
85124
|
+
}
|
|
85125
|
+
if (await hasPersistedMessages(ctx)) {
|
|
85126
|
+
eventState.mainSessionStarted = true;
|
|
85127
|
+
return;
|
|
85128
|
+
}
|
|
85129
|
+
if (Date.now() - startedAt >= timeoutMs) {
|
|
85130
|
+
throw new Error(`Prompt did not start within ${timeoutMs}ms; no busy status, message event, or persisted message was observed.`);
|
|
85131
|
+
}
|
|
85132
|
+
await sleep(pollIntervalMs);
|
|
85133
|
+
}
|
|
85134
|
+
throw createAbortError();
|
|
85135
|
+
}
|
|
85136
|
+
|
|
83578
85137
|
// src/cli/run/agent-profile-colors.ts
|
|
83579
85138
|
init_shared();
|
|
83580
85139
|
async function loadAgentProfileColors(client3) {
|
|
@@ -83684,7 +85243,7 @@ function createTimestampedStdoutController(stdout = process.stdout) {
|
|
|
83684
85243
|
// src/shared/posthog.ts
|
|
83685
85244
|
init_index_node();
|
|
83686
85245
|
import os5 from "os";
|
|
83687
|
-
import { createHash as
|
|
85246
|
+
import { createHash as createHash4 } from "crypto";
|
|
83688
85247
|
init_plugin_identity();
|
|
83689
85248
|
|
|
83690
85249
|
// src/shared/posthog-activity-state.ts
|
|
@@ -83692,11 +85251,11 @@ init_data_path();
|
|
|
83692
85251
|
init_logger();
|
|
83693
85252
|
init_plugin_identity();
|
|
83694
85253
|
init_write_file_atomically();
|
|
83695
|
-
import { existsSync as
|
|
83696
|
-
import { join as
|
|
85254
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync11, readFileSync as readFileSync21 } from "fs";
|
|
85255
|
+
import { join as join41 } from "path";
|
|
83697
85256
|
var POSTHOG_ACTIVITY_STATE_FILE2 = "posthog-activity.json";
|
|
83698
85257
|
function getPostHogActivityStateFilePath2() {
|
|
83699
|
-
return
|
|
85258
|
+
return join41(getDataDir(), CACHE_DIR_NAME, POSTHOG_ACTIVITY_STATE_FILE2);
|
|
83700
85259
|
}
|
|
83701
85260
|
function getUtcDayString2(date5) {
|
|
83702
85261
|
return date5.toISOString().slice(0, 10);
|
|
@@ -83706,7 +85265,7 @@ function isPostHogActivityState2(value) {
|
|
|
83706
85265
|
}
|
|
83707
85266
|
function readPostHogActivityState2() {
|
|
83708
85267
|
const stateFilePath = getPostHogActivityStateFilePath2();
|
|
83709
|
-
if (!
|
|
85268
|
+
if (!existsSync34(stateFilePath)) {
|
|
83710
85269
|
return {};
|
|
83711
85270
|
}
|
|
83712
85271
|
try {
|
|
@@ -83727,7 +85286,7 @@ function readPostHogActivityState2() {
|
|
|
83727
85286
|
function writePostHogActivityState2(nextState) {
|
|
83728
85287
|
const stateFilePath = getPostHogActivityStateFilePath2();
|
|
83729
85288
|
try {
|
|
83730
|
-
mkdirSync11(
|
|
85289
|
+
mkdirSync11(join41(getDataDir(), CACHE_DIR_NAME), { recursive: true });
|
|
83731
85290
|
writeFileAtomically(stateFilePath, `${JSON.stringify(nextState, null, 2)}
|
|
83732
85291
|
`);
|
|
83733
85292
|
} catch (error51) {
|
|
@@ -83775,8 +85334,11 @@ var NO_OP_POSTHOG2 = {
|
|
|
83775
85334
|
function isFalsy(value) {
|
|
83776
85335
|
return value === "0" || value === "false" || value === "no";
|
|
83777
85336
|
}
|
|
85337
|
+
function isTruthy(value) {
|
|
85338
|
+
return value === "1" || value === "true" || value === "yes";
|
|
85339
|
+
}
|
|
83778
85340
|
function shouldDisablePostHog2() {
|
|
83779
|
-
if (process.env.OMO_DISABLE_POSTHOG
|
|
85341
|
+
if (isTruthy(process.env.OMO_DISABLE_POSTHOG?.trim().toLowerCase())) {
|
|
83780
85342
|
return true;
|
|
83781
85343
|
}
|
|
83782
85344
|
return isFalsy(process.env.OMO_SEND_ANONYMOUS_TELEMETRY?.trim().toLowerCase());
|
|
@@ -83858,7 +85420,7 @@ function createPostHogClient2(source, options) {
|
|
|
83858
85420
|
};
|
|
83859
85421
|
}
|
|
83860
85422
|
function getPostHogDistinctId2() {
|
|
83861
|
-
return
|
|
85423
|
+
return createHash4("sha256").update(`${PUBLISHED_PACKAGE_NAME}:${resolveOsProvider2().hostname()}`).digest("hex");
|
|
83862
85424
|
}
|
|
83863
85425
|
function createCliPostHog2() {
|
|
83864
85426
|
return createPostHogClient2("cli", {
|
|
@@ -83877,7 +85439,7 @@ var EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS = 2000;
|
|
|
83877
85439
|
async function waitForEventProcessorShutdown(eventProcessor, timeoutMs = EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS) {
|
|
83878
85440
|
const completed = await Promise.race([
|
|
83879
85441
|
eventProcessor.then(() => true),
|
|
83880
|
-
new Promise((
|
|
85442
|
+
new Promise((resolve12) => setTimeout(() => resolve12(false), timeoutMs))
|
|
83881
85443
|
]);
|
|
83882
85444
|
}
|
|
83883
85445
|
async function run(options) {
|
|
@@ -83908,7 +85470,7 @@ async function run(options) {
|
|
|
83908
85470
|
attach: options.attach,
|
|
83909
85471
|
signal: abortController.signal
|
|
83910
85472
|
});
|
|
83911
|
-
const
|
|
85473
|
+
const cleanup2 = () => {
|
|
83912
85474
|
serverCleanup();
|
|
83913
85475
|
};
|
|
83914
85476
|
const restoreInput = suppressRunInput();
|
|
@@ -83916,7 +85478,7 @@ async function run(options) {
|
|
|
83916
85478
|
console.log(import_picocolors14.default.yellow(`
|
|
83917
85479
|
Interrupted. Shutting down...`));
|
|
83918
85480
|
restoreInput();
|
|
83919
|
-
|
|
85481
|
+
cleanup2();
|
|
83920
85482
|
process.exit(130);
|
|
83921
85483
|
};
|
|
83922
85484
|
process.on("SIGINT", handleSigint);
|
|
@@ -83974,10 +85536,13 @@ Interrupted. Shutting down...`));
|
|
|
83974
85536
|
if (!promptMayHaveBeenAccepted && !isInternalPromptDispatchAccepted(promptResult)) {
|
|
83975
85537
|
throw new Error(`Session ${sessionID} is not idle; promptAsync skipped by gate: ${promptResult.status}`);
|
|
83976
85538
|
}
|
|
83977
|
-
|
|
85539
|
+
await waitForPromptStart(ctx, eventState, abortController);
|
|
85540
|
+
const exitCode = await pollForCompletion(ctx, eventState, abortController, {
|
|
85541
|
+
requireMeaningfulWork: true
|
|
85542
|
+
});
|
|
83978
85543
|
abortController.abort();
|
|
83979
85544
|
await waitForEventProcessorShutdown(eventProcessor);
|
|
83980
|
-
|
|
85545
|
+
cleanup2();
|
|
83981
85546
|
const durationMs = Date.now() - startTime;
|
|
83982
85547
|
if (options.onComplete) {
|
|
83983
85548
|
await executeOnCompleteHook({
|
|
@@ -83999,7 +85564,7 @@ Interrupted. Shutting down...`));
|
|
|
83999
85564
|
}
|
|
84000
85565
|
return exitCode;
|
|
84001
85566
|
} catch (err) {
|
|
84002
|
-
|
|
85567
|
+
cleanup2();
|
|
84003
85568
|
throw err;
|
|
84004
85569
|
} finally {
|
|
84005
85570
|
process.removeListener("SIGINT", handleSigint);
|
|
@@ -84172,13 +85737,13 @@ async function getLocalVersion(options = {}) {
|
|
|
84172
85737
|
}
|
|
84173
85738
|
}
|
|
84174
85739
|
// src/cli/doctor/checks/system.ts
|
|
84175
|
-
import { existsSync as
|
|
85740
|
+
import { existsSync as existsSync45, readFileSync as readFileSync31 } from "fs";
|
|
84176
85741
|
|
|
84177
85742
|
// src/cli/doctor/checks/system-binary.ts
|
|
84178
85743
|
init_extract_semver();
|
|
84179
|
-
import { existsSync as
|
|
84180
|
-
import { homedir as
|
|
84181
|
-
import { join as
|
|
85744
|
+
import { existsSync as existsSync42, accessSync as accessSync4, constants as constants7 } from "fs";
|
|
85745
|
+
import { homedir as homedir11 } from "os";
|
|
85746
|
+
import { join as join48 } from "path";
|
|
84182
85747
|
|
|
84183
85748
|
// src/cli/doctor/spawn-with-timeout.ts
|
|
84184
85749
|
init_spawn_with_windows_hide();
|
|
@@ -84191,8 +85756,8 @@ async function spawnWithTimeout(command, options, timeoutMs = DEFAULT_SPAWN_TIME
|
|
|
84191
85756
|
return { stdout: "", stderr: "", exitCode: 1, timedOut: false };
|
|
84192
85757
|
}
|
|
84193
85758
|
let timer;
|
|
84194
|
-
const timeoutPromise = new Promise((
|
|
84195
|
-
timer = setTimeout(() =>
|
|
85759
|
+
const timeoutPromise = new Promise((resolve12) => {
|
|
85760
|
+
timer = setTimeout(() => resolve12("timeout"), timeoutMs);
|
|
84196
85761
|
});
|
|
84197
85762
|
const processPromise = (async () => {
|
|
84198
85763
|
await proc.exited;
|
|
@@ -84212,31 +85777,31 @@ async function spawnWithTimeout(command, options, timeoutMs = DEFAULT_SPAWN_TIME
|
|
|
84212
85777
|
|
|
84213
85778
|
// src/cli/doctor/checks/system-binary.ts
|
|
84214
85779
|
var WINDOWS_EXECUTABLE_EXTS = [".exe", ".cmd", ".bat", ".ps1"];
|
|
84215
|
-
function
|
|
85780
|
+
function isExecutable2(path14) {
|
|
84216
85781
|
try {
|
|
84217
|
-
|
|
85782
|
+
accessSync4(path14, constants7.X_OK);
|
|
84218
85783
|
return true;
|
|
84219
85784
|
} catch {
|
|
84220
85785
|
return false;
|
|
84221
85786
|
}
|
|
84222
85787
|
}
|
|
84223
85788
|
function getDesktopAppPaths(platform) {
|
|
84224
|
-
const home =
|
|
85789
|
+
const home = homedir11();
|
|
84225
85790
|
switch (platform) {
|
|
84226
85791
|
case "darwin":
|
|
84227
85792
|
return [
|
|
84228
85793
|
"/Applications/OpenCode.app/Contents/MacOS/OpenCode",
|
|
84229
|
-
|
|
85794
|
+
join48(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
|
|
84230
85795
|
];
|
|
84231
85796
|
case "win32": {
|
|
84232
85797
|
const programFiles = process.env.ProgramFiles;
|
|
84233
85798
|
const localAppData = process.env.LOCALAPPDATA;
|
|
84234
85799
|
const paths = [];
|
|
84235
85800
|
if (programFiles) {
|
|
84236
|
-
paths.push(
|
|
85801
|
+
paths.push(join48(programFiles, "OpenCode", "OpenCode.exe"));
|
|
84237
85802
|
}
|
|
84238
85803
|
if (localAppData) {
|
|
84239
|
-
paths.push(
|
|
85804
|
+
paths.push(join48(localAppData, "OpenCode", "OpenCode.exe"));
|
|
84240
85805
|
}
|
|
84241
85806
|
return paths;
|
|
84242
85807
|
}
|
|
@@ -84244,8 +85809,8 @@ function getDesktopAppPaths(platform) {
|
|
|
84244
85809
|
return [
|
|
84245
85810
|
"/usr/bin/opencode",
|
|
84246
85811
|
"/usr/lib/opencode/opencode",
|
|
84247
|
-
|
|
84248
|
-
|
|
85812
|
+
join48(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
|
|
85813
|
+
join48(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
|
|
84249
85814
|
];
|
|
84250
85815
|
default:
|
|
84251
85816
|
return [];
|
|
@@ -84257,7 +85822,7 @@ function buildVersionCommand(binaryPath, platform) {
|
|
|
84257
85822
|
}
|
|
84258
85823
|
return [binaryPath, "--version"];
|
|
84259
85824
|
}
|
|
84260
|
-
function findDesktopBinary(platform = process.platform, checkExists =
|
|
85825
|
+
function findDesktopBinary(platform = process.platform, checkExists = existsSync42) {
|
|
84261
85826
|
for (const desktopPath of getDesktopAppPaths(platform)) {
|
|
84262
85827
|
if (checkExists(desktopPath)) {
|
|
84263
85828
|
return { binary: "opencode", path: desktopPath };
|
|
@@ -84265,7 +85830,7 @@ function findDesktopBinary(platform = process.platform, checkExists = existsSync
|
|
|
84265
85830
|
}
|
|
84266
85831
|
return null;
|
|
84267
85832
|
}
|
|
84268
|
-
async function findOpenCodeBinary(platform = process.platform, checkExists =
|
|
85833
|
+
async function findOpenCodeBinary(platform = process.platform, checkExists = existsSync42) {
|
|
84269
85834
|
for (const binary2 of OPENCODE_BINARIES2) {
|
|
84270
85835
|
const path14 = Bun.which(binary2);
|
|
84271
85836
|
if (path14 && checkExists(path14)) {
|
|
@@ -84273,12 +85838,12 @@ async function findOpenCodeBinary(platform = process.platform, checkExists = exi
|
|
|
84273
85838
|
}
|
|
84274
85839
|
}
|
|
84275
85840
|
const pathEnv = process.env.PATH ?? "";
|
|
84276
|
-
const
|
|
85841
|
+
const delimiter3 = platform === "win32" ? ";" : ":";
|
|
84277
85842
|
const candidates = getCommandCandidates2(platform);
|
|
84278
|
-
for (const entry of pathEnv.split(
|
|
85843
|
+
for (const entry of pathEnv.split(delimiter3).filter(Boolean)) {
|
|
84279
85844
|
for (const command of candidates) {
|
|
84280
|
-
const fullPath =
|
|
84281
|
-
if (checkExists(fullPath) &&
|
|
85845
|
+
const fullPath = join48(entry, command);
|
|
85846
|
+
if (checkExists(fullPath) && isExecutable2(fullPath)) {
|
|
84282
85847
|
return { binary: command, path: fullPath };
|
|
84283
85848
|
}
|
|
84284
85849
|
}
|
|
@@ -84320,12 +85885,12 @@ function compareVersions3(current, minimum) {
|
|
|
84320
85885
|
|
|
84321
85886
|
// src/cli/doctor/checks/system-plugin.ts
|
|
84322
85887
|
init_shared();
|
|
84323
|
-
import { existsSync as
|
|
85888
|
+
import { existsSync as existsSync43, readFileSync as readFileSync29 } from "fs";
|
|
84324
85889
|
function detectConfigPath() {
|
|
84325
85890
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
84326
|
-
if (
|
|
85891
|
+
if (existsSync43(paths.configJsonc))
|
|
84327
85892
|
return paths.configJsonc;
|
|
84328
|
-
if (
|
|
85893
|
+
if (existsSync43(paths.configJson))
|
|
84329
85894
|
return paths.configJson;
|
|
84330
85895
|
return null;
|
|
84331
85896
|
}
|
|
@@ -84409,35 +85974,35 @@ function getPluginInfo() {
|
|
|
84409
85974
|
init_file_utils2();
|
|
84410
85975
|
init_checker();
|
|
84411
85976
|
init_auto_update_checker();
|
|
84412
|
-
import { existsSync as
|
|
85977
|
+
import { existsSync as existsSync44, readFileSync as readFileSync30 } from "fs";
|
|
84413
85978
|
import { createRequire } from "module";
|
|
84414
|
-
import { homedir as
|
|
84415
|
-
import { join as
|
|
85979
|
+
import { homedir as homedir12 } from "os";
|
|
85980
|
+
import { join as join49 } from "path";
|
|
84416
85981
|
init_shared();
|
|
84417
85982
|
function getPlatformDefaultCacheDir(platform = process.platform) {
|
|
84418
85983
|
if (platform === "darwin")
|
|
84419
|
-
return
|
|
85984
|
+
return join49(homedir12(), "Library", "Caches");
|
|
84420
85985
|
if (platform === "win32")
|
|
84421
|
-
return process.env.LOCALAPPDATA ??
|
|
84422
|
-
return
|
|
85986
|
+
return process.env.LOCALAPPDATA ?? join49(homedir12(), "AppData", "Local");
|
|
85987
|
+
return join49(homedir12(), ".cache");
|
|
84423
85988
|
}
|
|
84424
85989
|
function resolveOpenCodeCacheDir() {
|
|
84425
85990
|
const xdgCacheHome = process.env.XDG_CACHE_HOME;
|
|
84426
85991
|
if (xdgCacheHome)
|
|
84427
|
-
return
|
|
85992
|
+
return join49(xdgCacheHome, "opencode");
|
|
84428
85993
|
const fromShared = getOpenCodeCacheDir();
|
|
84429
|
-
const platformDefault =
|
|
84430
|
-
if (
|
|
85994
|
+
const platformDefault = join49(getPlatformDefaultCacheDir(), "opencode");
|
|
85995
|
+
if (existsSync44(fromShared) || !existsSync44(platformDefault))
|
|
84431
85996
|
return fromShared;
|
|
84432
85997
|
return platformDefault;
|
|
84433
85998
|
}
|
|
84434
85999
|
function resolveExistingDir(dirPath) {
|
|
84435
|
-
if (!
|
|
86000
|
+
if (!existsSync44(dirPath))
|
|
84436
86001
|
return dirPath;
|
|
84437
86002
|
return resolveSymlink(dirPath);
|
|
84438
86003
|
}
|
|
84439
86004
|
function readPackageJson(filePath) {
|
|
84440
|
-
if (!
|
|
86005
|
+
if (!existsSync44(filePath))
|
|
84441
86006
|
return null;
|
|
84442
86007
|
try {
|
|
84443
86008
|
const content = readFileSync30(filePath, "utf-8");
|
|
@@ -84455,11 +86020,11 @@ function normalizeVersion(value) {
|
|
|
84455
86020
|
function createPackageCandidates(rootDir) {
|
|
84456
86021
|
return ACCEPTED_PACKAGE_NAMES.map((packageName) => ({
|
|
84457
86022
|
packageName,
|
|
84458
|
-
installedPackagePath:
|
|
86023
|
+
installedPackagePath: join49(rootDir, "node_modules", packageName, "package.json")
|
|
84459
86024
|
}));
|
|
84460
86025
|
}
|
|
84461
86026
|
function selectInstalledPackage(candidate) {
|
|
84462
|
-
return candidate.packageCandidates.find((packageCandidate) =>
|
|
86027
|
+
return candidate.packageCandidates.find((packageCandidate) => existsSync44(packageCandidate.installedPackagePath)) ?? candidate.packageCandidates[0];
|
|
84463
86028
|
}
|
|
84464
86029
|
function getExpectedVersion(cachePackage, packageName) {
|
|
84465
86030
|
return normalizeVersion(cachePackage?.dependencies?.[packageName]) ?? normalizeVersion(cachePackage?.dependencies?.[PACKAGE_NAME]);
|
|
@@ -84470,7 +86035,7 @@ function resolveInstalledPackageJsonPath() {
|
|
|
84470
86035
|
for (const packageName of ACCEPTED_PACKAGE_NAMES) {
|
|
84471
86036
|
try {
|
|
84472
86037
|
const packageJsonPath = require2.resolve(`${packageName}/package.json`);
|
|
84473
|
-
if (
|
|
86038
|
+
if (existsSync44(packageJsonPath)) {
|
|
84474
86039
|
return { packageName, packageJsonPath };
|
|
84475
86040
|
}
|
|
84476
86041
|
} catch {
|
|
@@ -84489,20 +86054,20 @@ function getLoadedPluginVersion() {
|
|
|
84489
86054
|
const candidates = [
|
|
84490
86055
|
{
|
|
84491
86056
|
cacheDir: configDir,
|
|
84492
|
-
cachePackagePath:
|
|
86057
|
+
cachePackagePath: join49(configDir, "package.json"),
|
|
84493
86058
|
packageCandidates: createPackageCandidates(configDir)
|
|
84494
86059
|
},
|
|
84495
86060
|
{
|
|
84496
86061
|
cacheDir,
|
|
84497
|
-
cachePackagePath:
|
|
86062
|
+
cachePackagePath: join49(cacheDir, "package.json"),
|
|
84498
86063
|
packageCandidates: createPackageCandidates(cacheDir)
|
|
84499
86064
|
}
|
|
84500
86065
|
];
|
|
84501
|
-
const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) =>
|
|
86066
|
+
const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) => existsSync44(packageCandidate.installedPackagePath))) ?? candidates[0];
|
|
84502
86067
|
const { cacheDir: selectedDir, cachePackagePath } = selectedCandidate;
|
|
84503
86068
|
const selectedPackage = selectInstalledPackage(selectedCandidate);
|
|
84504
86069
|
const candidateInstalledPath = selectedPackage.installedPackagePath;
|
|
84505
|
-
const candidateExists =
|
|
86070
|
+
const candidateExists = existsSync44(candidateInstalledPath);
|
|
84506
86071
|
const resolvedFallback = candidateExists ? null : resolveInstalledPackageJsonPath();
|
|
84507
86072
|
const installedPackagePath = resolvedFallback?.packageJsonPath ?? candidateInstalledPath;
|
|
84508
86073
|
const resolvedPackageName = resolvedFallback?.packageName ?? selectedPackage.packageName;
|
|
@@ -84541,7 +86106,7 @@ var defaultDeps5 = {
|
|
|
84541
86106
|
function isConfigValid(configPath) {
|
|
84542
86107
|
if (!configPath)
|
|
84543
86108
|
return true;
|
|
84544
|
-
if (!
|
|
86109
|
+
if (!existsSync45(configPath))
|
|
84545
86110
|
return false;
|
|
84546
86111
|
try {
|
|
84547
86112
|
parseJsonc(readFileSync31(configPath, "utf-8"));
|
|
@@ -84667,29 +86232,29 @@ async function checkSystem(deps = defaultDeps5) {
|
|
|
84667
86232
|
|
|
84668
86233
|
// src/cli/doctor/checks/config.ts
|
|
84669
86234
|
import { readFileSync as readFileSync34 } from "fs";
|
|
84670
|
-
import { join as
|
|
86235
|
+
import { join as join53 } from "path";
|
|
84671
86236
|
init_shared();
|
|
84672
86237
|
init_plugin_identity();
|
|
84673
86238
|
|
|
84674
86239
|
// src/cli/doctor/checks/model-resolution-cache.ts
|
|
84675
86240
|
init_shared();
|
|
84676
|
-
import { existsSync as
|
|
84677
|
-
import { homedir as
|
|
84678
|
-
import { join as
|
|
86241
|
+
import { existsSync as existsSync46, readFileSync as readFileSync32 } from "fs";
|
|
86242
|
+
import { homedir as homedir13 } from "os";
|
|
86243
|
+
import { join as join50 } from "path";
|
|
84679
86244
|
function getUserConfigDir2() {
|
|
84680
86245
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
84681
86246
|
if (xdgConfig)
|
|
84682
|
-
return
|
|
84683
|
-
return
|
|
86247
|
+
return join50(xdgConfig, "opencode");
|
|
86248
|
+
return join50(homedir13(), ".config", "opencode");
|
|
84684
86249
|
}
|
|
84685
86250
|
function loadCustomProviderNames() {
|
|
84686
86251
|
const configDir = getUserConfigDir2();
|
|
84687
86252
|
const candidatePaths = [
|
|
84688
|
-
|
|
84689
|
-
|
|
86253
|
+
join50(configDir, "opencode.json"),
|
|
86254
|
+
join50(configDir, "opencode.jsonc")
|
|
84690
86255
|
];
|
|
84691
86256
|
for (const configPath of candidatePaths) {
|
|
84692
|
-
if (!
|
|
86257
|
+
if (!existsSync46(configPath))
|
|
84693
86258
|
continue;
|
|
84694
86259
|
try {
|
|
84695
86260
|
const content = readFileSync32(configPath, "utf-8");
|
|
@@ -84702,9 +86267,9 @@ function loadCustomProviderNames() {
|
|
|
84702
86267
|
return [];
|
|
84703
86268
|
}
|
|
84704
86269
|
function loadAvailableModelsFromCache() {
|
|
84705
|
-
const cacheFile =
|
|
86270
|
+
const cacheFile = join50(getOpenCodeCacheDir(), "models.json");
|
|
84706
86271
|
const customProviders = loadCustomProviderNames();
|
|
84707
|
-
if (!
|
|
86272
|
+
if (!existsSync46(cacheFile)) {
|
|
84708
86273
|
if (customProviders.length > 0) {
|
|
84709
86274
|
return { providers: customProviders, modelCount: 0, cacheExists: true };
|
|
84710
86275
|
}
|
|
@@ -84736,8 +86301,8 @@ init_model_capabilities2();
|
|
|
84736
86301
|
init_shared();
|
|
84737
86302
|
init_plugin_identity();
|
|
84738
86303
|
import { readFileSync as readFileSync33 } from "fs";
|
|
84739
|
-
import { join as
|
|
84740
|
-
var PROJECT_CONFIG_DIR =
|
|
86304
|
+
import { join as join51 } from "path";
|
|
86305
|
+
var PROJECT_CONFIG_DIR = join51(process.cwd(), ".opencode");
|
|
84741
86306
|
function loadOmoConfig() {
|
|
84742
86307
|
const projectDetected = detectPluginConfigFile(PROJECT_CONFIG_DIR, {
|
|
84743
86308
|
basenames: [CONFIG_BASENAME],
|
|
@@ -84769,7 +86334,7 @@ function loadOmoConfig() {
|
|
|
84769
86334
|
|
|
84770
86335
|
// src/cli/doctor/checks/model-resolution-details.ts
|
|
84771
86336
|
init_shared();
|
|
84772
|
-
import { join as
|
|
86337
|
+
import { join as join52 } from "path";
|
|
84773
86338
|
|
|
84774
86339
|
// src/cli/doctor/checks/model-resolution-variant.ts
|
|
84775
86340
|
function formatModelWithVariant(model, variant) {
|
|
@@ -84811,7 +86376,7 @@ function formatCapabilityResolutionLabel(mode) {
|
|
|
84811
86376
|
}
|
|
84812
86377
|
function buildModelResolutionDetails(options) {
|
|
84813
86378
|
const details = [];
|
|
84814
|
-
const cacheFile =
|
|
86379
|
+
const cacheFile = join52(getOpenCodeCacheDir(), "models.json");
|
|
84815
86380
|
details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
|
|
84816
86381
|
details.push("");
|
|
84817
86382
|
if (options.available.cacheExists) {
|
|
@@ -84966,7 +86531,7 @@ async function checkModels() {
|
|
|
84966
86531
|
}
|
|
84967
86532
|
|
|
84968
86533
|
// src/cli/doctor/checks/config.ts
|
|
84969
|
-
var PROJECT_CONFIG_DIR2 =
|
|
86534
|
+
var PROJECT_CONFIG_DIR2 = join53(process.cwd(), ".opencode");
|
|
84970
86535
|
function findConfigPath() {
|
|
84971
86536
|
const projectConfig = detectPluginConfigFile(PROJECT_CONFIG_DIR2, {
|
|
84972
86537
|
basenames: [CONFIG_BASENAME],
|
|
@@ -85092,27 +86657,27 @@ async function checkConfig() {
|
|
|
85092
86657
|
}
|
|
85093
86658
|
|
|
85094
86659
|
// src/cli/doctor/checks/dependencies.ts
|
|
85095
|
-
import { existsSync as
|
|
86660
|
+
import { existsSync as existsSync47 } from "fs";
|
|
85096
86661
|
import { createRequire as createRequire2 } from "module";
|
|
85097
|
-
import { dirname as
|
|
86662
|
+
import { dirname as dirname22, join as join55 } from "path";
|
|
85098
86663
|
|
|
85099
86664
|
// src/hooks/comment-checker/downloader.ts
|
|
85100
|
-
import { join as
|
|
85101
|
-
import { homedir as
|
|
86665
|
+
import { join as join54 } from "path";
|
|
86666
|
+
import { homedir as homedir14, tmpdir as tmpdir3 } from "os";
|
|
85102
86667
|
init_binary_downloader();
|
|
85103
86668
|
init_logger();
|
|
85104
86669
|
init_plugin_identity();
|
|
85105
86670
|
var DEBUG = process.env.COMMENT_CHECKER_DEBUG === "1";
|
|
85106
|
-
var DEBUG_FILE =
|
|
86671
|
+
var DEBUG_FILE = join54(tmpdir3(), "comment-checker-debug.log");
|
|
85107
86672
|
function getCacheDir2() {
|
|
85108
86673
|
if (process.platform === "win32") {
|
|
85109
86674
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
85110
|
-
const base2 = localAppData ||
|
|
85111
|
-
return
|
|
86675
|
+
const base2 = localAppData || join54(homedir14(), "AppData", "Local");
|
|
86676
|
+
return join54(base2, CACHE_DIR_NAME, "bin");
|
|
85112
86677
|
}
|
|
85113
86678
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
85114
|
-
const base = xdgCache ||
|
|
85115
|
-
return
|
|
86679
|
+
const base = xdgCache || join54(homedir14(), ".cache");
|
|
86680
|
+
return join54(base, CACHE_DIR_NAME, "bin");
|
|
85116
86681
|
}
|
|
85117
86682
|
function getBinaryName() {
|
|
85118
86683
|
return process.platform === "win32" ? "comment-checker.exe" : "comment-checker";
|
|
@@ -85176,15 +86741,15 @@ async function checkAstGrepNapi() {
|
|
|
85176
86741
|
path: null
|
|
85177
86742
|
};
|
|
85178
86743
|
} catch {
|
|
85179
|
-
const { existsSync:
|
|
85180
|
-
const { join:
|
|
85181
|
-
const { homedir:
|
|
86744
|
+
const { existsSync: existsSync48 } = await import("fs");
|
|
86745
|
+
const { join: join56 } = await import("path");
|
|
86746
|
+
const { homedir: homedir15 } = await import("os");
|
|
85182
86747
|
const pathsToCheck = [
|
|
85183
|
-
|
|
85184
|
-
|
|
86748
|
+
join56(homedir15(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
|
|
86749
|
+
join56(process.cwd(), "node_modules", "@ast-grep", "napi")
|
|
85185
86750
|
];
|
|
85186
86751
|
for (const napiPath of pathsToCheck) {
|
|
85187
|
-
if (
|
|
86752
|
+
if (existsSync48(napiPath)) {
|
|
85188
86753
|
return {
|
|
85189
86754
|
name: "AST-Grep NAPI",
|
|
85190
86755
|
required: false,
|
|
@@ -85209,8 +86774,8 @@ function findCommentCheckerPackageBinary() {
|
|
|
85209
86774
|
try {
|
|
85210
86775
|
const require2 = createRequire2(import.meta.url);
|
|
85211
86776
|
const pkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
|
|
85212
|
-
const binaryPath =
|
|
85213
|
-
if (
|
|
86777
|
+
const binaryPath = join55(dirname22(pkgPath), "bin", binaryName);
|
|
86778
|
+
if (existsSync47(binaryPath))
|
|
85214
86779
|
return binaryPath;
|
|
85215
86780
|
} catch {}
|
|
85216
86781
|
return null;
|
|
@@ -85343,11 +86908,11 @@ async function getGhCliInfo() {
|
|
|
85343
86908
|
|
|
85344
86909
|
// src/cli/doctor/checks/tools-lsp.ts
|
|
85345
86910
|
import { readFileSync as readFileSync35 } from "fs";
|
|
85346
|
-
import { join as
|
|
86911
|
+
import { join as join56 } from "path";
|
|
85347
86912
|
|
|
85348
86913
|
// src/mcp/lsp.ts
|
|
85349
|
-
import { existsSync as
|
|
85350
|
-
import { dirname as
|
|
86914
|
+
import { existsSync as existsSync48 } from "fs";
|
|
86915
|
+
import { dirname as dirname23, resolve as resolve12 } from "path";
|
|
85351
86916
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
85352
86917
|
|
|
85353
86918
|
// src/mcp/cli-suffix.ts
|
|
@@ -85360,66 +86925,6 @@ function hasCliSuffix(candidatePath, suffix) {
|
|
|
85360
86925
|
|
|
85361
86926
|
// src/mcp/runtime-executable.ts
|
|
85362
86927
|
import { basename as basename8 } from "path";
|
|
85363
|
-
|
|
85364
|
-
// src/shared/bun-which-shim.ts
|
|
85365
|
-
import { accessSync as accessSync4, constants as constants7 } from "fs";
|
|
85366
|
-
import { delimiter as delimiter2, join as join50 } from "path";
|
|
85367
|
-
var runtime3 = globalThis;
|
|
85368
|
-
var IS_BUN2 = typeof runtime3.Bun !== "undefined";
|
|
85369
|
-
function isUnsafeCommandName(commandName) {
|
|
85370
|
-
if (commandName.includes("/") || commandName.includes("\\"))
|
|
85371
|
-
return true;
|
|
85372
|
-
if (commandName === "." || commandName === ".." || commandName.includes(".."))
|
|
85373
|
-
return true;
|
|
85374
|
-
if (/^[a-zA-Z]:/.test(commandName))
|
|
85375
|
-
return true;
|
|
85376
|
-
if (commandName.includes("\x00"))
|
|
85377
|
-
return true;
|
|
85378
|
-
return false;
|
|
85379
|
-
}
|
|
85380
|
-
function isExecutable2(filePath) {
|
|
85381
|
-
try {
|
|
85382
|
-
accessSync4(filePath, constants7.X_OK);
|
|
85383
|
-
return true;
|
|
85384
|
-
} catch {
|
|
85385
|
-
return false;
|
|
85386
|
-
}
|
|
85387
|
-
}
|
|
85388
|
-
function resolvePathValue() {
|
|
85389
|
-
if (process.platform === "win32")
|
|
85390
|
-
return process.env.Path ?? process.env.PATH;
|
|
85391
|
-
return process.env.PATH;
|
|
85392
|
-
}
|
|
85393
|
-
function getWindowsCandidates(commandName) {
|
|
85394
|
-
if (process.platform !== "win32")
|
|
85395
|
-
return [commandName];
|
|
85396
|
-
return [commandName, `${commandName}.exe`, `${commandName}.cmd`, `${commandName}.bat`, `${commandName}.com`];
|
|
85397
|
-
}
|
|
85398
|
-
function bunWhich(commandName) {
|
|
85399
|
-
if (!commandName)
|
|
85400
|
-
return null;
|
|
85401
|
-
if (isUnsafeCommandName(commandName))
|
|
85402
|
-
return null;
|
|
85403
|
-
if (IS_BUN2)
|
|
85404
|
-
return runtime3.Bun?.which(commandName) ?? null;
|
|
85405
|
-
const pathValue = resolvePathValue();
|
|
85406
|
-
if (!pathValue)
|
|
85407
|
-
return null;
|
|
85408
|
-
const pathEntries = pathValue.split(delimiter2).filter((pathEntry) => pathEntry.length > 0);
|
|
85409
|
-
if (pathEntries.length === 0)
|
|
85410
|
-
return null;
|
|
85411
|
-
const candidateNames = getWindowsCandidates(commandName);
|
|
85412
|
-
for (const pathEntry of pathEntries) {
|
|
85413
|
-
for (const candidateName of candidateNames) {
|
|
85414
|
-
const candidatePath = join50(pathEntry, candidateName);
|
|
85415
|
-
if (isExecutable2(candidatePath))
|
|
85416
|
-
return candidatePath;
|
|
85417
|
-
}
|
|
85418
|
-
}
|
|
85419
|
-
return null;
|
|
85420
|
-
}
|
|
85421
|
-
|
|
85422
|
-
// src/mcp/runtime-executable.ts
|
|
85423
86928
|
var NODE_EXECUTABLE_NAMES = new Set(["node", "node.exe"]);
|
|
85424
86929
|
function isUnsafeCommandName2(commandName) {
|
|
85425
86930
|
if (commandName.length === 0)
|
|
@@ -85481,9 +86986,9 @@ var LSP_BOOTSTRAP_SCRIPT = [
|
|
|
85481
86986
|
"finish(run(process.execPath, [dist, 'mcp'], 'inherit'))"
|
|
85482
86987
|
].join(";");
|
|
85483
86988
|
function addAncestorCommandCandidates(startDirectory, target, seenPaths, pathExists, resolveExecutable) {
|
|
85484
|
-
let currentDirectory =
|
|
86989
|
+
let currentDirectory = resolve12(startDirectory);
|
|
85485
86990
|
while (true) {
|
|
85486
|
-
const distCliPath =
|
|
86991
|
+
const distCliPath = resolve12(currentDirectory, SUBMODULE_REL, DIST_CLI_REL);
|
|
85487
86992
|
if (!seenPaths.has(distCliPath)) {
|
|
85488
86993
|
const runtime4 = resolveJavaScriptRuntime(resolveExecutable);
|
|
85489
86994
|
seenPaths.add(distCliPath);
|
|
@@ -85494,7 +86999,7 @@ function addAncestorCommandCandidates(startDirectory, target, seenPaths, pathExi
|
|
|
85494
86999
|
exists: runtime4.available && pathExists(distCliPath)
|
|
85495
87000
|
});
|
|
85496
87001
|
}
|
|
85497
|
-
const sourceCliPath =
|
|
87002
|
+
const sourceCliPath = resolve12(currentDirectory, SUBMODULE_REL, SOURCE_CLI_REL);
|
|
85498
87003
|
if (!seenPaths.has(sourceCliPath)) {
|
|
85499
87004
|
const runtime4 = resolveExecutable("bun");
|
|
85500
87005
|
seenPaths.add(sourceCliPath);
|
|
@@ -85505,7 +87010,7 @@ function addAncestorCommandCandidates(startDirectory, target, seenPaths, pathExi
|
|
|
85505
87010
|
exists: runtime4.available && pathExists(sourceCliPath)
|
|
85506
87011
|
});
|
|
85507
87012
|
}
|
|
85508
|
-
const parentDirectory =
|
|
87013
|
+
const parentDirectory = resolve12(currentDirectory, "..");
|
|
85509
87014
|
if (parentDirectory === currentDirectory) {
|
|
85510
87015
|
return;
|
|
85511
87016
|
}
|
|
@@ -85514,13 +87019,13 @@ function addAncestorCommandCandidates(startDirectory, target, seenPaths, pathExi
|
|
|
85514
87019
|
}
|
|
85515
87020
|
function getModuleDirectory(moduleUrl) {
|
|
85516
87021
|
try {
|
|
85517
|
-
return
|
|
87022
|
+
return dirname23(fileURLToPath3(moduleUrl));
|
|
85518
87023
|
} catch {
|
|
85519
87024
|
return null;
|
|
85520
87025
|
}
|
|
85521
87026
|
}
|
|
85522
87027
|
function findBootstrapRoot(candidates, pathExists) {
|
|
85523
|
-
return candidates.find((candidate) => pathExists(
|
|
87028
|
+
return candidates.find((candidate) => pathExists(resolve12(candidate.root, "package.json")))?.root ?? process.cwd();
|
|
85524
87029
|
}
|
|
85525
87030
|
function resolveJavaScriptRuntime(resolveExecutable) {
|
|
85526
87031
|
const node = resolveExecutable("node");
|
|
@@ -85534,12 +87039,12 @@ function createBootstrapCandidate(root, resolveExecutable) {
|
|
|
85534
87039
|
return {
|
|
85535
87040
|
command: [runtime4.command, "-e", LSP_BOOTSTRAP_SCRIPT, root, git.command, npm.command, bun.command],
|
|
85536
87041
|
root,
|
|
85537
|
-
path:
|
|
87042
|
+
path: resolve12(root, SUBMODULE_REL, DIST_CLI_REL),
|
|
85538
87043
|
exists: runtime4.available && git.available && npm.available
|
|
85539
87044
|
};
|
|
85540
87045
|
}
|
|
85541
87046
|
function resolveLspCommand(options = {}) {
|
|
85542
|
-
const pathExists = options.exists ??
|
|
87047
|
+
const pathExists = options.exists ?? existsSync48;
|
|
85543
87048
|
const resolveExecutable = options.resolveExecutable ?? resolveRuntimeExecutable;
|
|
85544
87049
|
const candidates = [];
|
|
85545
87050
|
const seenPaths = new Set;
|
|
@@ -85589,7 +87094,7 @@ function readOmoConfig(configDirectory) {
|
|
|
85589
87094
|
}
|
|
85590
87095
|
function isLspMcpDisabled(options) {
|
|
85591
87096
|
const userConfigDirectory = options.configDirectory ?? getOpenCodeConfigDir({ binary: "opencode" });
|
|
85592
|
-
const projectConfigDirectory =
|
|
87097
|
+
const projectConfigDirectory = join56(options.cwd ?? process.cwd(), ".opencode");
|
|
85593
87098
|
const userConfig = readOmoConfig(userConfigDirectory);
|
|
85594
87099
|
const projectConfig = readOmoConfig(projectConfigDirectory);
|
|
85595
87100
|
const disabledMcps = new Set([
|
|
@@ -85608,21 +87113,21 @@ function getInstalledLspServers(options = {}) {
|
|
|
85608
87113
|
|
|
85609
87114
|
// src/cli/doctor/checks/tools-mcp.ts
|
|
85610
87115
|
init_shared();
|
|
85611
|
-
import { existsSync as
|
|
85612
|
-
import { homedir as
|
|
85613
|
-
import { join as
|
|
87116
|
+
import { existsSync as existsSync49, readFileSync as readFileSync36 } from "fs";
|
|
87117
|
+
import { homedir as homedir15 } from "os";
|
|
87118
|
+
import { join as join57 } from "path";
|
|
85614
87119
|
var BUILTIN_MCP_SERVERS = ["websearch", "context7", "grep_app", "lsp", "ast_grep"];
|
|
85615
87120
|
function getMcpConfigPaths() {
|
|
85616
87121
|
return [
|
|
85617
|
-
|
|
85618
|
-
|
|
85619
|
-
|
|
87122
|
+
join57(homedir15(), ".claude", ".mcp.json"),
|
|
87123
|
+
join57(process.cwd(), ".mcp.json"),
|
|
87124
|
+
join57(process.cwd(), ".claude", ".mcp.json")
|
|
85620
87125
|
];
|
|
85621
87126
|
}
|
|
85622
87127
|
function loadUserMcpConfig() {
|
|
85623
87128
|
const servers = {};
|
|
85624
87129
|
for (const configPath of getMcpConfigPaths()) {
|
|
85625
|
-
if (!
|
|
87130
|
+
if (!existsSync49(configPath))
|
|
85626
87131
|
continue;
|
|
85627
87132
|
try {
|
|
85628
87133
|
const content = readFileSync36(configPath, "utf-8");
|
|
@@ -85779,10 +87284,10 @@ async function probeBinary(cmd, args) {
|
|
|
85779
87284
|
|
|
85780
87285
|
// src/features/team-mode/team-registry/paths.ts
|
|
85781
87286
|
init_logger();
|
|
85782
|
-
import { homedir as
|
|
87287
|
+
import { homedir as homedir16 } from "os";
|
|
85783
87288
|
import path14 from "path";
|
|
85784
87289
|
function resolveBaseDir(config2) {
|
|
85785
|
-
return config2.base_dir ?? path14.join(
|
|
87290
|
+
return config2.base_dir ?? path14.join(homedir16(), ".omo");
|
|
85786
87291
|
}
|
|
85787
87292
|
|
|
85788
87293
|
// src/cli/doctor/checks/team-mode.ts
|
|
@@ -85849,22 +87354,57 @@ async function pathExists(dir) {
|
|
|
85849
87354
|
|
|
85850
87355
|
// src/cli/doctor/checks/tui-plugin-config.ts
|
|
85851
87356
|
init_shared();
|
|
85852
|
-
import { existsSync as
|
|
85853
|
-
import { join as
|
|
87357
|
+
import { existsSync as existsSync50, readFileSync as readFileSync38 } from "fs";
|
|
87358
|
+
import { join as join58 } from "path";
|
|
85854
87359
|
var TUI_SUBPATH = "tui";
|
|
85855
|
-
|
|
85856
|
-
|
|
85857
|
-
return false;
|
|
87360
|
+
var TUI_EXPORT_SUBPATH = `./${TUI_SUBPATH}`;
|
|
87361
|
+
function fileEntryPackageJsonPath(entry) {
|
|
85858
87362
|
let path16 = entry.slice("file:".length);
|
|
85859
87363
|
if (path16.startsWith("//"))
|
|
85860
87364
|
path16 = path16.slice(2);
|
|
87365
|
+
return join58(path16, "package.json");
|
|
87366
|
+
}
|
|
87367
|
+
function packageJsonExportsTui(pkgJsonPath) {
|
|
87368
|
+
if (!existsSync50(pkgJsonPath))
|
|
87369
|
+
return null;
|
|
85861
87370
|
try {
|
|
85862
|
-
const
|
|
85863
|
-
if (
|
|
87371
|
+
const parsed = JSON.parse(readFileSync38(pkgJsonPath, "utf-8"));
|
|
87372
|
+
if (parsed.exports === undefined)
|
|
87373
|
+
return null;
|
|
87374
|
+
if (typeof parsed.exports === "string")
|
|
87375
|
+
return false;
|
|
87376
|
+
if (parsed.exports == null || typeof parsed.exports !== "object" || Array.isArray(parsed.exports))
|
|
87377
|
+
return null;
|
|
87378
|
+
return Object.hasOwn(parsed.exports, TUI_EXPORT_SUBPATH);
|
|
87379
|
+
} catch (error51) {
|
|
87380
|
+
return null;
|
|
87381
|
+
}
|
|
87382
|
+
}
|
|
87383
|
+
function packageNameFromServerEntry(entry) {
|
|
87384
|
+
if (entry === PLUGIN_NAME || entry.startsWith(`${PLUGIN_NAME}@`))
|
|
87385
|
+
return PLUGIN_NAME;
|
|
87386
|
+
if (entry === LEGACY_PLUGIN_NAME || entry.startsWith(`${LEGACY_PLUGIN_NAME}@`))
|
|
87387
|
+
return LEGACY_PLUGIN_NAME;
|
|
87388
|
+
return null;
|
|
87389
|
+
}
|
|
87390
|
+
function packageExportsTuiForServerEntry(entry) {
|
|
87391
|
+
if (entry.startsWith("file:"))
|
|
87392
|
+
return packageJsonExportsTui(fileEntryPackageJsonPath(entry));
|
|
87393
|
+
const packageName = packageNameFromServerEntry(entry);
|
|
87394
|
+
if (packageName === null)
|
|
87395
|
+
return null;
|
|
87396
|
+
return packageJsonExportsTui(join58(getOpenCodeConfigDir({ binary: "opencode" }), "node_modules", packageName, "package.json"));
|
|
87397
|
+
}
|
|
87398
|
+
function isOurFilePluginEntry(entry) {
|
|
87399
|
+
if (!entry.startsWith("file:"))
|
|
87400
|
+
return false;
|
|
87401
|
+
try {
|
|
87402
|
+
const pkgJsonPath = fileEntryPackageJsonPath(entry);
|
|
87403
|
+
if (!existsSync50(pkgJsonPath))
|
|
85864
87404
|
return false;
|
|
85865
87405
|
const parsed = JSON.parse(readFileSync38(pkgJsonPath, "utf-8"));
|
|
85866
87406
|
return typeof parsed.name === "string" && ACCEPTED_PACKAGE_NAMES.includes(parsed.name);
|
|
85867
|
-
} catch {
|
|
87407
|
+
} catch (error51) {
|
|
85868
87408
|
return false;
|
|
85869
87409
|
}
|
|
85870
87410
|
}
|
|
@@ -85878,41 +87418,56 @@ function isServerPluginEntry(entry) {
|
|
|
85878
87418
|
return false;
|
|
85879
87419
|
}
|
|
85880
87420
|
function isTuiPluginEntry(entry) {
|
|
87421
|
+
if (isNamedTuiPluginEntry(entry))
|
|
87422
|
+
return true;
|
|
87423
|
+
if (entry.startsWith("file:") && isOurFilePluginEntry(entry))
|
|
87424
|
+
return true;
|
|
87425
|
+
return false;
|
|
87426
|
+
}
|
|
87427
|
+
function isNamedTuiPluginEntry(entry) {
|
|
85881
87428
|
const canonicalPrefix = `${PLUGIN_NAME}/${TUI_SUBPATH}`;
|
|
85882
87429
|
const legacyPrefix = `${LEGACY_PLUGIN_NAME}/${TUI_SUBPATH}`;
|
|
85883
87430
|
if (entry === canonicalPrefix || entry.startsWith(`${canonicalPrefix}@`))
|
|
85884
87431
|
return true;
|
|
85885
87432
|
if (entry === legacyPrefix || entry.startsWith(`${legacyPrefix}@`))
|
|
85886
87433
|
return true;
|
|
85887
|
-
if (entry.startsWith("file:") && isOurFilePluginEntry(entry))
|
|
85888
|
-
return true;
|
|
85889
87434
|
return false;
|
|
85890
87435
|
}
|
|
85891
87436
|
function detectServerPluginRegistration() {
|
|
85892
87437
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
85893
|
-
const configPath =
|
|
87438
|
+
const configPath = existsSync50(paths.configJsonc) ? paths.configJsonc : existsSync50(paths.configJson) ? paths.configJson : null;
|
|
85894
87439
|
if (!configPath) {
|
|
85895
|
-
return { registered: false, configPath: null };
|
|
87440
|
+
return { registered: false, configPath: null, packageExportsTui: null };
|
|
85896
87441
|
}
|
|
85897
87442
|
try {
|
|
85898
87443
|
const parsed = parseJsonc(readFileSync38(configPath, "utf-8"));
|
|
85899
87444
|
const plugins = parsed.plugin ?? [];
|
|
85900
|
-
|
|
85901
|
-
|
|
85902
|
-
|
|
87445
|
+
const serverEntry = plugins.find(isServerPluginEntry);
|
|
87446
|
+
return {
|
|
87447
|
+
registered: serverEntry !== undefined,
|
|
87448
|
+
configPath,
|
|
87449
|
+
packageExportsTui: serverEntry === undefined ? null : packageExportsTuiForServerEntry(serverEntry)
|
|
87450
|
+
};
|
|
87451
|
+
} catch (error51) {
|
|
87452
|
+
return { registered: false, configPath, packageExportsTui: null };
|
|
85903
87453
|
}
|
|
85904
87454
|
}
|
|
85905
87455
|
function detectTuiPluginRegistration() {
|
|
85906
|
-
const tuiJsonPath =
|
|
85907
|
-
if (!
|
|
85908
|
-
return { registered: false, configPath: tuiJsonPath, exists: false };
|
|
87456
|
+
const tuiJsonPath = join58(getOpenCodeConfigDir({ binary: "opencode" }), "tui.json");
|
|
87457
|
+
if (!existsSync50(tuiJsonPath)) {
|
|
87458
|
+
return { registered: false, configPath: tuiJsonPath, exists: false, hasNamedTuiEntry: false };
|
|
85909
87459
|
}
|
|
85910
87460
|
try {
|
|
85911
87461
|
const parsed = parseJsonc(readFileSync38(tuiJsonPath, "utf-8"));
|
|
85912
87462
|
const plugins = parsed.plugin ?? [];
|
|
85913
|
-
return {
|
|
85914
|
-
|
|
85915
|
-
|
|
87463
|
+
return {
|
|
87464
|
+
registered: plugins.some(isTuiPluginEntry),
|
|
87465
|
+
configPath: tuiJsonPath,
|
|
87466
|
+
exists: true,
|
|
87467
|
+
hasNamedTuiEntry: plugins.some(isNamedTuiPluginEntry)
|
|
87468
|
+
};
|
|
87469
|
+
} catch (error51) {
|
|
87470
|
+
return { registered: false, configPath: tuiJsonPath, exists: true, hasNamedTuiEntry: false };
|
|
85916
87471
|
}
|
|
85917
87472
|
}
|
|
85918
87473
|
async function checkTuiPluginConfig() {
|
|
@@ -85934,7 +87489,32 @@ async function checkTuiPluginConfig() {
|
|
|
85934
87489
|
issues
|
|
85935
87490
|
};
|
|
85936
87491
|
}
|
|
87492
|
+
if (server2.registered && server2.packageExportsTui === false && tui.hasNamedTuiEntry) {
|
|
87493
|
+
issues.push({
|
|
87494
|
+
title: "TUI plugin entry in tui.json is unresolvable",
|
|
87495
|
+
description: `The installed ${PLUGIN_NAME} package registered in opencode.json does not export ` + `"${TUI_EXPORT_SUBPATH}", but tui.json contains "${PLUGIN_NAME}/${TUI_SUBPATH}". ` + "OpenCode TUI may try to resolve that package subpath as a GitHub repository and fail.",
|
|
87496
|
+
fix: `Remove "${PLUGIN_NAME}/${TUI_SUBPATH}" or "${LEGACY_PLUGIN_NAME}/${TUI_SUBPATH}" from the "plugin" array in ${tui.configPath}.`,
|
|
87497
|
+
affects: ["TUI startup", "plugin loading"],
|
|
87498
|
+
severity: "warning"
|
|
87499
|
+
});
|
|
87500
|
+
return {
|
|
87501
|
+
name,
|
|
87502
|
+
status: "warn",
|
|
87503
|
+
message: "TUI plugin entry in tui.json is unresolvable",
|
|
87504
|
+
details: details.length > 0 ? details : undefined,
|
|
87505
|
+
issues
|
|
87506
|
+
};
|
|
87507
|
+
}
|
|
85937
87508
|
if (server2.registered && !tui.registered) {
|
|
87509
|
+
if (server2.packageExportsTui === false) {
|
|
87510
|
+
return {
|
|
87511
|
+
name,
|
|
87512
|
+
status: "pass",
|
|
87513
|
+
message: "Server plugin registered; TUI subpath not shipped by this package version",
|
|
87514
|
+
details: details.length > 0 ? details : undefined,
|
|
87515
|
+
issues
|
|
87516
|
+
};
|
|
87517
|
+
}
|
|
85938
87518
|
issues.push({
|
|
85939
87519
|
title: "TUI plugin entry missing from tui.json",
|
|
85940
87520
|
description: "The server plugin is registered in opencode.json, but the TUI plugin entry " + `("${PLUGIN_NAME}/${TUI_SUBPATH}") is missing from tui.json. The Roles \xB7 ` + "Models sidebar section and TUI-only commands will not appear.",
|
|
@@ -86361,11 +87941,11 @@ async function refreshModelCapabilities(options, deps = {}) {
|
|
|
86361
87941
|
|
|
86362
87942
|
// src/features/mcp-oauth/storage.ts
|
|
86363
87943
|
init_shared();
|
|
86364
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
86365
|
-
import { dirname as
|
|
87944
|
+
import { chmodSync as chmodSync2, existsSync as existsSync51, mkdirSync as mkdirSync13, readFileSync as readFileSync39, renameSync as renameSync6, unlinkSync as unlinkSync8, writeFileSync as writeFileSync10 } from "fs";
|
|
87945
|
+
import { dirname as dirname24, join as join59 } from "path";
|
|
86366
87946
|
var STORAGE_FILE_NAME = "mcp-oauth.json";
|
|
86367
87947
|
function getMcpOauthStoragePath() {
|
|
86368
|
-
return
|
|
87948
|
+
return join59(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
|
|
86369
87949
|
}
|
|
86370
87950
|
function normalizeHost2(serverHost) {
|
|
86371
87951
|
let host = serverHost.trim();
|
|
@@ -86402,7 +87982,7 @@ function buildKey(serverHost, resource) {
|
|
|
86402
87982
|
}
|
|
86403
87983
|
function readStore() {
|
|
86404
87984
|
const filePath = getMcpOauthStoragePath();
|
|
86405
|
-
if (!
|
|
87985
|
+
if (!existsSync51(filePath)) {
|
|
86406
87986
|
return null;
|
|
86407
87987
|
}
|
|
86408
87988
|
try {
|
|
@@ -86415,8 +87995,8 @@ function readStore() {
|
|
|
86415
87995
|
function writeStore(store2) {
|
|
86416
87996
|
const filePath = getMcpOauthStoragePath();
|
|
86417
87997
|
try {
|
|
86418
|
-
const dir =
|
|
86419
|
-
if (!
|
|
87998
|
+
const dir = dirname24(filePath);
|
|
87999
|
+
if (!existsSync51(dir)) {
|
|
86420
88000
|
mkdirSync13(dir, { recursive: true });
|
|
86421
88001
|
}
|
|
86422
88002
|
const tempPath = `${filePath}.tmp.${Date.now()}`;
|
|
@@ -86453,7 +88033,7 @@ function deleteToken(serverHost, resource) {
|
|
|
86453
88033
|
if (Object.keys(store2).length === 0) {
|
|
86454
88034
|
try {
|
|
86455
88035
|
const filePath = getMcpOauthStoragePath();
|
|
86456
|
-
if (
|
|
88036
|
+
if (existsSync51(filePath)) {
|
|
86457
88037
|
unlinkSync8(filePath);
|
|
86458
88038
|
}
|
|
86459
88039
|
return true;
|
|
@@ -86622,7 +88202,7 @@ async function getOrRegisterClient(options) {
|
|
|
86622
88202
|
}
|
|
86623
88203
|
}
|
|
86624
88204
|
function parseRegistrationResponse(data) {
|
|
86625
|
-
if (!
|
|
88205
|
+
if (!isRecord17(data))
|
|
86626
88206
|
return null;
|
|
86627
88207
|
const clientId = data.client_id;
|
|
86628
88208
|
if (typeof clientId !== "string" || clientId.length === 0)
|
|
@@ -86633,7 +88213,7 @@ function parseRegistrationResponse(data) {
|
|
|
86633
88213
|
}
|
|
86634
88214
|
return { clientId };
|
|
86635
88215
|
}
|
|
86636
|
-
function
|
|
88216
|
+
function isRecord17(value) {
|
|
86637
88217
|
return typeof value === "object" && value !== null;
|
|
86638
88218
|
}
|
|
86639
88219
|
|
|
@@ -86647,13 +88227,13 @@ async function findAvailablePort2(startPort = DEFAULT_PORT) {
|
|
|
86647
88227
|
|
|
86648
88228
|
// src/features/mcp-oauth/oauth-authorization-flow.ts
|
|
86649
88229
|
import { spawn as spawn2 } from "child_process";
|
|
86650
|
-
import { createHash as
|
|
88230
|
+
import { createHash as createHash5, randomBytes as randomBytes2 } from "crypto";
|
|
86651
88231
|
import { createServer as createServer2 } from "http";
|
|
86652
88232
|
function generateCodeVerifier() {
|
|
86653
88233
|
return randomBytes2(32).toString("base64url");
|
|
86654
88234
|
}
|
|
86655
88235
|
function generateCodeChallenge(verifier) {
|
|
86656
|
-
return
|
|
88236
|
+
return createHash5("sha256").update(verifier).digest("base64url");
|
|
86657
88237
|
}
|
|
86658
88238
|
function buildAuthorizationUrl(authorizationEndpoint, options) {
|
|
86659
88239
|
const url2 = new URL(authorizationEndpoint);
|
|
@@ -86673,7 +88253,7 @@ function buildAuthorizationUrl(authorizationEndpoint, options) {
|
|
|
86673
88253
|
}
|
|
86674
88254
|
var CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
|
|
86675
88255
|
function startCallbackServer(port) {
|
|
86676
|
-
return new Promise((
|
|
88256
|
+
return new Promise((resolve13, reject) => {
|
|
86677
88257
|
let timeoutId;
|
|
86678
88258
|
const server2 = createServer2((request, response) => {
|
|
86679
88259
|
clearTimeout(timeoutId);
|
|
@@ -86699,7 +88279,7 @@ function startCallbackServer(port) {
|
|
|
86699
88279
|
response.writeHead(200, { "content-type": "text/html" });
|
|
86700
88280
|
response.end("<html><body><h1>Authorization successful. You can close this tab.</h1></body></html>");
|
|
86701
88281
|
server2.close();
|
|
86702
|
-
|
|
88282
|
+
resolve13({ code, state: state2 });
|
|
86703
88283
|
});
|
|
86704
88284
|
timeoutId = setTimeout(() => {
|
|
86705
88285
|
server2.close();
|
|
@@ -87033,7 +88613,7 @@ function createMcpOAuthCommand() {
|
|
|
87033
88613
|
}
|
|
87034
88614
|
|
|
87035
88615
|
// src/cli/boulder/boulder.ts
|
|
87036
|
-
import { existsSync as
|
|
88616
|
+
import { existsSync as existsSync52 } from "fs";
|
|
87037
88617
|
|
|
87038
88618
|
// src/cli/boulder/formatter.ts
|
|
87039
88619
|
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
@@ -87170,10 +88750,10 @@ async function boulder(options) {
|
|
|
87170
88750
|
const boulderFilePath = getBoulderFilePath(directory);
|
|
87171
88751
|
const state2 = readBoulderState(directory);
|
|
87172
88752
|
if (!state2) {
|
|
87173
|
-
const message =
|
|
88753
|
+
const message = existsSync52(boulderFilePath) ? formatReadErrorMessage(options.json) : formatNoBoulderMessage(options.json);
|
|
87174
88754
|
process.stderr.write(`${message}
|
|
87175
88755
|
`);
|
|
87176
|
-
return
|
|
88756
|
+
return existsSync52(boulderFilePath) ? 2 : 1;
|
|
87177
88757
|
}
|
|
87178
88758
|
const works = getBoulderWorks(state2);
|
|
87179
88759
|
const filteredWorks = options.workId ? works.filter((work) => work.work_id === options.workId) : works;
|
|
@@ -87189,11 +88769,86 @@ async function boulder(options) {
|
|
|
87189
88769
|
`);
|
|
87190
88770
|
return 0;
|
|
87191
88771
|
}
|
|
88772
|
+
// src/cli/codex-ulw-loop.ts
|
|
88773
|
+
import { spawn as spawn3 } from "child_process";
|
|
88774
|
+
import { existsSync as existsSync53, readdirSync as readdirSync7, realpathSync as realpathSync7 } from "fs";
|
|
88775
|
+
import { homedir as homedir17 } from "os";
|
|
88776
|
+
import { join as join60 } from "path";
|
|
88777
|
+
function resolveCodexUlwLoopCommand(input = {}) {
|
|
88778
|
+
const env = input.env ?? process.env;
|
|
88779
|
+
const homeDir = input.homeDir ?? homedir17();
|
|
88780
|
+
const localBin = resolveLocalOmoBin(env, homeDir, input.currentExecutablePaths ?? [process.argv[1]].filter((value) => typeof value === "string"));
|
|
88781
|
+
if (localBin !== null)
|
|
88782
|
+
return { executable: localBin, argsPrefix: ["ulw-loop"] };
|
|
88783
|
+
const componentCli = resolveNewestCachedUlwLoopCli(env.CODEX_HOME ?? join60(homeDir, ".codex"));
|
|
88784
|
+
if (componentCli !== null)
|
|
88785
|
+
return { executable: process.execPath, argsPrefix: [componentCli] };
|
|
88786
|
+
return null;
|
|
88787
|
+
}
|
|
88788
|
+
async function codexUlwLoop(args) {
|
|
88789
|
+
const command = resolveCodexUlwLoopCommand();
|
|
88790
|
+
if (command === null) {
|
|
88791
|
+
console.error("Codex ulw-loop is not installed. Run: npx lazycodex-ai@latest install --no-tui");
|
|
88792
|
+
return 1;
|
|
88793
|
+
}
|
|
88794
|
+
return new Promise((resolve13) => {
|
|
88795
|
+
const child = spawn3(command.executable, [...command.argsPrefix, ...args], { stdio: "inherit" });
|
|
88796
|
+
child.on("error", (error51) => {
|
|
88797
|
+
console.error(error51.message);
|
|
88798
|
+
resolve13(1);
|
|
88799
|
+
});
|
|
88800
|
+
child.on("close", (code) => resolve13(code ?? 1));
|
|
88801
|
+
});
|
|
88802
|
+
}
|
|
88803
|
+
function resolveLocalOmoBin(env, homeDir, currentExecutablePaths) {
|
|
88804
|
+
const candidates = [
|
|
88805
|
+
env.CODEX_LOCAL_BIN_DIR ? join60(env.CODEX_LOCAL_BIN_DIR, "omo") : undefined,
|
|
88806
|
+
join60(homeDir, ".local", "bin", "omo"),
|
|
88807
|
+
join60(homeDir, ".codex", "bin", "omo")
|
|
88808
|
+
].filter((value) => typeof value === "string");
|
|
88809
|
+
return candidates.find((candidate) => existsSync53(candidate) && !isCurrentExecutable(candidate, currentExecutablePaths)) ?? null;
|
|
88810
|
+
}
|
|
88811
|
+
function isCurrentExecutable(candidate, currentExecutablePaths) {
|
|
88812
|
+
const candidateRealPath = realpathOrSelf(candidate);
|
|
88813
|
+
return currentExecutablePaths.some((currentPath) => realpathOrSelf(currentPath) === candidateRealPath);
|
|
88814
|
+
}
|
|
88815
|
+
function realpathOrSelf(path16) {
|
|
88816
|
+
try {
|
|
88817
|
+
return realpathSync7(path16);
|
|
88818
|
+
} catch {
|
|
88819
|
+
return path16;
|
|
88820
|
+
}
|
|
88821
|
+
}
|
|
88822
|
+
function resolveNewestCachedUlwLoopCli(codexHome) {
|
|
88823
|
+
const versionsRoot = join60(codexHome, "plugins", "cache", "sisyphuslabs", "omo");
|
|
88824
|
+
if (!existsSync53(versionsRoot))
|
|
88825
|
+
return null;
|
|
88826
|
+
const versions2 = readdirSync7(versionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareVersionNames).reverse();
|
|
88827
|
+
for (const version3 of versions2) {
|
|
88828
|
+
const candidate = join60(versionsRoot, version3, "components", "ulw-loop", "dist", "cli.js");
|
|
88829
|
+
if (existsSync53(candidate))
|
|
88830
|
+
return candidate;
|
|
88831
|
+
}
|
|
88832
|
+
return null;
|
|
88833
|
+
}
|
|
88834
|
+
function compareVersionNames(left, right) {
|
|
88835
|
+
const leftParts = left.split(".").map((part) => Number.parseInt(part, 10));
|
|
88836
|
+
const rightParts = right.split(".").map((part) => Number.parseInt(part, 10));
|
|
88837
|
+
const length = Math.max(leftParts.length, rightParts.length);
|
|
88838
|
+
for (let index = 0;index < length; index += 1) {
|
|
88839
|
+
const leftValue = Number.isFinite(leftParts[index] ?? Number.NaN) ? leftParts[index] ?? 0 : 0;
|
|
88840
|
+
const rightValue = Number.isFinite(rightParts[index] ?? Number.NaN) ? rightParts[index] ?? 0 : 0;
|
|
88841
|
+
if (leftValue !== rightValue)
|
|
88842
|
+
return leftValue - rightValue;
|
|
88843
|
+
}
|
|
88844
|
+
return left.localeCompare(right);
|
|
88845
|
+
}
|
|
88846
|
+
|
|
87192
88847
|
// src/cli/cli-program.ts
|
|
87193
88848
|
var VERSION2 = package_default.version;
|
|
87194
88849
|
var program2 = new Command;
|
|
87195
88850
|
function resolveInstallArgs(options, invocationName = process.env.OMO_INVOCATION_NAME) {
|
|
87196
|
-
const defaultPlatform = invocationName === "lazycodex" ? "codex" : undefined;
|
|
88851
|
+
const defaultPlatform = invocationName === "lazycodex" || invocationName === "lazycodex-ai" ? "codex" : undefined;
|
|
87197
88852
|
return {
|
|
87198
88853
|
tui: options.tui !== false,
|
|
87199
88854
|
claude: options.claude,
|
|
@@ -87214,7 +88869,7 @@ program2.name("oh-my-opencode").description("The ultimate OpenCode plugin - mult
|
|
|
87214
88869
|
program2.command("install").alias("setup").description("Install and configure oh-my-opencode with interactive setup").option("--no-tui", "Run in non-interactive mode (requires all options)").option("--claude <value>", "Claude subscription: no, yes, max20").option("--openai <value>", "OpenAI/ChatGPT subscription: no, yes (default: no)").option("--gemini <value>", "Gemini integration: no, yes").option("--copilot <value>", "GitHub Copilot subscription: no, yes").addOption(new Option("--platform <platform>", "Install target platform: opencode, codex, both").choices(["opencode", "codex", "both"])).option("--opencode-zen <value>", "OpenCode Zen access: no, yes (default: no)").option("--zai-coding-plan <value>", "Z.ai Coding Plan subscription: no, yes (default: no)").option("--kimi-for-coding <value>", "Kimi For Coding subscription: no, yes (default: no)").option("--opencode-go <value>", "OpenCode Go subscription: no, yes (default: no)").option("--vercel-ai-gateway <value>", "Vercel AI Gateway: no, yes (default: no)").option("--codex-autonomous", "Configure Codex with approval never, full filesystem access, and network enabled").option("--no-codex-autonomous", "Leave existing Codex permission settings unchanged").option("--skip-auth", "Skip authentication setup hints").addHelpText("after", `
|
|
87215
88870
|
Examples:
|
|
87216
88871
|
$ bunx oh-my-opencode install
|
|
87217
|
-
$
|
|
88872
|
+
$ npx lazycodex-ai install --no-tui
|
|
87218
88873
|
$ bunx oh-my-opencode install --no-tui --platform=both --claude=max20 --openai=yes --gemini=yes --copilot=no
|
|
87219
88874
|
$ omo install --platform=codex --codex-autonomous
|
|
87220
88875
|
$ bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=yes --opencode-zen=yes
|
|
@@ -87234,6 +88889,7 @@ Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi > Verce
|
|
|
87234
88889
|
const exitCode = await install(args);
|
|
87235
88890
|
process.exit(exitCode);
|
|
87236
88891
|
});
|
|
88892
|
+
configureCleanupCommand(program2);
|
|
87237
88893
|
program2.command("run <message>").allowUnknownOption().passThroughOptions().description("Run opencode with todo/background task completion enforcement").option("-a, --agent <name>", "Agent to use (default: from CLI/env/config, fallback: Sisyphus)").option("-m, --model <provider/model>", "Model override (e.g., anthropic/claude-sonnet-4)").option("-d, --directory <path>", "Working directory").option("-p, --port <port>", "Server port (attaches if port already in use)", parseInt).option("--attach <url>", "Attach to existing opencode server URL").option("--on-complete <command>", "Shell command to run after completion").option("--json", "Output structured JSON result to stdout").option("--no-timestamp", "Disable timestamp prefix in run output").option("--verbose", "Show full event stream (default: messages/tools only)").option("--session-id <id>", "Resume existing session instead of creating new one").addHelpText("after", `
|
|
87238
88894
|
Examples:
|
|
87239
88895
|
$ bunx oh-my-opencode run "Fix the bug in index.ts"
|
|
@@ -87332,6 +88988,10 @@ program2.command("boulder").description("Show boulder progress, elapsed time, an
|
|
|
87332
88988
|
});
|
|
87333
88989
|
process.exit(exitCode);
|
|
87334
88990
|
});
|
|
88991
|
+
program2.command("ulw-loop [args...]").allowUnknownOption().passThroughOptions().description("Run the Codex LazyCodex ulw-loop CLI").action(async (args = []) => {
|
|
88992
|
+
const exitCode = await codexUlwLoop(args);
|
|
88993
|
+
process.exit(exitCode);
|
|
88994
|
+
});
|
|
87335
88995
|
program2.addCommand(createMcpOAuthCommand());
|
|
87336
88996
|
function runCli() {
|
|
87337
88997
|
program2.parse();
|