oh-my-opencode 4.5.12 → 4.6.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/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/index.js +1837 -450
- 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-mcp.d.ts +1 -0
- package/dist/cli/install-codex/codex-config-permissions.d.ts +1 -0
- package/dist/cli/install-codex/codex-config-reasoning.d.ts +1 -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-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/builtin-skills/skills/debugging.d.ts +2 -0
- package/dist/features/builtin-skills/skills/index.d.ts +1 -0
- package/dist/hooks/index.d.ts +0 -1
- package/dist/index.js +267 -114
- 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/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/package.json +22 -17
- package/packages/git-bash-mcp/dist/cli.js +367 -0
- 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/windows-git-bash.md +10 -0
- 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 +5 -4
- package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +22 -0
- package/packages/omo-codex/plugin/components/ultrawork/README.md +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/agents/codex-ultrawork-reviewer.toml +1 -0
- package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +8 -7
- package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +31 -5
- 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 +27 -205
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +230 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +102 -5
- package/packages/omo-codex/plugin/hooks/hooks.json +24 -2
- 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/build-bundled-mcp-runtimes.mjs +16 -1
- package/packages/omo-codex/plugin/scripts/build-components.mjs +2 -1
- package/packages/omo-codex/plugin/scripts/sync-hook-status-messages.mjs +87 -0
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +27 -2
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +20 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +27 -205
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +230 -0
- package/packages/omo-codex/plugin/test/aggregate.test.mjs +23 -8
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +56 -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/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 +66 -0
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +32 -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 +36 -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/mcp-runtime-cache.mjs +5 -1
- 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 +14 -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-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 +62 -0
- package/packages/omo-codex/scripts/install-config.test.mjs +206 -0
- package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +129 -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/review-work/SKILL.md +27 -2
- package/packages/shared-skills/skills/start-work/SKILL.md +20 -0
- package/dist/hooks/context-window-monitor.d.ts +0 -19
package/dist/cli/index.js
CHANGED
|
@@ -51711,7 +51711,7 @@ async function withDispatchTimeout(operation, dispatchTimeoutMs, operationName)
|
|
|
51711
51711
|
}
|
|
51712
51712
|
}
|
|
51713
51713
|
}
|
|
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;
|
|
51714
|
+
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
51715
|
|
|
51716
51716
|
// src/shared/prompt-async-gate/pending-tool-turn.ts
|
|
51717
51717
|
function getPromptQuery(input) {
|
|
@@ -51808,6 +51808,42 @@ var init_pending_tool_turn = __esm(() => {
|
|
|
51808
51808
|
init_message_inspection_error();
|
|
51809
51809
|
});
|
|
51810
51810
|
|
|
51811
|
+
// src/shared/prompt-async-gate/recent-dispatches.ts
|
|
51812
|
+
function recentDispatchKey(sessionID, dedupeKey) {
|
|
51813
|
+
return `${sessionID}\x00${dedupeKey}`;
|
|
51814
|
+
}
|
|
51815
|
+
function pruneRecentPromptDispatches(now = Date.now()) {
|
|
51816
|
+
for (const [key, dispatch] of recentPromptDispatches) {
|
|
51817
|
+
if (dispatch.expiresAt <= now) {
|
|
51818
|
+
recentPromptDispatches.delete(key);
|
|
51819
|
+
}
|
|
51820
|
+
}
|
|
51821
|
+
}
|
|
51822
|
+
function getRecentPromptDispatch(sessionID, dedupeKey) {
|
|
51823
|
+
pruneRecentPromptDispatches();
|
|
51824
|
+
return recentPromptDispatches.get(recentDispatchKey(sessionID, dedupeKey));
|
|
51825
|
+
}
|
|
51826
|
+
function rememberRecentPromptDispatch(args) {
|
|
51827
|
+
pruneRecentPromptDispatches();
|
|
51828
|
+
if (args.holdMs <= 0) {
|
|
51829
|
+
return;
|
|
51830
|
+
}
|
|
51831
|
+
recentPromptDispatches.set(recentDispatchKey(args.sessionID, args.dedupeKey), {
|
|
51832
|
+
source: args.source,
|
|
51833
|
+
expiresAt: Date.now() + args.holdMs
|
|
51834
|
+
});
|
|
51835
|
+
log("[prompt-async-gate] remembered semantic prompt dispatch", {
|
|
51836
|
+
sessionID: args.sessionID,
|
|
51837
|
+
source: args.source,
|
|
51838
|
+
holdMs: args.holdMs
|
|
51839
|
+
});
|
|
51840
|
+
}
|
|
51841
|
+
var recentPromptDispatches;
|
|
51842
|
+
var init_recent_dispatches = __esm(() => {
|
|
51843
|
+
init_logger();
|
|
51844
|
+
recentPromptDispatches = new Map;
|
|
51845
|
+
});
|
|
51846
|
+
|
|
51811
51847
|
// src/shared/prompt-async-gate/reservations.ts
|
|
51812
51848
|
function setExpiredReservationHandler(handler) {
|
|
51813
51849
|
expiredReservationHandler = handler;
|
|
@@ -51869,6 +51905,7 @@ async function dispatchAfterSessionIdle(args) {
|
|
|
51869
51905
|
dedupeKey,
|
|
51870
51906
|
settleMs,
|
|
51871
51907
|
postDispatchHoldMs,
|
|
51908
|
+
semanticDedupeHoldMs,
|
|
51872
51909
|
dispatchTimeoutMs,
|
|
51873
51910
|
checkStatus,
|
|
51874
51911
|
checkToolState,
|
|
@@ -51926,10 +51963,25 @@ async function dispatchAfterSessionIdle(args) {
|
|
|
51926
51963
|
log(`[prompt-async-gate] ${sessionName} dispatching`, { sessionID, source });
|
|
51927
51964
|
dispatchAttempted = true;
|
|
51928
51965
|
const response = await withDispatchTimeout(dispatch(input), dispatchTimeoutMs, `[prompt-async-gate] ${sessionName} dispatch`);
|
|
51966
|
+
rememberRecentPromptDispatch({
|
|
51967
|
+
sessionID,
|
|
51968
|
+
dedupeKey,
|
|
51969
|
+
source,
|
|
51970
|
+
holdMs: semanticDedupeHoldMs
|
|
51971
|
+
});
|
|
51929
51972
|
log(`[prompt-async-gate] ${sessionName} dispatched`, { sessionID, source });
|
|
51930
51973
|
return { status: "dispatched", response };
|
|
51931
51974
|
} catch (error) {
|
|
51932
|
-
|
|
51975
|
+
if (dispatchAttempted) {
|
|
51976
|
+
rememberRecentPromptDispatch({
|
|
51977
|
+
sessionID,
|
|
51978
|
+
dedupeKey,
|
|
51979
|
+
source,
|
|
51980
|
+
holdMs: semanticDedupeHoldMs
|
|
51981
|
+
});
|
|
51982
|
+
}
|
|
51983
|
+
const errorText = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
51984
|
+
log(`[prompt-async-gate] ${sessionName} failed`, { sessionID, source, error: errorText });
|
|
51933
51985
|
return { status: "failed", error, dispatchAttempted };
|
|
51934
51986
|
} finally {
|
|
51935
51987
|
finishPromptReservation(sessionID, reservation, dispatchAttempted, postDispatchHoldMs);
|
|
@@ -51939,6 +51991,7 @@ var init_session_idle_dispatch = __esm(() => {
|
|
|
51939
51991
|
init_logger();
|
|
51940
51992
|
init_session_idle_settle();
|
|
51941
51993
|
init_pending_tool_turn();
|
|
51994
|
+
init_recent_dispatches();
|
|
51942
51995
|
init_reservations();
|
|
51943
51996
|
});
|
|
51944
51997
|
|
|
@@ -52038,6 +52091,7 @@ async function drainPromptQueue(sessionID, awaitedEntry) {
|
|
|
52038
52091
|
dedupeKey: entry.dedupeKey,
|
|
52039
52092
|
settleMs: entry.settleMs,
|
|
52040
52093
|
postDispatchHoldMs: entry.postDispatchHoldMs,
|
|
52094
|
+
semanticDedupeHoldMs: entry.semanticDedupeHoldMs,
|
|
52041
52095
|
dispatchTimeoutMs: entry.dispatchTimeoutMs,
|
|
52042
52096
|
checkStatus: entry.checkStatus,
|
|
52043
52097
|
checkToolState: entry.checkToolState,
|
|
@@ -52121,27 +52175,119 @@ var init_queue = __esm(() => {
|
|
|
52121
52175
|
});
|
|
52122
52176
|
});
|
|
52123
52177
|
|
|
52124
|
-
// src/shared/prompt-async-gate.ts
|
|
52178
|
+
// src/shared/prompt-async-gate/semantic-dedupe.ts
|
|
52179
|
+
import { createHash } from "crypto";
|
|
52180
|
+
function isPlainRecord(value) {
|
|
52181
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
52182
|
+
return false;
|
|
52183
|
+
}
|
|
52184
|
+
const prototype = Object.getPrototypeOf(value);
|
|
52185
|
+
return prototype === Object.prototype || prototype === null;
|
|
52186
|
+
}
|
|
52187
|
+
function canonicalizePromptInputForDedupe(key, value, seen = new WeakSet, depth = 0) {
|
|
52188
|
+
if (key === "signal") {
|
|
52189
|
+
return "[AbortSignal]";
|
|
52190
|
+
}
|
|
52191
|
+
if (typeof value === "function") {
|
|
52192
|
+
return `[Function:${value.name}]`;
|
|
52193
|
+
}
|
|
52194
|
+
if (depth > MAX_PROMPT_DEDUPE_DEPTH) {
|
|
52195
|
+
return "[MaxDepth]";
|
|
52196
|
+
}
|
|
52197
|
+
if (Array.isArray(value)) {
|
|
52198
|
+
if (seen.has(value)) {
|
|
52199
|
+
return "[Circular]";
|
|
52200
|
+
}
|
|
52201
|
+
seen.add(value);
|
|
52202
|
+
try {
|
|
52203
|
+
return value.map((entry) => canonicalizePromptInputForDedupe("", entry, seen, depth + 1));
|
|
52204
|
+
} finally {
|
|
52205
|
+
seen.delete(value);
|
|
52206
|
+
}
|
|
52207
|
+
}
|
|
52208
|
+
if (!isPlainRecord(value)) {
|
|
52209
|
+
return value;
|
|
52210
|
+
}
|
|
52211
|
+
if (seen.has(value)) {
|
|
52212
|
+
return "[Circular]";
|
|
52213
|
+
}
|
|
52214
|
+
seen.add(value);
|
|
52215
|
+
try {
|
|
52216
|
+
const canonicalEntries = [];
|
|
52217
|
+
for (const entryKey of Object.keys(value).sort()) {
|
|
52218
|
+
canonicalEntries.push([
|
|
52219
|
+
entryKey,
|
|
52220
|
+
canonicalizePromptInputForDedupe(entryKey, value[entryKey], seen, depth + 1)
|
|
52221
|
+
]);
|
|
52222
|
+
}
|
|
52223
|
+
return Object.fromEntries(canonicalEntries);
|
|
52224
|
+
} finally {
|
|
52225
|
+
seen.delete(value);
|
|
52226
|
+
}
|
|
52227
|
+
}
|
|
52228
|
+
function isContinuationTextPartLike(value) {
|
|
52229
|
+
if (!isPlainRecord(value)) {
|
|
52230
|
+
return false;
|
|
52231
|
+
}
|
|
52232
|
+
if (value.type !== "text" || typeof value.text !== "string") {
|
|
52233
|
+
return false;
|
|
52234
|
+
}
|
|
52235
|
+
if (!hasInternalInitiatorMarker(value.text)) {
|
|
52236
|
+
return false;
|
|
52237
|
+
}
|
|
52238
|
+
if (!isPlainRecord(value.metadata)) {
|
|
52239
|
+
return false;
|
|
52240
|
+
}
|
|
52241
|
+
return value.metadata.compaction_continue === true;
|
|
52242
|
+
}
|
|
52243
|
+
function hasContinuationPromptIntent(input) {
|
|
52244
|
+
if (!isPlainRecord(input) || !isPlainRecord(input.body) || !Array.isArray(input.body.parts)) {
|
|
52245
|
+
return false;
|
|
52246
|
+
}
|
|
52247
|
+
return input.body.parts.some((part) => isContinuationTextPartLike(part));
|
|
52248
|
+
}
|
|
52249
|
+
function normalizePromptInputForSemanticDedupe(input) {
|
|
52250
|
+
if (hasContinuationPromptIntent(input)) {
|
|
52251
|
+
return {
|
|
52252
|
+
__omo_internal_intent: "continuation"
|
|
52253
|
+
};
|
|
52254
|
+
}
|
|
52255
|
+
return canonicalizePromptInputForDedupe("", input);
|
|
52256
|
+
}
|
|
52125
52257
|
function stringifyPromptInputForDedupe(input) {
|
|
52126
52258
|
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
|
-
});
|
|
52259
|
+
const serialized = JSON.stringify(normalizePromptInputForSemanticDedupe(input));
|
|
52136
52260
|
return serialized ?? String(input);
|
|
52137
|
-
} catch {
|
|
52138
|
-
|
|
52261
|
+
} catch (error) {
|
|
52262
|
+
const errorTag = error instanceof Error ? error.name : String(error);
|
|
52263
|
+
return `${String(input)}:[unserializable:${errorTag}]`;
|
|
52139
52264
|
}
|
|
52140
52265
|
}
|
|
52141
|
-
function
|
|
52266
|
+
function createSemanticPromptDedupeKey(input) {
|
|
52142
52267
|
const fingerprint = stringifyPromptInputForDedupe(input);
|
|
52143
|
-
|
|
52268
|
+
const digest = createHash("sha256").update(fingerprint, "utf8").digest("hex");
|
|
52269
|
+
return `semantic:${digest}`;
|
|
52270
|
+
}
|
|
52271
|
+
function coalesceRecentSemanticPromptDispatch(args) {
|
|
52272
|
+
const recentDispatch = getRecentPromptDispatch(args.sessionID, args.dedupeKey);
|
|
52273
|
+
if (!recentDispatch) {
|
|
52274
|
+
return;
|
|
52275
|
+
}
|
|
52276
|
+
log("[prompt-async-gate] prompt coalesced with recent semantic dispatch", {
|
|
52277
|
+
sessionID: args.sessionID,
|
|
52278
|
+
source: args.source,
|
|
52279
|
+
queuedBy: recentDispatch.source
|
|
52280
|
+
});
|
|
52281
|
+
return { status: "queued", queuedBy: recentDispatch.source, position: 0 };
|
|
52144
52282
|
}
|
|
52283
|
+
var MAX_PROMPT_DEDUPE_DEPTH = 64;
|
|
52284
|
+
var init_semantic_dedupe = __esm(() => {
|
|
52285
|
+
init_internal_initiator_marker();
|
|
52286
|
+
init_logger();
|
|
52287
|
+
init_recent_dispatches();
|
|
52288
|
+
});
|
|
52289
|
+
|
|
52290
|
+
// src/shared/prompt-async-gate.ts
|
|
52145
52291
|
function hasObjectSessionPath(input) {
|
|
52146
52292
|
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
52293
|
}
|
|
@@ -52171,9 +52317,10 @@ async function dispatchInternalPrompt(args) {
|
|
|
52171
52317
|
source,
|
|
52172
52318
|
settleMs = DEFAULT_SESSION_IDLE_SETTLE_MS
|
|
52173
52319
|
} = args;
|
|
52174
|
-
const dedupeKey = args.dedupeKey ??
|
|
52320
|
+
const dedupeKey = args.dedupeKey ?? createSemanticPromptDedupeKey(input);
|
|
52175
52321
|
const queueRetryMs = args.queueRetryMs ?? DEFAULT_PROMPT_QUEUE_RETRY_MS;
|
|
52176
52322
|
const postDispatchHoldMs = args.postDispatchHoldMs ?? DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS;
|
|
52323
|
+
const semanticDedupeHoldMs = args.semanticDedupeHoldMs ?? (postDispatchHoldMs > 0 ? DEFAULT_PROMPT_SEMANTIC_DEDUPE_HOLD_MS : 0);
|
|
52177
52324
|
const dispatchTimeoutMs = args.dispatchTimeoutMs ?? DEFAULT_PROMPT_DISPATCH_TIMEOUT_MS;
|
|
52178
52325
|
const sessionName = args.mode === "async" ? "promptAsync" : "prompt";
|
|
52179
52326
|
const dispatch = (() => {
|
|
@@ -52206,6 +52353,10 @@ async function dispatchInternalPrompt(args) {
|
|
|
52206
52353
|
if (queuedBy !== undefined || isPromptQueueDraining(sessionID)) {
|
|
52207
52354
|
return { status: "reserved", reservedBy: queuedBy ?? source };
|
|
52208
52355
|
}
|
|
52356
|
+
const recentDispatchResult2 = coalesceRecentSemanticPromptDispatch({ sessionID, dedupeKey, source });
|
|
52357
|
+
if (recentDispatchResult2) {
|
|
52358
|
+
return recentDispatchResult2;
|
|
52359
|
+
}
|
|
52209
52360
|
return dispatchAfterSessionIdle({
|
|
52210
52361
|
sessionName,
|
|
52211
52362
|
client,
|
|
@@ -52215,6 +52366,7 @@ async function dispatchInternalPrompt(args) {
|
|
|
52215
52366
|
dedupeKey,
|
|
52216
52367
|
settleMs,
|
|
52217
52368
|
postDispatchHoldMs,
|
|
52369
|
+
semanticDedupeHoldMs,
|
|
52218
52370
|
dispatchTimeoutMs,
|
|
52219
52371
|
checkStatus: args.checkStatus !== false,
|
|
52220
52372
|
checkToolState: args.checkToolState !== false,
|
|
@@ -52222,6 +52374,10 @@ async function dispatchInternalPrompt(args) {
|
|
|
52222
52374
|
});
|
|
52223
52375
|
}
|
|
52224
52376
|
if (args.queue !== false) {
|
|
52377
|
+
const recentDispatchResult2 = coalesceRecentSemanticPromptDispatch({ sessionID, dedupeKey, source });
|
|
52378
|
+
if (recentDispatchResult2) {
|
|
52379
|
+
return recentDispatchResult2;
|
|
52380
|
+
}
|
|
52225
52381
|
return enqueueInternalPrompt({
|
|
52226
52382
|
id: nextPromptQueueID(),
|
|
52227
52383
|
sessionID,
|
|
@@ -52232,6 +52388,7 @@ async function dispatchInternalPrompt(args) {
|
|
|
52232
52388
|
dedupeKey,
|
|
52233
52389
|
settleMs,
|
|
52234
52390
|
postDispatchHoldMs,
|
|
52391
|
+
semanticDedupeHoldMs,
|
|
52235
52392
|
dispatchTimeoutMs,
|
|
52236
52393
|
queueRetryMs,
|
|
52237
52394
|
checkStatus: args.checkStatus !== false,
|
|
@@ -52239,6 +52396,10 @@ async function dispatchInternalPrompt(args) {
|
|
|
52239
52396
|
dispatch: async (_dispatchInput) => dispatchWithPathCompatibility(dispatch, input)
|
|
52240
52397
|
});
|
|
52241
52398
|
}
|
|
52399
|
+
const recentDispatchResult = coalesceRecentSemanticPromptDispatch({ sessionID, dedupeKey, source });
|
|
52400
|
+
if (recentDispatchResult) {
|
|
52401
|
+
return recentDispatchResult;
|
|
52402
|
+
}
|
|
52242
52403
|
return dispatchAfterSessionIdle({
|
|
52243
52404
|
sessionName,
|
|
52244
52405
|
client,
|
|
@@ -52248,6 +52409,7 @@ async function dispatchInternalPrompt(args) {
|
|
|
52248
52409
|
dedupeKey,
|
|
52249
52410
|
settleMs,
|
|
52250
52411
|
postDispatchHoldMs,
|
|
52412
|
+
semanticDedupeHoldMs,
|
|
52251
52413
|
dispatchTimeoutMs,
|
|
52252
52414
|
checkStatus: args.checkStatus !== false,
|
|
52253
52415
|
checkToolState: args.checkToolState !== false,
|
|
@@ -52261,8 +52423,10 @@ var init_prompt_async_gate = __esm(() => {
|
|
|
52261
52423
|
init_logger();
|
|
52262
52424
|
init_session_idle_settle();
|
|
52263
52425
|
init_queue();
|
|
52426
|
+
init_recent_dispatches();
|
|
52264
52427
|
init_reservations();
|
|
52265
52428
|
init_session_idle_dispatch();
|
|
52429
|
+
init_semantic_dedupe();
|
|
52266
52430
|
});
|
|
52267
52431
|
|
|
52268
52432
|
// src/shared/prompt-failure-classifier.ts
|
|
@@ -54105,7 +54269,7 @@ var init_config_manager = __esm(() => {
|
|
|
54105
54269
|
});
|
|
54106
54270
|
|
|
54107
54271
|
// node_modules/.bun/posthog-node@5.35.3/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
54108
|
-
import { dirname as
|
|
54272
|
+
import { dirname as dirname14, posix, sep as sep3 } from "path";
|
|
54109
54273
|
function createModulerModifier() {
|
|
54110
54274
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
54111
54275
|
return async (frames) => {
|
|
@@ -54114,7 +54278,7 @@ function createModulerModifier() {
|
|
|
54114
54278
|
return frames;
|
|
54115
54279
|
};
|
|
54116
54280
|
}
|
|
54117
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ?
|
|
54281
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname14(process.argv[1]) : process.cwd(), isWindows = sep3 === "\\") {
|
|
54118
54282
|
const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
|
|
54119
54283
|
return (filename) => {
|
|
54120
54284
|
if (!filename)
|
|
@@ -56919,14 +57083,14 @@ async function addSourceContext(frames) {
|
|
|
56919
57083
|
return frames;
|
|
56920
57084
|
}
|
|
56921
57085
|
function getContextLinesFromFile(path6, ranges, output) {
|
|
56922
|
-
return new Promise((
|
|
57086
|
+
return new Promise((resolve9) => {
|
|
56923
57087
|
const stream = createReadStream(path6);
|
|
56924
57088
|
const lineReaded = createInterface({
|
|
56925
57089
|
input: stream
|
|
56926
57090
|
});
|
|
56927
57091
|
function destroyStreamAndResolve() {
|
|
56928
57092
|
stream.destroy();
|
|
56929
|
-
|
|
57093
|
+
resolve9();
|
|
56930
57094
|
}
|
|
56931
57095
|
let lineNumber = 0;
|
|
56932
57096
|
let currentRangeIndex = 0;
|
|
@@ -58398,9 +58562,9 @@ var init_client = __esm(() => {
|
|
|
58398
58562
|
if (this.disabled || this.optedOut)
|
|
58399
58563
|
return;
|
|
58400
58564
|
if (!this._waitUntilCycle) {
|
|
58401
|
-
let
|
|
58565
|
+
let resolve9;
|
|
58402
58566
|
const promise = new Promise((r) => {
|
|
58403
|
-
|
|
58567
|
+
resolve9 = r;
|
|
58404
58568
|
});
|
|
58405
58569
|
try {
|
|
58406
58570
|
waitUntil(promise);
|
|
@@ -58408,7 +58572,7 @@ var init_client = __esm(() => {
|
|
|
58408
58572
|
return;
|
|
58409
58573
|
}
|
|
58410
58574
|
this._waitUntilCycle = {
|
|
58411
|
-
resolve:
|
|
58575
|
+
resolve: resolve9,
|
|
58412
58576
|
startedAt: Date.now(),
|
|
58413
58577
|
timer: undefined
|
|
58414
58578
|
};
|
|
@@ -58434,11 +58598,11 @@ var init_client = __esm(() => {
|
|
|
58434
58598
|
return cycle?.resolve;
|
|
58435
58599
|
}
|
|
58436
58600
|
async resolveWaitUntilFlush() {
|
|
58437
|
-
const
|
|
58601
|
+
const resolve9 = this._consumeWaitUntilCycle();
|
|
58438
58602
|
try {
|
|
58439
58603
|
await super.flush();
|
|
58440
58604
|
} catch {} finally {
|
|
58441
|
-
|
|
58605
|
+
resolve9?.();
|
|
58442
58606
|
}
|
|
58443
58607
|
}
|
|
58444
58608
|
getPersistedProperty(key) {
|
|
@@ -58538,15 +58702,15 @@ var init_client = __esm(() => {
|
|
|
58538
58702
|
return true;
|
|
58539
58703
|
if (this.featureFlagsPoller === undefined)
|
|
58540
58704
|
return false;
|
|
58541
|
-
return new Promise((
|
|
58705
|
+
return new Promise((resolve9) => {
|
|
58542
58706
|
const timeout = setTimeout(() => {
|
|
58543
58707
|
cleanup();
|
|
58544
|
-
|
|
58708
|
+
resolve9(false);
|
|
58545
58709
|
}, timeoutMs);
|
|
58546
58710
|
const cleanup = this._events.on("localEvaluationFlagsLoaded", (count) => {
|
|
58547
58711
|
clearTimeout(timeout);
|
|
58548
58712
|
cleanup();
|
|
58549
|
-
|
|
58713
|
+
resolve9(count > 0);
|
|
58550
58714
|
});
|
|
58551
58715
|
});
|
|
58552
58716
|
}
|
|
@@ -59033,13 +59197,13 @@ var init_client = __esm(() => {
|
|
|
59033
59197
|
this.context?.enter(data, options);
|
|
59034
59198
|
}
|
|
59035
59199
|
async _shutdown(shutdownTimeoutMs) {
|
|
59036
|
-
const
|
|
59200
|
+
const resolve9 = this._consumeWaitUntilCycle();
|
|
59037
59201
|
await this.featureFlagsPoller?.stopPoller(shutdownTimeoutMs);
|
|
59038
59202
|
this.errorTracking.shutdown();
|
|
59039
59203
|
try {
|
|
59040
59204
|
return await super._shutdown(shutdownTimeoutMs);
|
|
59041
59205
|
} finally {
|
|
59042
|
-
|
|
59206
|
+
resolve9?.();
|
|
59043
59207
|
}
|
|
59044
59208
|
}
|
|
59045
59209
|
async _requestRemoteConfigPayload(flagKey) {
|
|
@@ -59435,7 +59599,10 @@ var init_package = __esm(() => {
|
|
|
59435
59599
|
types: "./index.d.ts",
|
|
59436
59600
|
import: "./src/index.ts"
|
|
59437
59601
|
},
|
|
59438
|
-
"./telemetry":
|
|
59602
|
+
"./telemetry": {
|
|
59603
|
+
types: "./src/telemetry/index.ts",
|
|
59604
|
+
import: "./src/telemetry/index.ts"
|
|
59605
|
+
},
|
|
59439
59606
|
"./marketplace.json": "./marketplace.json"
|
|
59440
59607
|
},
|
|
59441
59608
|
types: "./index.d.ts",
|
|
@@ -59543,10 +59710,10 @@ var init_data_path2 = __esm(() => {
|
|
|
59543
59710
|
});
|
|
59544
59711
|
|
|
59545
59712
|
// packages/omo-codex/src/telemetry/posthog-activity-state.ts
|
|
59546
|
-
import { existsSync as
|
|
59547
|
-
import { join as
|
|
59713
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync8, readFileSync as readFileSync13 } from "fs";
|
|
59714
|
+
import { join as join29 } from "path";
|
|
59548
59715
|
function getPostHogActivityStateFilePath() {
|
|
59549
|
-
return
|
|
59716
|
+
return join29(getActivityStateDir(), POSTHOG_ACTIVITY_STATE_FILE);
|
|
59550
59717
|
}
|
|
59551
59718
|
function getUtcDayString(date) {
|
|
59552
59719
|
return date.toISOString().slice(0, 10);
|
|
@@ -59556,7 +59723,7 @@ function isPostHogActivityState(value) {
|
|
|
59556
59723
|
}
|
|
59557
59724
|
function readPostHogActivityState() {
|
|
59558
59725
|
const stateFilePath = getPostHogActivityStateFilePath();
|
|
59559
|
-
if (!
|
|
59726
|
+
if (!existsSync24(stateFilePath)) {
|
|
59560
59727
|
return {};
|
|
59561
59728
|
}
|
|
59562
59729
|
try {
|
|
@@ -59603,7 +59770,7 @@ var init_posthog_activity_state = __esm(() => {
|
|
|
59603
59770
|
});
|
|
59604
59771
|
|
|
59605
59772
|
// packages/omo-codex/src/telemetry/posthog.ts
|
|
59606
|
-
import { createHash as
|
|
59773
|
+
import { createHash as createHash3 } from "crypto";
|
|
59607
59774
|
import os4 from "os";
|
|
59608
59775
|
function resolveOsProvider() {
|
|
59609
59776
|
return osProviderOverride2 ?? os4;
|
|
@@ -59686,7 +59853,7 @@ function createPostHogClient(source, options) {
|
|
|
59686
59853
|
};
|
|
59687
59854
|
}
|
|
59688
59855
|
function getPostHogDistinctId() {
|
|
59689
|
-
return
|
|
59856
|
+
return createHash3("sha256").update(`omo-codex:${resolveOsProvider().hostname()}`).digest("hex");
|
|
59690
59857
|
}
|
|
59691
59858
|
function createCliPostHog() {
|
|
59692
59859
|
return createPostHogClient("cli", {
|
|
@@ -59910,12 +60077,12 @@ var require_isexe = __commonJS((exports2, module) => {
|
|
|
59910
60077
|
if (typeof Promise !== "function") {
|
|
59911
60078
|
throw new TypeError("callback not provided");
|
|
59912
60079
|
}
|
|
59913
|
-
return new Promise(function(
|
|
60080
|
+
return new Promise(function(resolve11, reject) {
|
|
59914
60081
|
isexe(path8, options || {}, function(er, is) {
|
|
59915
60082
|
if (er) {
|
|
59916
60083
|
reject(er);
|
|
59917
60084
|
} else {
|
|
59918
|
-
|
|
60085
|
+
resolve11(is);
|
|
59919
60086
|
}
|
|
59920
60087
|
});
|
|
59921
60088
|
});
|
|
@@ -59977,27 +60144,27 @@ var require_which = __commonJS((exports2, module) => {
|
|
|
59977
60144
|
opt = {};
|
|
59978
60145
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
59979
60146
|
const found = [];
|
|
59980
|
-
const step = (i2) => new Promise((
|
|
60147
|
+
const step = (i2) => new Promise((resolve11, reject) => {
|
|
59981
60148
|
if (i2 === pathEnv.length)
|
|
59982
|
-
return opt.all && found.length ?
|
|
60149
|
+
return opt.all && found.length ? resolve11(found) : reject(getNotFoundError(cmd));
|
|
59983
60150
|
const ppRaw = pathEnv[i2];
|
|
59984
60151
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
59985
60152
|
const pCmd = path8.join(pathPart, cmd);
|
|
59986
60153
|
const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
59987
|
-
|
|
60154
|
+
resolve11(subStep(p2, i2, 0));
|
|
59988
60155
|
});
|
|
59989
|
-
const subStep = (p2, i2, ii) => new Promise((
|
|
60156
|
+
const subStep = (p2, i2, ii) => new Promise((resolve11, reject) => {
|
|
59990
60157
|
if (ii === pathExt.length)
|
|
59991
|
-
return
|
|
60158
|
+
return resolve11(step(i2 + 1));
|
|
59992
60159
|
const ext = pathExt[ii];
|
|
59993
60160
|
isexe(p2 + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
59994
60161
|
if (!er && is) {
|
|
59995
60162
|
if (opt.all)
|
|
59996
60163
|
found.push(p2 + ext);
|
|
59997
60164
|
else
|
|
59998
|
-
return
|
|
60165
|
+
return resolve11(p2 + ext);
|
|
59999
60166
|
}
|
|
60000
|
-
return
|
|
60167
|
+
return resolve11(subStep(p2, i2, ii + 1));
|
|
60001
60168
|
});
|
|
60002
60169
|
});
|
|
60003
60170
|
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
@@ -60894,8 +61061,8 @@ var init_update_toasts = __esm(() => {
|
|
|
60894
61061
|
});
|
|
60895
61062
|
|
|
60896
61063
|
// src/hooks/auto-update-checker/hook/background-update-check.ts
|
|
60897
|
-
import { existsSync as
|
|
60898
|
-
import { join as
|
|
61064
|
+
import { existsSync as existsSync41 } from "fs";
|
|
61065
|
+
import { join as join46 } from "path";
|
|
60899
61066
|
function getCacheWorkspaceDir(deps) {
|
|
60900
61067
|
return deps.join(deps.getOpenCodeCacheDir(), "packages");
|
|
60901
61068
|
}
|
|
@@ -61013,8 +61180,8 @@ var init_background_update_check = __esm(() => {
|
|
|
61013
61180
|
init_checker();
|
|
61014
61181
|
init_update_toasts();
|
|
61015
61182
|
defaultDeps3 = {
|
|
61016
|
-
existsSync:
|
|
61017
|
-
join:
|
|
61183
|
+
existsSync: existsSync41,
|
|
61184
|
+
join: join46,
|
|
61018
61185
|
runBunInstallWithDetails,
|
|
61019
61186
|
log,
|
|
61020
61187
|
getOpenCodeCacheDir,
|
|
@@ -61173,7 +61340,7 @@ async function showSpinnerToast(ctx, version3, message) {
|
|
|
61173
61340
|
duration: frameInterval + 50
|
|
61174
61341
|
}
|
|
61175
61342
|
}).catch(() => {});
|
|
61176
|
-
await new Promise((
|
|
61343
|
+
await new Promise((resolve12) => setTimeout(resolve12, frameInterval));
|
|
61177
61344
|
}
|
|
61178
61345
|
}
|
|
61179
61346
|
var SISYPHUS_SPINNER;
|
|
@@ -61256,13 +61423,13 @@ v${latestVersion} available. Restart OpenCode to apply.` : "OpenCode is now on S
|
|
|
61256
61423
|
}
|
|
61257
61424
|
};
|
|
61258
61425
|
}
|
|
61259
|
-
var defaultDeps4,
|
|
61426
|
+
var defaultDeps4, isRecord15 = (value) => {
|
|
61260
61427
|
return typeof value === "object" && value !== null;
|
|
61261
61428
|
}, getParentID = (properties) => {
|
|
61262
|
-
if (!
|
|
61429
|
+
if (!isRecord15(properties))
|
|
61263
61430
|
return;
|
|
61264
61431
|
const { info } = properties;
|
|
61265
|
-
if (!
|
|
61432
|
+
if (!isRecord15(info))
|
|
61266
61433
|
return;
|
|
61267
61434
|
const { parentID } = info;
|
|
61268
61435
|
return typeof parentID === "string" && parentID.length > 0 ? parentID : undefined;
|
|
@@ -61326,7 +61493,7 @@ var {
|
|
|
61326
61493
|
// package.json
|
|
61327
61494
|
var package_default = {
|
|
61328
61495
|
name: "oh-my-opencode",
|
|
61329
|
-
version: "4.
|
|
61496
|
+
version: "4.6.0",
|
|
61330
61497
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
61331
61498
|
main: "./dist/index.js",
|
|
61332
61499
|
types: "dist/index.d.ts",
|
|
@@ -61335,6 +61502,7 @@ var package_default = {
|
|
|
61335
61502
|
"packages/rules-engine",
|
|
61336
61503
|
"packages/ast-grep-core",
|
|
61337
61504
|
"packages/ast-grep-mcp",
|
|
61505
|
+
"packages/git-bash-mcp",
|
|
61338
61506
|
"packages/utils",
|
|
61339
61507
|
"packages/model-core",
|
|
61340
61508
|
"packages/prompts-core",
|
|
@@ -61349,7 +61517,8 @@ var package_default = {
|
|
|
61349
61517
|
"oh-my-opencode": "bin/oh-my-opencode.js",
|
|
61350
61518
|
"oh-my-openagent": "bin/oh-my-opencode.js",
|
|
61351
61519
|
omo: "bin/oh-my-opencode.js",
|
|
61352
|
-
lazycodex: "bin/oh-my-opencode.js"
|
|
61520
|
+
lazycodex: "bin/oh-my-opencode.js",
|
|
61521
|
+
"lazycodex-ai": "bin/oh-my-opencode.js"
|
|
61353
61522
|
},
|
|
61354
61523
|
files: [
|
|
61355
61524
|
"dist",
|
|
@@ -61361,6 +61530,7 @@ var package_default = {
|
|
|
61361
61530
|
".agents/skills",
|
|
61362
61531
|
"packages/lsp-tools-mcp/dist",
|
|
61363
61532
|
"packages/ast-grep-mcp/dist",
|
|
61533
|
+
"packages/git-bash-mcp/dist",
|
|
61364
61534
|
"packages/shared-skills/package.json",
|
|
61365
61535
|
"packages/shared-skills/index.mjs",
|
|
61366
61536
|
"packages/shared-skills/skills",
|
|
@@ -61378,7 +61548,7 @@ var package_default = {
|
|
|
61378
61548
|
"./schema.json": "./dist/oh-my-opencode.schema.json"
|
|
61379
61549
|
},
|
|
61380
61550
|
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",
|
|
61551
|
+
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
61552
|
"build:lsp-tools-mcp": "npm --prefix packages/lsp-tools-mcp ci && npm --prefix packages/lsp-tools-mcp run build",
|
|
61383
61553
|
"build:node-require-shim": "bun run script/patch-node-require-shim.ts",
|
|
61384
61554
|
"build:all": "bun run build && bun run build:binaries",
|
|
@@ -61391,12 +61561,13 @@ var package_default = {
|
|
|
61391
61561
|
prepublishOnly: "bun run clean && bun run build:lsp-tools-mcp && bun run build",
|
|
61392
61562
|
"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
61563
|
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",
|
|
61564
|
+
"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
61565
|
"typecheck:script": "tsgo --noEmit -p script/tsconfig.json",
|
|
61396
61566
|
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",
|
|
61567
|
+
"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
61568
|
"test:windows-codex": "bun run test:codex",
|
|
61399
|
-
"build:ast-grep-mcp": "bun run --cwd packages/ast-grep-mcp build"
|
|
61569
|
+
"build:ast-grep-mcp": "bun run --cwd packages/ast-grep-mcp build",
|
|
61570
|
+
"build:git-bash-mcp": "bun run --cwd packages/git-bash-mcp build"
|
|
61400
61571
|
},
|
|
61401
61572
|
keywords: [
|
|
61402
61573
|
"opencode",
|
|
@@ -61439,6 +61610,7 @@ var package_default = {
|
|
|
61439
61610
|
devDependencies: {
|
|
61440
61611
|
"@oh-my-opencode/ast-grep-core": "workspace:*",
|
|
61441
61612
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
61613
|
+
"@oh-my-opencode/git-bash-mcp": "workspace:*",
|
|
61442
61614
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
61443
61615
|
"@oh-my-opencode/boulder-state": "workspace:*",
|
|
61444
61616
|
"@oh-my-opencode/comment-checker-core": "workspace:*",
|
|
@@ -61457,17 +61629,17 @@ var package_default = {
|
|
|
61457
61629
|
zod: "^4.4.3"
|
|
61458
61630
|
},
|
|
61459
61631
|
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.
|
|
61632
|
+
"oh-my-opencode-darwin-arm64": "4.6.0",
|
|
61633
|
+
"oh-my-opencode-darwin-x64": "4.6.0",
|
|
61634
|
+
"oh-my-opencode-darwin-x64-baseline": "4.6.0",
|
|
61635
|
+
"oh-my-opencode-linux-arm64": "4.6.0",
|
|
61636
|
+
"oh-my-opencode-linux-arm64-musl": "4.6.0",
|
|
61637
|
+
"oh-my-opencode-linux-x64": "4.6.0",
|
|
61638
|
+
"oh-my-opencode-linux-x64-baseline": "4.6.0",
|
|
61639
|
+
"oh-my-opencode-linux-x64-musl": "4.6.0",
|
|
61640
|
+
"oh-my-opencode-linux-x64-musl-baseline": "4.6.0",
|
|
61641
|
+
"oh-my-opencode-windows-x64": "4.6.0",
|
|
61642
|
+
"oh-my-opencode-windows-x64-baseline": "4.6.0"
|
|
61471
61643
|
},
|
|
61472
61644
|
overrides: {
|
|
61473
61645
|
hono: "^4.12.18",
|
|
@@ -61490,6 +61662,7 @@ var package_default = {
|
|
|
61490
61662
|
init_shared();
|
|
61491
61663
|
init_config_manager();
|
|
61492
61664
|
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
61665
|
+
import { createInterface as createInterface2 } from "readline/promises";
|
|
61493
61666
|
|
|
61494
61667
|
// src/cli/install-validators.ts
|
|
61495
61668
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
@@ -61517,6 +61690,9 @@ function formatConfigSummary(config) {
|
|
|
61517
61690
|
if (config.hasCodex) {
|
|
61518
61691
|
lines.push(` ${SYMBOLS.info} Codex autonomous mode: ${config.codexAutonomous ? "enabled" : "disabled"}`);
|
|
61519
61692
|
}
|
|
61693
|
+
if (!config.hasOpenCode)
|
|
61694
|
+
return lines.join(`
|
|
61695
|
+
`);
|
|
61520
61696
|
lines.push("");
|
|
61521
61697
|
const claudeDetail = config.hasClaude ? config.isMax20 ? "max20" : "standard" : undefined;
|
|
61522
61698
|
lines.push(formatProvider("Claude", config.hasClaude, claudeDetail));
|
|
@@ -61742,9 +61918,9 @@ function getUnsupportedOpenCodeVersionMessage(openCodeVersion) {
|
|
|
61742
61918
|
|
|
61743
61919
|
// src/cli/install-codex/install-codex.ts
|
|
61744
61920
|
import { homedir as homedir5 } from "os";
|
|
61745
|
-
import { join as
|
|
61746
|
-
import { existsSync as
|
|
61747
|
-
import { mkdir as mkdir6, writeFile as
|
|
61921
|
+
import { join as join30, resolve as resolve9 } from "path";
|
|
61922
|
+
import { existsSync as existsSync25 } from "fs";
|
|
61923
|
+
import { mkdir as mkdir6, writeFile as writeFile7 } from "fs/promises";
|
|
61748
61924
|
|
|
61749
61925
|
// src/cli/install-codex/codex-cache.ts
|
|
61750
61926
|
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 +61937,13 @@ var BUNDLED_MCP_RUNTIMES = [
|
|
|
61761
61937
|
destinationArg: "./components/ast-grep-mcp/dist/cli.js",
|
|
61762
61938
|
destinationDistFromPlugin: "components/ast-grep-mcp/dist"
|
|
61763
61939
|
},
|
|
61940
|
+
{
|
|
61941
|
+
label: "Git Bash MCP",
|
|
61942
|
+
sourceArg: "../../git-bash-mcp/dist/cli.js",
|
|
61943
|
+
sourceDistFromPlugin: "../../git-bash-mcp/dist",
|
|
61944
|
+
destinationArg: "./components/git-bash-mcp/dist/cli.js",
|
|
61945
|
+
destinationDistFromPlugin: "components/git-bash-mcp/dist"
|
|
61946
|
+
},
|
|
61764
61947
|
{
|
|
61765
61948
|
label: "LSP MCP",
|
|
61766
61949
|
sourceArg: "../../lsp-tools-mcp/dist/cli.js",
|
|
@@ -61956,8 +62139,10 @@ function isRecord9(value) {
|
|
|
61956
62139
|
|
|
61957
62140
|
// src/cli/install-codex/codex-cache.ts
|
|
61958
62141
|
async function installCachedPlugin(input) {
|
|
61959
|
-
|
|
61960
|
-
|
|
62142
|
+
if (input.buildSource !== false) {
|
|
62143
|
+
await maybeRunNpmInstall(input.sourcePath, input.runCommand);
|
|
62144
|
+
await maybeRunNpmBuild(input.sourcePath, input.runCommand);
|
|
62145
|
+
}
|
|
61961
62146
|
const targetPath = join22(input.codexHome, "plugins", "cache", input.marketplaceName, input.name, input.version);
|
|
61962
62147
|
await replaceDirectory(input.sourcePath, targetPath);
|
|
61963
62148
|
await rewriteCachedPackageLocalFileDependencies(targetPath, input.sourcePath);
|
|
@@ -62178,8 +62363,35 @@ function isRecord10(value) {
|
|
|
62178
62363
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
62179
62364
|
}
|
|
62180
62365
|
|
|
62366
|
+
// src/cli/install-codex/codex-package-layout.ts
|
|
62367
|
+
import { existsSync as existsSync22 } from "fs";
|
|
62368
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
62369
|
+
import { join as join23 } from "path";
|
|
62370
|
+
var PACKAGED_CODEX_INSTALLER_NAMES = new Set([
|
|
62371
|
+
"@code-yeongyu/lazycodex",
|
|
62372
|
+
"@code-yeongyu/lazycodex-ai",
|
|
62373
|
+
"lazycodex",
|
|
62374
|
+
"lazycodex-ai",
|
|
62375
|
+
"oh-my-opencode",
|
|
62376
|
+
"oh-my-openagent"
|
|
62377
|
+
]);
|
|
62378
|
+
async function shouldBuildSourcePackages(repoRoot) {
|
|
62379
|
+
if (existsSync22(join23(repoRoot, "src", "index.ts")))
|
|
62380
|
+
return true;
|
|
62381
|
+
const packageJsonPath = join23(repoRoot, "package.json");
|
|
62382
|
+
if (!existsSync22(packageJsonPath))
|
|
62383
|
+
return true;
|
|
62384
|
+
const packageJson = JSON.parse(await readFile5(packageJsonPath, "utf8"));
|
|
62385
|
+
if (!isRecord11(packageJson) || typeof packageJson.name !== "string")
|
|
62386
|
+
return true;
|
|
62387
|
+
return !PACKAGED_CODEX_INSTALLER_NAMES.has(packageJson.name);
|
|
62388
|
+
}
|
|
62389
|
+
function isRecord11(value) {
|
|
62390
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
62391
|
+
}
|
|
62392
|
+
|
|
62181
62393
|
// src/cli/install-codex/codex-config-toml.ts
|
|
62182
|
-
import { mkdir as mkdir3, readFile as
|
|
62394
|
+
import { mkdir as mkdir3, readFile as readFile6, writeFile as writeFile3 } from "fs/promises";
|
|
62183
62395
|
import { dirname as dirname12 } from "path";
|
|
62184
62396
|
|
|
62185
62397
|
// src/cli/install-codex/toml-section-editor.ts
|
|
@@ -62210,10 +62422,24 @@ function replaceOrInsertSetting(config, section, key, value) {
|
|
|
62210
62422
|
return config.slice(0, section.start) + replacement + config.slice(section.end);
|
|
62211
62423
|
}
|
|
62212
62424
|
function removeSetting(config, section, key) {
|
|
62213
|
-
const linePattern = new RegExp(
|
|
62425
|
+
const linePattern = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=.*(?:\\n|$)`, "m");
|
|
62214
62426
|
const replacement = section.text.replace(linePattern, "");
|
|
62215
62427
|
return config.slice(0, section.start) + replacement + config.slice(section.end);
|
|
62216
62428
|
}
|
|
62429
|
+
function replaceOrInsertRootSetting(config, key, value) {
|
|
62430
|
+
const sectionStart = findFirstTableStart(config);
|
|
62431
|
+
const root = config.slice(0, sectionStart);
|
|
62432
|
+
const suffix = config.slice(sectionStart);
|
|
62433
|
+
const linePattern = new RegExp(`^${escapeRegExp(key)}\\s*=.*$`, "m");
|
|
62434
|
+
const replacement = linePattern.test(root) ? root.replace(linePattern, `${key} = ${value}`) : `${root.trimEnd()}${root.trimEnd().length > 0 ? `
|
|
62435
|
+
` : ""}${key} = ${value}
|
|
62436
|
+
`;
|
|
62437
|
+
if (suffix.length === 0)
|
|
62438
|
+
return replacement;
|
|
62439
|
+
return `${replacement.trimEnd()}
|
|
62440
|
+
|
|
62441
|
+
${suffix.trimStart()}`;
|
|
62442
|
+
}
|
|
62217
62443
|
function appendBlock(config, block) {
|
|
62218
62444
|
const prefix = config.trimEnd();
|
|
62219
62445
|
return `${prefix}${prefix.length > 0 ? `
|
|
@@ -62221,6 +62447,10 @@ function appendBlock(config, block) {
|
|
|
62221
62447
|
` : ""}${block.trimEnd()}
|
|
62222
62448
|
`;
|
|
62223
62449
|
}
|
|
62450
|
+
function findFirstTableStart(config) {
|
|
62451
|
+
const match = config.match(/^[[].*$/m);
|
|
62452
|
+
return match?.index ?? config.length;
|
|
62453
|
+
}
|
|
62224
62454
|
function insertSetting(sectionText, key, value) {
|
|
62225
62455
|
const lines = sectionText.split(`
|
|
62226
62456
|
`);
|
|
@@ -62232,11 +62462,130 @@ function escapeRegExp(value) {
|
|
|
62232
62462
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
62233
62463
|
}
|
|
62234
62464
|
|
|
62465
|
+
// src/cli/install-codex/codex-config-mcp.ts
|
|
62466
|
+
var CONTEXT7_MCP_SERVER_HEADER = "mcp_servers.context7";
|
|
62467
|
+
var CONTEXT7_MCP_SERVER_BLOCK = [
|
|
62468
|
+
`[${CONTEXT7_MCP_SERVER_HEADER}]`,
|
|
62469
|
+
'command = "npx"',
|
|
62470
|
+
'args = ["-y", "@upstash/context7-mcp", "--api-key", "YOUR_API_KEY"]',
|
|
62471
|
+
"startup_timeout_sec = 20",
|
|
62472
|
+
""
|
|
62473
|
+
].join(`
|
|
62474
|
+
`);
|
|
62475
|
+
function ensureContext7McpServer(config) {
|
|
62476
|
+
if (findTomlSection(config, CONTEXT7_MCP_SERVER_HEADER))
|
|
62477
|
+
return config;
|
|
62478
|
+
return appendBlock(config, CONTEXT7_MCP_SERVER_BLOCK);
|
|
62479
|
+
}
|
|
62480
|
+
|
|
62481
|
+
// packages/omo-codex/scripts/install/toml-editor.mjs
|
|
62482
|
+
function findTomlSection2(config, header) {
|
|
62483
|
+
const headerLine = `[${header}]`;
|
|
62484
|
+
const lines = config.match(/[^\n]*\n?|$/g) ?? [];
|
|
62485
|
+
let offset = 0;
|
|
62486
|
+
let start = -1;
|
|
62487
|
+
for (const line of lines) {
|
|
62488
|
+
if (line.length === 0)
|
|
62489
|
+
break;
|
|
62490
|
+
const trimmed = line.trim();
|
|
62491
|
+
if (start === -1) {
|
|
62492
|
+
if (trimmed === headerLine)
|
|
62493
|
+
start = offset;
|
|
62494
|
+
} else if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
62495
|
+
return { start, end: offset, text: config.slice(start, offset) };
|
|
62496
|
+
}
|
|
62497
|
+
offset += line.length;
|
|
62498
|
+
}
|
|
62499
|
+
if (start === -1)
|
|
62500
|
+
return null;
|
|
62501
|
+
return { start, end: config.length, text: config.slice(start) };
|
|
62502
|
+
}
|
|
62503
|
+
function replaceOrInsertSetting2(config, section, key, value) {
|
|
62504
|
+
const linePattern = new RegExp(`^${escapeRegExp2(key)}\\s*=.*$`, "m");
|
|
62505
|
+
const replacement = linePattern.test(section.text) ? section.text.replace(linePattern, `${key} = ${value}`) : insertSetting2(section.text, key, value);
|
|
62506
|
+
return config.slice(0, section.start) + replacement + config.slice(section.end);
|
|
62507
|
+
}
|
|
62508
|
+
function removeSetting2(config, section, key) {
|
|
62509
|
+
const linePattern = new RegExp(`^\\s*${escapeRegExp2(key)}\\s*=.*(?:\\n|$)`, "m");
|
|
62510
|
+
const replacement = section.text.replace(linePattern, "");
|
|
62511
|
+
return config.slice(0, section.start) + replacement + config.slice(section.end);
|
|
62512
|
+
}
|
|
62513
|
+
function replaceOrInsertRootSetting2(config, key, value) {
|
|
62514
|
+
const sectionStart = findFirstTableStart2(config);
|
|
62515
|
+
const root = config.slice(0, sectionStart);
|
|
62516
|
+
const suffix = config.slice(sectionStart);
|
|
62517
|
+
const linePattern = new RegExp(`^${escapeRegExp2(key)}\\s*=.*$`, "m");
|
|
62518
|
+
const replacement = linePattern.test(root) ? root.replace(linePattern, `${key} = ${value}`) : `${root.trimEnd()}${root.trimEnd().length > 0 ? `
|
|
62519
|
+
` : ""}${key} = ${value}
|
|
62520
|
+
`;
|
|
62521
|
+
if (suffix.length === 0)
|
|
62522
|
+
return replacement;
|
|
62523
|
+
return `${replacement.trimEnd()}
|
|
62524
|
+
|
|
62525
|
+
${suffix.trimStart()}`;
|
|
62526
|
+
}
|
|
62527
|
+
function appendBlock2(config, block) {
|
|
62528
|
+
const prefix = config.trimEnd();
|
|
62529
|
+
return `${prefix}${prefix.length > 0 ? `
|
|
62530
|
+
|
|
62531
|
+
` : ""}${block.trimEnd()}
|
|
62532
|
+
`;
|
|
62533
|
+
}
|
|
62534
|
+
function findFirstTableStart2(config) {
|
|
62535
|
+
const match = config.match(/^[[].*$/m);
|
|
62536
|
+
return match?.index ?? config.length;
|
|
62537
|
+
}
|
|
62538
|
+
function insertSetting2(sectionText, key, value) {
|
|
62539
|
+
const lines = sectionText.split(`
|
|
62540
|
+
`);
|
|
62541
|
+
lines.splice(1, 0, `${key} = ${value}`);
|
|
62542
|
+
return lines.join(`
|
|
62543
|
+
`);
|
|
62544
|
+
}
|
|
62545
|
+
function escapeRegExp2(value) {
|
|
62546
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
62547
|
+
}
|
|
62548
|
+
|
|
62549
|
+
// packages/omo-codex/scripts/install/permissions.mjs
|
|
62550
|
+
function ensureAutonomousPermissions(config) {
|
|
62551
|
+
let next = replaceOrInsertRootSetting2(config, "approval_policy", JSON.stringify("never"));
|
|
62552
|
+
next = replaceOrInsertRootSetting2(next, "sandbox_mode", JSON.stringify("danger-full-access"));
|
|
62553
|
+
next = replaceOrInsertRootSetting2(next, "network_access", JSON.stringify("enabled"));
|
|
62554
|
+
next = removeWindowsSandboxSetting(next);
|
|
62555
|
+
next = ensureNoticeEnabled(next, "hide_full_access_warning");
|
|
62556
|
+
return ensureNoticeEnabled(next, "hide_world_writable_warning");
|
|
62557
|
+
}
|
|
62558
|
+
function removeWindowsSandboxSetting(config) {
|
|
62559
|
+
const section = findTomlSection2(config, "windows");
|
|
62560
|
+
if (!section)
|
|
62561
|
+
return config;
|
|
62562
|
+
return removeSetting2(config, section, "sandbox");
|
|
62563
|
+
}
|
|
62564
|
+
function ensureNoticeEnabled(config, key) {
|
|
62565
|
+
const section = findTomlSection2(config, "notice");
|
|
62566
|
+
if (!section)
|
|
62567
|
+
return appendNoticeBlock(config, key);
|
|
62568
|
+
return replaceOrInsertSetting2(config, section, key, "true");
|
|
62569
|
+
}
|
|
62570
|
+
function appendNoticeBlock(config, key) {
|
|
62571
|
+
return appendBlock2(config, `[notice]
|
|
62572
|
+
${key} = true
|
|
62573
|
+
`);
|
|
62574
|
+
}
|
|
62575
|
+
// src/cli/install-codex/codex-config-reasoning.ts
|
|
62576
|
+
var DEFAULT_MODE_REASONING_EFFORT = "high";
|
|
62577
|
+
var PLAN_MODE_REASONING_EFFORT = "xhigh";
|
|
62578
|
+
function ensureCodexReasoningConfig(config) {
|
|
62579
|
+
let next = replaceOrInsertRootSetting(config, "model_reasoning_effort", JSON.stringify(DEFAULT_MODE_REASONING_EFFORT));
|
|
62580
|
+
next = replaceOrInsertRootSetting(next, "plan_mode_reasoning_effort", JSON.stringify(PLAN_MODE_REASONING_EFFORT));
|
|
62581
|
+
return next;
|
|
62582
|
+
}
|
|
62583
|
+
|
|
62235
62584
|
// src/cli/install-codex/codex-multi-agent-v2-config.ts
|
|
62236
62585
|
var CODEX_MULTI_AGENT_V2_HEADER = "features.multi_agent_v2";
|
|
62237
62586
|
var CODEX_MULTI_AGENT_V2_MAX_CONCURRENT_THREADS_PER_SESSION = 1e4;
|
|
62238
62587
|
function ensureCodexMultiAgentV2Config(config) {
|
|
62239
|
-
const normalizedConfig = removeFeatureFlagSetting(config, "multi_agent_v2");
|
|
62588
|
+
const normalizedConfig = removeLegacyAgentsMaxThreadsSetting(removeFeatureFlagSetting(config, "multi_agent_v2"));
|
|
62240
62589
|
const section = findTomlSection(normalizedConfig, CODEX_MULTI_AGENT_V2_HEADER);
|
|
62241
62590
|
const maxThreadsValue = CODEX_MULTI_AGENT_V2_MAX_CONCURRENT_THREADS_PER_SESSION.toString();
|
|
62242
62591
|
if (!section) {
|
|
@@ -62261,6 +62610,12 @@ function removeFeatureFlagSetting(config, featureName) {
|
|
|
62261
62610
|
return config;
|
|
62262
62611
|
return removeSetting(config, section, featureName);
|
|
62263
62612
|
}
|
|
62613
|
+
function removeLegacyAgentsMaxThreadsSetting(config) {
|
|
62614
|
+
const section = findTomlSection(config, "agents");
|
|
62615
|
+
if (!section)
|
|
62616
|
+
return config;
|
|
62617
|
+
return removeSetting(config, section, "max_threads");
|
|
62618
|
+
}
|
|
62264
62619
|
|
|
62265
62620
|
// src/cli/install-codex/codex-config-toml.ts
|
|
62266
62621
|
var SISYPHUS_LEGACY_MARKETPLACES = ["lazycodex", "code-yeongyu-codex-plugins"];
|
|
@@ -62276,7 +62631,7 @@ async function updateCodexConfig(input) {
|
|
|
62276
62631
|
await mkdir3(dirname12(input.configPath), { recursive: true });
|
|
62277
62632
|
let config = "";
|
|
62278
62633
|
if (await exists2(input.configPath))
|
|
62279
|
-
config = await
|
|
62634
|
+
config = await readFile6(input.configPath, "utf8");
|
|
62280
62635
|
const pluginSet = new Set(input.pluginNames);
|
|
62281
62636
|
for (const legacyMarketplaceName of legacyMarketplaceNames(input.marketplaceName)) {
|
|
62282
62637
|
config = removeMarketplaceBlock(config, legacyMarketplaceName);
|
|
@@ -62288,13 +62643,16 @@ async function updateCodexConfig(input) {
|
|
|
62288
62643
|
config = removeStaleManagedAgentBlocks(config, new Set((input.agentConfigs ?? []).map((agentConfig) => agentConfig.name)));
|
|
62289
62644
|
config = ensureFeatureEnabled(config, "plugins");
|
|
62290
62645
|
config = ensureFeatureEnabled(config, "plugin_hooks");
|
|
62646
|
+
config = ensureCodexReasoningConfig(config);
|
|
62291
62647
|
config = ensureCodexMultiAgentV2Config(config);
|
|
62648
|
+
config = ensureContext7McpServer(config);
|
|
62292
62649
|
if (input.autonomousPermissions === true)
|
|
62293
62650
|
config = ensureAutonomousPermissions(config);
|
|
62294
62651
|
config = ensureMarketplaceBlock(config, input.marketplaceName, input.marketplaceSource);
|
|
62295
62652
|
for (const pluginName of input.pluginNames) {
|
|
62296
62653
|
config = ensurePluginEnabled(config, `${pluginName}@${input.marketplaceName}`);
|
|
62297
62654
|
}
|
|
62655
|
+
config = ensureOmoGitBashMcpPolicy(config, input);
|
|
62298
62656
|
for (const state of input.trustedHookStates ?? []) {
|
|
62299
62657
|
config = ensureHookTrusted(config, state.key, state.trustedHash);
|
|
62300
62658
|
}
|
|
@@ -62360,42 +62718,6 @@ ${featureName} = true
|
|
|
62360
62718
|
`);
|
|
62361
62719
|
return replaceOrInsertSetting(config, section, featureName, "true");
|
|
62362
62720
|
}
|
|
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, "\\$&");
|
|
62398
|
-
}
|
|
62399
62721
|
function ensureMarketplaceBlock(config, marketplaceName, source) {
|
|
62400
62722
|
const header = `marketplaces.${marketplaceName}`;
|
|
62401
62723
|
const lines = [
|
|
@@ -62424,6 +62746,22 @@ enabled = true
|
|
|
62424
62746
|
`);
|
|
62425
62747
|
return replaceOrInsertSetting(config, section, "enabled", "true");
|
|
62426
62748
|
}
|
|
62749
|
+
function ensurePluginMcpEnabled(config, pluginKey, serverName, enabled) {
|
|
62750
|
+
const header = `plugins.${JSON.stringify(pluginKey)}.mcp_servers.${serverName}`;
|
|
62751
|
+
const section = findTomlSection(config, header);
|
|
62752
|
+
const enabledValue = enabled ? "true" : "false";
|
|
62753
|
+
if (!section)
|
|
62754
|
+
return appendBlock(config, `[${header}]
|
|
62755
|
+
enabled = ${enabledValue}
|
|
62756
|
+
`);
|
|
62757
|
+
return replaceOrInsertSetting(config, section, "enabled", enabledValue);
|
|
62758
|
+
}
|
|
62759
|
+
function ensureOmoGitBashMcpPolicy(config, input) {
|
|
62760
|
+
if (input.marketplaceName !== "sisyphuslabs" || !input.pluginNames.includes("omo"))
|
|
62761
|
+
return config;
|
|
62762
|
+
const enabled = (input.platform ?? process.platform) === "win32";
|
|
62763
|
+
return ensurePluginMcpEnabled(config, "omo@sisyphuslabs", "git_bash", enabled);
|
|
62764
|
+
}
|
|
62427
62765
|
function ensureHookTrusted(config, key, trustedHash) {
|
|
62428
62766
|
const header = `hooks.state.${JSON.stringify(key)}`;
|
|
62429
62767
|
const section = findTomlSection(config, header);
|
|
@@ -62521,7 +62859,7 @@ function parseJsonString(value) {
|
|
|
62521
62859
|
}
|
|
62522
62860
|
async function exists2(path6) {
|
|
62523
62861
|
try {
|
|
62524
|
-
await
|
|
62862
|
+
await readFile6(path6, "utf8");
|
|
62525
62863
|
return true;
|
|
62526
62864
|
} catch (error) {
|
|
62527
62865
|
if (error instanceof Error)
|
|
@@ -62531,9 +62869,9 @@ async function exists2(path6) {
|
|
|
62531
62869
|
}
|
|
62532
62870
|
|
|
62533
62871
|
// src/cli/install-codex/codex-hook-trust.ts
|
|
62534
|
-
import { createHash } from "crypto";
|
|
62535
|
-
import { readFile as
|
|
62536
|
-
import { join as
|
|
62872
|
+
import { createHash as createHash2 } from "crypto";
|
|
62873
|
+
import { readFile as readFile7 } from "fs/promises";
|
|
62874
|
+
import { join as join24 } from "path";
|
|
62537
62875
|
var EVENT_LABELS = new Map([
|
|
62538
62876
|
["PreToolUse", "pre_tool_use"],
|
|
62539
62877
|
["PermissionRequest", "permission_request"],
|
|
@@ -62547,17 +62885,17 @@ var EVENT_LABELS = new Map([
|
|
|
62547
62885
|
["Stop", "stop"]
|
|
62548
62886
|
]);
|
|
62549
62887
|
async function trustedHookStatesForPlugin(input) {
|
|
62550
|
-
const manifestPath =
|
|
62888
|
+
const manifestPath = join24(input.pluginRoot, ".codex-plugin", "plugin.json");
|
|
62551
62889
|
if (!await exists3(manifestPath))
|
|
62552
62890
|
return [];
|
|
62553
|
-
const manifest = JSON.parse(await
|
|
62554
|
-
if (!
|
|
62891
|
+
const manifest = JSON.parse(await readFile7(manifestPath, "utf8"));
|
|
62892
|
+
if (!isRecord12(manifest) || typeof manifest.hooks !== "string")
|
|
62555
62893
|
return [];
|
|
62556
|
-
const hooksPath =
|
|
62894
|
+
const hooksPath = join24(input.pluginRoot, manifest.hooks);
|
|
62557
62895
|
if (!await exists3(hooksPath))
|
|
62558
62896
|
return [];
|
|
62559
|
-
const parsed = JSON.parse(await
|
|
62560
|
-
if (!
|
|
62897
|
+
const parsed = JSON.parse(await readFile7(hooksPath, "utf8"));
|
|
62898
|
+
if (!isRecord12(parsed) || !isRecord12(parsed.hooks))
|
|
62561
62899
|
return [];
|
|
62562
62900
|
const keySource = `${input.pluginName}@${input.marketplaceName}:${stripDotSlash(manifest.hooks)}`;
|
|
62563
62901
|
const states = [];
|
|
@@ -62568,10 +62906,10 @@ async function trustedHookStatesForPlugin(input) {
|
|
|
62568
62906
|
if (eventLabel === undefined)
|
|
62569
62907
|
continue;
|
|
62570
62908
|
for (const [groupIndex, group] of groups.entries()) {
|
|
62571
|
-
if (!
|
|
62909
|
+
if (!isRecord12(group) || !Array.isArray(group.hooks))
|
|
62572
62910
|
continue;
|
|
62573
62911
|
for (const [handlerIndex, handler] of group.hooks.entries()) {
|
|
62574
|
-
if (!
|
|
62912
|
+
if (!isRecord12(handler) || handler.type !== "command")
|
|
62575
62913
|
continue;
|
|
62576
62914
|
if (handler.async === true)
|
|
62577
62915
|
continue;
|
|
@@ -62598,12 +62936,12 @@ function commandHookHash(eventName, matcher, handler) {
|
|
|
62598
62936
|
if (typeof matcher === "string")
|
|
62599
62937
|
identity.matcher = matcher;
|
|
62600
62938
|
const canonical = JSON.stringify(canonicalJson(identity));
|
|
62601
|
-
return `sha256:${
|
|
62939
|
+
return `sha256:${createHash2("sha256").update(canonical).digest("hex")}`;
|
|
62602
62940
|
}
|
|
62603
62941
|
function canonicalJson(value) {
|
|
62604
62942
|
if (Array.isArray(value))
|
|
62605
62943
|
return value.map(canonicalJson);
|
|
62606
|
-
if (!
|
|
62944
|
+
if (!isRecord12(value))
|
|
62607
62945
|
return value;
|
|
62608
62946
|
const result = {};
|
|
62609
62947
|
for (const key of Object.keys(value).sort()) {
|
|
@@ -62616,19 +62954,113 @@ function stripDotSlash(value) {
|
|
|
62616
62954
|
}
|
|
62617
62955
|
async function exists3(path6) {
|
|
62618
62956
|
try {
|
|
62619
|
-
await
|
|
62957
|
+
await readFile7(path6, "utf8");
|
|
62620
62958
|
return true;
|
|
62621
62959
|
} catch {
|
|
62622
62960
|
return false;
|
|
62623
62961
|
}
|
|
62624
62962
|
}
|
|
62625
|
-
function
|
|
62963
|
+
function isRecord12(value) {
|
|
62626
62964
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
62627
62965
|
}
|
|
62628
62966
|
|
|
62967
|
+
// src/cli/install-codex/git-bash.ts
|
|
62968
|
+
import { execFileSync } from "child_process";
|
|
62969
|
+
import { existsSync as existsSync23 } from "fs";
|
|
62970
|
+
var GIT_BASH_ENV_KEY = "OMO_CODEX_GIT_BASH_PATH";
|
|
62971
|
+
var SKIP_GIT_BASH_AUTO_INSTALL_ENV_KEY = "OMO_CODEX_SKIP_GIT_BASH_AUTO_INSTALL";
|
|
62972
|
+
var PROGRAM_FILES_GIT_BASH = "C:\\Program Files\\Git\\bin\\bash.exe";
|
|
62973
|
+
var PROGRAM_FILES_X86_GIT_BASH = "C:\\Program Files (x86)\\Git\\bin\\bash.exe";
|
|
62974
|
+
var WINGET_INSTALL_ARGS = ["install", "--id", "Git.Git", "-e", "--source", "winget"];
|
|
62975
|
+
function resolveGitBash(input) {
|
|
62976
|
+
if (input.platform !== "win32")
|
|
62977
|
+
return { found: true, path: null, source: "not-required" };
|
|
62978
|
+
const checkedPaths = [];
|
|
62979
|
+
const envPath = nonEmptyEnvValue(input.env, GIT_BASH_ENV_KEY);
|
|
62980
|
+
if (envPath !== undefined) {
|
|
62981
|
+
checkedPaths.push(envPath);
|
|
62982
|
+
if (isBashExePath(envPath) && input.exists(envPath))
|
|
62983
|
+
return { found: true, path: envPath, source: "env" };
|
|
62984
|
+
return missingGitBash(checkedPaths);
|
|
62985
|
+
}
|
|
62986
|
+
for (const candidate of [
|
|
62987
|
+
{ path: PROGRAM_FILES_GIT_BASH, source: "program-files" },
|
|
62988
|
+
{ path: PROGRAM_FILES_X86_GIT_BASH, source: "program-files-x86" }
|
|
62989
|
+
]) {
|
|
62990
|
+
checkedPaths.push(candidate.path);
|
|
62991
|
+
if (input.exists(candidate.path))
|
|
62992
|
+
return { found: true, path: candidate.path, source: candidate.source };
|
|
62993
|
+
}
|
|
62994
|
+
for (const pathCandidate of input.where("bash")) {
|
|
62995
|
+
const candidate = pathCandidate.trim();
|
|
62996
|
+
if (candidate.length === 0)
|
|
62997
|
+
continue;
|
|
62998
|
+
checkedPaths.push(candidate);
|
|
62999
|
+
if (isBashExePath(candidate) && input.exists(candidate))
|
|
63000
|
+
return { found: true, path: candidate, source: "path" };
|
|
63001
|
+
}
|
|
63002
|
+
return missingGitBash(checkedPaths);
|
|
63003
|
+
}
|
|
63004
|
+
function resolveGitBashForCurrentProcess(input = {}) {
|
|
63005
|
+
return resolveGitBash({
|
|
63006
|
+
platform: input.platform ?? process.platform,
|
|
63007
|
+
env: input.env ?? process.env,
|
|
63008
|
+
exists: existsSync23,
|
|
63009
|
+
where: whereCommand
|
|
63010
|
+
});
|
|
63011
|
+
}
|
|
63012
|
+
async function prepareGitBashForInstall(input) {
|
|
63013
|
+
const resolve8 = input.resolveGitBash ?? (() => resolveGitBashForCurrentProcess({ platform: input.platform, env: input.env }));
|
|
63014
|
+
const initialResolution = resolve8();
|
|
63015
|
+
if (input.platform !== "win32" || initialResolution.found)
|
|
63016
|
+
return initialResolution;
|
|
63017
|
+
if (input.env[SKIP_GIT_BASH_AUTO_INSTALL_ENV_KEY] === "1")
|
|
63018
|
+
return initialResolution;
|
|
63019
|
+
try {
|
|
63020
|
+
await input.runCommand("winget", WINGET_INSTALL_ARGS, { cwd: input.cwd });
|
|
63021
|
+
} catch (error) {
|
|
63022
|
+
if (!(error instanceof Error))
|
|
63023
|
+
throw error;
|
|
63024
|
+
return initialResolution;
|
|
63025
|
+
}
|
|
63026
|
+
return resolve8();
|
|
63027
|
+
}
|
|
63028
|
+
function missingGitBash(checkedPaths) {
|
|
63029
|
+
return {
|
|
63030
|
+
found: false,
|
|
63031
|
+
checkedPaths,
|
|
63032
|
+
installHint: [
|
|
63033
|
+
"Git Bash is required for native Windows Codex profile installs.",
|
|
63034
|
+
"Install it with: winget install --id Git.Git -e --source winget",
|
|
63035
|
+
`For a custom install, set ${GIT_BASH_ENV_KEY}=C:\\path\\to\\bash.exe`,
|
|
63036
|
+
"Then rerun `npx lazycodex-ai install`."
|
|
63037
|
+
].join(`
|
|
63038
|
+
`)
|
|
63039
|
+
};
|
|
63040
|
+
}
|
|
63041
|
+
function nonEmptyEnvValue(env, key) {
|
|
63042
|
+
const value = env[key];
|
|
63043
|
+
if (value === undefined)
|
|
63044
|
+
return;
|
|
63045
|
+
const trimmed = value.trim();
|
|
63046
|
+
return trimmed.length === 0 ? undefined : trimmed;
|
|
63047
|
+
}
|
|
63048
|
+
function isBashExePath(path6) {
|
|
63049
|
+
return path6.toLowerCase().endsWith("bash.exe");
|
|
63050
|
+
}
|
|
63051
|
+
function whereCommand(command) {
|
|
63052
|
+
try {
|
|
63053
|
+
return execFileSync("where", [command], { encoding: "utf8" }).split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
63054
|
+
} catch (error) {
|
|
63055
|
+
if (error instanceof Error)
|
|
63056
|
+
return [];
|
|
63057
|
+
throw error;
|
|
63058
|
+
}
|
|
63059
|
+
}
|
|
63060
|
+
|
|
62629
63061
|
// src/cli/install-codex/link-cached-plugin-agents.ts
|
|
62630
63062
|
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
|
|
63063
|
+
import { basename as basename6, join as join25 } from "path";
|
|
62632
63064
|
var MANIFEST_FILE = ".installed-agents.json";
|
|
62633
63065
|
async function linkCachedPluginAgents(input) {
|
|
62634
63066
|
const platform = input.platform ?? process.platform;
|
|
@@ -62637,11 +63069,11 @@ async function linkCachedPluginAgents(input) {
|
|
|
62637
63069
|
await writeManifest(input.pluginRoot, []);
|
|
62638
63070
|
return [];
|
|
62639
63071
|
}
|
|
62640
|
-
const agentsDir =
|
|
63072
|
+
const agentsDir = join25(input.codexHome, "agents");
|
|
62641
63073
|
await mkdir4(agentsDir, { recursive: true });
|
|
62642
63074
|
const linked = [];
|
|
62643
63075
|
for (const agentPath of bundledAgents) {
|
|
62644
|
-
const linkPath =
|
|
63076
|
+
const linkPath = join25(agentsDir, basename6(agentPath));
|
|
62645
63077
|
if (platform === "win32") {
|
|
62646
63078
|
await replaceWithCopy(linkPath, agentPath);
|
|
62647
63079
|
} else {
|
|
@@ -62653,7 +63085,7 @@ async function linkCachedPluginAgents(input) {
|
|
|
62653
63085
|
return linked;
|
|
62654
63086
|
}
|
|
62655
63087
|
async function discoverBundledAgents(pluginRoot) {
|
|
62656
|
-
const componentsRoot =
|
|
63088
|
+
const componentsRoot = join25(pluginRoot, "components");
|
|
62657
63089
|
if (!await exists4(componentsRoot))
|
|
62658
63090
|
return [];
|
|
62659
63091
|
const componentEntries = await readdir3(componentsRoot, { withFileTypes: true });
|
|
@@ -62661,14 +63093,14 @@ async function discoverBundledAgents(pluginRoot) {
|
|
|
62661
63093
|
for (const entry of componentEntries) {
|
|
62662
63094
|
if (!entry.isDirectory())
|
|
62663
63095
|
continue;
|
|
62664
|
-
const agentsRoot =
|
|
63096
|
+
const agentsRoot = join25(componentsRoot, entry.name, "agents");
|
|
62665
63097
|
if (!await exists4(agentsRoot))
|
|
62666
63098
|
continue;
|
|
62667
63099
|
const agentEntries = await readdir3(agentsRoot, { withFileTypes: true });
|
|
62668
63100
|
for (const file of agentEntries) {
|
|
62669
63101
|
if (!file.isFile() || !file.name.endsWith(".toml"))
|
|
62670
63102
|
continue;
|
|
62671
|
-
agents.push(
|
|
63103
|
+
agents.push(join25(agentsRoot, file.name));
|
|
62672
63104
|
}
|
|
62673
63105
|
}
|
|
62674
63106
|
agents.sort();
|
|
@@ -62692,7 +63124,7 @@ async function prepareReplacement(linkPath) {
|
|
|
62692
63124
|
await rm3(linkPath, { force: true });
|
|
62693
63125
|
}
|
|
62694
63126
|
async function writeManifest(pluginRoot, agentPaths) {
|
|
62695
|
-
const manifestPath =
|
|
63127
|
+
const manifestPath = join25(pluginRoot, MANIFEST_FILE);
|
|
62696
63128
|
const payload = { agents: [...agentPaths].sort() };
|
|
62697
63129
|
await writeFile4(manifestPath, `${JSON.stringify(payload, null, "\t")}
|
|
62698
63130
|
`);
|
|
@@ -62707,14 +63139,14 @@ async function exists4(path6) {
|
|
|
62707
63139
|
}
|
|
62708
63140
|
|
|
62709
63141
|
// src/cli/install-codex/codex-marketplace.ts
|
|
62710
|
-
import { readFile as
|
|
62711
|
-
import { join as
|
|
63142
|
+
import { readFile as readFile8 } from "fs/promises";
|
|
63143
|
+
import { join as join26 } from "path";
|
|
62712
63144
|
var DEFAULT_MARKETPLACE_PATH = "packages/omo-codex/marketplace.json";
|
|
62713
63145
|
async function readMarketplace(repoRoot, options) {
|
|
62714
|
-
const marketplacePath = options?.marketplacePath ??
|
|
62715
|
-
const raw = await
|
|
63146
|
+
const marketplacePath = options?.marketplacePath ?? join26(repoRoot, DEFAULT_MARKETPLACE_PATH);
|
|
63147
|
+
const raw = await readFile8(marketplacePath, "utf8");
|
|
62716
63148
|
const parsed = JSON.parse(raw);
|
|
62717
|
-
if (!
|
|
63149
|
+
if (!isRecord13(parsed))
|
|
62718
63150
|
throw new Error("marketplace.json must be an object");
|
|
62719
63151
|
if (typeof parsed.name !== "string" || parsed.name.trim() === "") {
|
|
62720
63152
|
throw new Error("marketplace.json name must be a non-empty string");
|
|
@@ -62730,12 +63162,12 @@ async function readMarketplace(repoRoot, options) {
|
|
|
62730
63162
|
function resolvePluginSource(repoRoot, plugin, options) {
|
|
62731
63163
|
const sourcePath = localSourcePath(options?.pathOverride ?? plugin.source);
|
|
62732
63164
|
const relativePath = sourcePath.slice(2);
|
|
62733
|
-
return
|
|
63165
|
+
return join26(repoRoot, ...relativePath.split(/[\\/]/));
|
|
62734
63166
|
}
|
|
62735
63167
|
async function readPluginManifest(pluginRoot) {
|
|
62736
|
-
const raw = await
|
|
63168
|
+
const raw = await readFile8(join26(pluginRoot, ".codex-plugin", "plugin.json"), "utf8");
|
|
62737
63169
|
const parsed = JSON.parse(raw);
|
|
62738
|
-
if (!
|
|
63170
|
+
if (!isRecord13(parsed))
|
|
62739
63171
|
throw new Error(`${pluginRoot} plugin.json must be an object`);
|
|
62740
63172
|
if (typeof parsed.name !== "string" || parsed.name.trim() === "") {
|
|
62741
63173
|
throw new Error(`${pluginRoot} plugin.json name must be a non-empty string`);
|
|
@@ -62761,7 +63193,7 @@ function validatePathSegment(value, label) {
|
|
|
62761
63193
|
}
|
|
62762
63194
|
}
|
|
62763
63195
|
function normalizeMarketplacePlugin(plugin, index) {
|
|
62764
|
-
if (!
|
|
63196
|
+
if (!isRecord13(plugin))
|
|
62765
63197
|
throw new Error(`marketplace plugin ${index} must be an object`);
|
|
62766
63198
|
if (typeof plugin.name !== "string" || plugin.name.trim() === "") {
|
|
62767
63199
|
throw new Error(`marketplace plugin ${index} name must be a non-empty string`);
|
|
@@ -62773,7 +63205,7 @@ function normalizeMarketplacePlugin(plugin, index) {
|
|
|
62773
63205
|
}
|
|
62774
63206
|
return { name: plugin.name, source: plugin.source };
|
|
62775
63207
|
}
|
|
62776
|
-
if (
|
|
63208
|
+
if (isRecord13(plugin.source) && plugin.source.source === "local" && typeof plugin.source.path === "string") {
|
|
62777
63209
|
validateLocalSourcePath(plugin.source.path);
|
|
62778
63210
|
const local = { source: "local", path: plugin.source.path };
|
|
62779
63211
|
return { name: plugin.name, source: local };
|
|
@@ -62800,13 +63232,13 @@ function validateLocalSourcePath(path6) {
|
|
|
62800
63232
|
}
|
|
62801
63233
|
return path6;
|
|
62802
63234
|
}
|
|
62803
|
-
function
|
|
63235
|
+
function isRecord13(value) {
|
|
62804
63236
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
62805
63237
|
}
|
|
62806
63238
|
|
|
62807
63239
|
// src/cli/install-codex/codex-marketplace-snapshot.ts
|
|
62808
63240
|
import { cp as cp3, mkdir as mkdir5, rename as rename2, rm as rm4, writeFile as writeFile5 } from "fs/promises";
|
|
62809
|
-
import { join as
|
|
63241
|
+
import { join as join27, sep as sep2 } from "path";
|
|
62810
63242
|
var INSTALLED_MARKETPLACES_DIR = ".tmp/marketplaces";
|
|
62811
63243
|
async function writeInstalledMarketplaceSnapshot(input) {
|
|
62812
63244
|
const marketplaceRoot = installedMarketplaceRoot(input.codexHome, input.marketplace.name);
|
|
@@ -62819,21 +63251,21 @@ async function writeInstalledMarketplaceSnapshot(input) {
|
|
|
62819
63251
|
return snapshotPlugins;
|
|
62820
63252
|
}
|
|
62821
63253
|
function installedMarketplaceRoot(codexHome, marketplaceName) {
|
|
62822
|
-
return
|
|
63254
|
+
return join27(codexHome, INSTALLED_MARKETPLACES_DIR, marketplaceName);
|
|
62823
63255
|
}
|
|
62824
63256
|
async function writeMarketplaceManifest(marketplaceRoot, marketplace) {
|
|
62825
|
-
const manifestDir =
|
|
63257
|
+
const manifestDir = join27(marketplaceRoot, ".agents", "plugins");
|
|
62826
63258
|
await mkdir5(manifestDir, { recursive: true });
|
|
62827
|
-
const tempPath =
|
|
63259
|
+
const tempPath = join27(manifestDir, `.marketplace-${process.pid}-${Date.now()}.json.tmp`);
|
|
62828
63260
|
await writeFile5(tempPath, `${JSON.stringify(marketplace, null, "\t")}
|
|
62829
63261
|
`);
|
|
62830
|
-
await rename2(tempPath,
|
|
63262
|
+
await rename2(tempPath, join27(manifestDir, "marketplace.json"));
|
|
62831
63263
|
}
|
|
62832
63264
|
async function writeSnapshotPlugin(marketplaceRoot, plugin) {
|
|
62833
|
-
const pluginsDir =
|
|
63265
|
+
const pluginsDir = join27(marketplaceRoot, "plugins");
|
|
62834
63266
|
await mkdir5(pluginsDir, { recursive: true });
|
|
62835
|
-
const targetPath =
|
|
62836
|
-
const tempPath =
|
|
63267
|
+
const targetPath = join27(pluginsDir, plugin.name);
|
|
63268
|
+
const tempPath = join27(pluginsDir, `.tmp-${plugin.name}-${process.pid}-${Date.now()}`);
|
|
62837
63269
|
await rm4(tempPath, { recursive: true, force: true });
|
|
62838
63270
|
await cp3(plugin.sourcePath, tempPath, {
|
|
62839
63271
|
recursive: true,
|
|
@@ -62871,19 +63303,260 @@ var defaultRunCommand = async (command, args, options) => {
|
|
|
62871
63303
|
}
|
|
62872
63304
|
};
|
|
62873
63305
|
|
|
63306
|
+
// src/cli/install-codex/codex-project-local-cleanup.ts
|
|
63307
|
+
import { copyFile as copyFile2, lstat as lstat4, readFile as readFile9, writeFile as writeFile6 } from "fs/promises";
|
|
63308
|
+
import { dirname as dirname13, join as join28, resolve as resolve8 } from "path";
|
|
63309
|
+
var LEGACY_AGENT_CONFLICT_KEYS = ["max_threads"];
|
|
63310
|
+
var PROJECT_LOCAL_ARTIFACT_PATHS = [
|
|
63311
|
+
".omx",
|
|
63312
|
+
".codex/hooks.json",
|
|
63313
|
+
".codex/agents",
|
|
63314
|
+
".codex/prompts",
|
|
63315
|
+
".codex/skills"
|
|
63316
|
+
];
|
|
63317
|
+
async function repairNearestProjectLocalCodexArtifacts(input) {
|
|
63318
|
+
const project = await findProjectLocalCodexConfigs(input.startDirectory, input.codexHome);
|
|
63319
|
+
if (project === null) {
|
|
63320
|
+
return emptyProjectLocalCodexCleanupResult();
|
|
63321
|
+
}
|
|
63322
|
+
const artifacts = await collectProjectLocalArtifacts(project.artifactRoots);
|
|
63323
|
+
const configs = [];
|
|
63324
|
+
for (const configPath of project.configPaths) {
|
|
63325
|
+
const original = await readFile9(configPath, "utf8");
|
|
63326
|
+
const repair = repairProjectLocalCodexConfigText(original);
|
|
63327
|
+
if (!repair.changed) {
|
|
63328
|
+
configs.push({
|
|
63329
|
+
projectRoot: project.projectRoot,
|
|
63330
|
+
configPath,
|
|
63331
|
+
changed: false,
|
|
63332
|
+
removedKeys: repair.removedKeys
|
|
63333
|
+
});
|
|
63334
|
+
continue;
|
|
63335
|
+
}
|
|
63336
|
+
const backupPath = `${configPath}.backup-${formatBackupTimestamp(input.now?.() ?? new Date)}`;
|
|
63337
|
+
await copyFile2(configPath, backupPath);
|
|
63338
|
+
await writeFile6(configPath, `${repair.config.trimEnd()}
|
|
63339
|
+
`);
|
|
63340
|
+
configs.push({
|
|
63341
|
+
projectRoot: project.projectRoot,
|
|
63342
|
+
configPath,
|
|
63343
|
+
changed: true,
|
|
63344
|
+
removedKeys: repair.removedKeys,
|
|
63345
|
+
backupPath
|
|
63346
|
+
});
|
|
63347
|
+
}
|
|
63348
|
+
const changedConfigs = configs.filter((config) => config.changed);
|
|
63349
|
+
const nearestChangedConfig = lastValue(changedConfigs);
|
|
63350
|
+
const nearestConfig = lastValue(configs);
|
|
63351
|
+
return {
|
|
63352
|
+
projectRoot: project.projectRoot,
|
|
63353
|
+
configPath: nearestChangedConfig?.configPath ?? nearestConfig?.configPath ?? null,
|
|
63354
|
+
changed: changedConfigs.length > 0,
|
|
63355
|
+
removedKeys: uniqueRemovedKeys(changedConfigs),
|
|
63356
|
+
backupPath: nearestChangedConfig?.backupPath,
|
|
63357
|
+
configs,
|
|
63358
|
+
artifacts
|
|
63359
|
+
};
|
|
63360
|
+
}
|
|
63361
|
+
function emptyProjectLocalCodexCleanupResult() {
|
|
63362
|
+
return {
|
|
63363
|
+
projectRoot: null,
|
|
63364
|
+
configPath: null,
|
|
63365
|
+
changed: false,
|
|
63366
|
+
removedKeys: [],
|
|
63367
|
+
configs: [],
|
|
63368
|
+
artifacts: []
|
|
63369
|
+
};
|
|
63370
|
+
}
|
|
63371
|
+
function uniqueRemovedKeys(configs) {
|
|
63372
|
+
const keys = [];
|
|
63373
|
+
for (const config of configs) {
|
|
63374
|
+
for (const key of config.removedKeys) {
|
|
63375
|
+
if (!keys.includes(key))
|
|
63376
|
+
keys.push(key);
|
|
63377
|
+
}
|
|
63378
|
+
}
|
|
63379
|
+
return keys;
|
|
63380
|
+
}
|
|
63381
|
+
function lastValue(values) {
|
|
63382
|
+
return values.length > 0 ? values[values.length - 1] ?? null : null;
|
|
63383
|
+
}
|
|
63384
|
+
function repairProjectLocalCodexConfigText(config) {
|
|
63385
|
+
if (!isMultiAgentV2Enabled(config))
|
|
63386
|
+
return { config, changed: false, removedKeys: [] };
|
|
63387
|
+
let nextConfig = config;
|
|
63388
|
+
const removedKeys = [];
|
|
63389
|
+
for (const key of LEGACY_AGENT_CONFLICT_KEYS) {
|
|
63390
|
+
const section = findTomlSection(nextConfig, "agents");
|
|
63391
|
+
if (section === null || !hasSetting(section.text, key))
|
|
63392
|
+
continue;
|
|
63393
|
+
nextConfig = removeSetting(nextConfig, section, key);
|
|
63394
|
+
removedKeys.push(key);
|
|
63395
|
+
}
|
|
63396
|
+
return {
|
|
63397
|
+
config: nextConfig,
|
|
63398
|
+
changed: removedKeys.length > 0,
|
|
63399
|
+
removedKeys
|
|
63400
|
+
};
|
|
63401
|
+
}
|
|
63402
|
+
async function findProjectLocalCodexConfigs(startDirectory, codexHome) {
|
|
63403
|
+
if (startDirectory.includes("\x00"))
|
|
63404
|
+
return null;
|
|
63405
|
+
const startDirectoryStat = await maybeLstat(startDirectory);
|
|
63406
|
+
if (startDirectoryStat !== null && !startDirectoryStat.isDirectory()) {
|
|
63407
|
+
throw new ProjectLocalCleanupStartDirectoryError(startDirectory);
|
|
63408
|
+
}
|
|
63409
|
+
const codexHomeConfigPath = codexHome === undefined ? null : join28(resolve8(codexHome), "config.toml");
|
|
63410
|
+
let current = resolve8(startDirectory);
|
|
63411
|
+
const configPathsFromCwd = [];
|
|
63412
|
+
while (true) {
|
|
63413
|
+
const configPath = join28(current, ".codex", "config.toml");
|
|
63414
|
+
if (await isRegularProjectLocalConfig(current, configPath)) {
|
|
63415
|
+
if (codexHomeConfigPath === null || resolve8(configPath) !== codexHomeConfigPath) {
|
|
63416
|
+
configPathsFromCwd.push(configPath);
|
|
63417
|
+
}
|
|
63418
|
+
}
|
|
63419
|
+
if (await exists5(join28(current, ".git"))) {
|
|
63420
|
+
return configPathsFromCwd.length === 0 ? null : {
|
|
63421
|
+
projectRoot: current,
|
|
63422
|
+
configPaths: [...configPathsFromCwd].reverse(),
|
|
63423
|
+
artifactRoots: artifactRootsForConfigPaths(configPathsFromCwd)
|
|
63424
|
+
};
|
|
63425
|
+
}
|
|
63426
|
+
const parent = dirname13(current);
|
|
63427
|
+
if (parent === current) {
|
|
63428
|
+
const nearestConfigPath = configPathsFromCwd[0];
|
|
63429
|
+
return nearestConfigPath === undefined ? null : {
|
|
63430
|
+
projectRoot: dirname13(dirname13(nearestConfigPath)),
|
|
63431
|
+
configPaths: [nearestConfigPath],
|
|
63432
|
+
artifactRoots: [dirname13(dirname13(nearestConfigPath))]
|
|
63433
|
+
};
|
|
63434
|
+
}
|
|
63435
|
+
current = parent;
|
|
63436
|
+
}
|
|
63437
|
+
}
|
|
63438
|
+
async function isRegularProjectLocalConfig(directory, configPath) {
|
|
63439
|
+
const codexDirStat = await maybeLstat(join28(directory, ".codex"));
|
|
63440
|
+
if (codexDirStat === null || !codexDirStat.isDirectory() || codexDirStat.isSymbolicLink())
|
|
63441
|
+
return false;
|
|
63442
|
+
const configStat = await maybeLstat(configPath);
|
|
63443
|
+
return configStat !== null && configStat.isFile() && !configStat.isSymbolicLink();
|
|
63444
|
+
}
|
|
63445
|
+
function artifactRootsForConfigPaths(configPaths) {
|
|
63446
|
+
const roots = [];
|
|
63447
|
+
for (const configPath of configPaths) {
|
|
63448
|
+
const root = dirname13(dirname13(configPath));
|
|
63449
|
+
if (!roots.includes(root))
|
|
63450
|
+
roots.push(root);
|
|
63451
|
+
}
|
|
63452
|
+
return roots.reverse();
|
|
63453
|
+
}
|
|
63454
|
+
async function collectProjectLocalArtifacts(projectRoots) {
|
|
63455
|
+
const artifacts = [];
|
|
63456
|
+
const seenPaths = new Set;
|
|
63457
|
+
for (const projectRoot of projectRoots) {
|
|
63458
|
+
for (const relativePath of PROJECT_LOCAL_ARTIFACT_PATHS) {
|
|
63459
|
+
const artifactPath = join28(projectRoot, relativePath);
|
|
63460
|
+
if (seenPaths.has(artifactPath))
|
|
63461
|
+
continue;
|
|
63462
|
+
const entryStat = await maybeLstat(artifactPath);
|
|
63463
|
+
if (entryStat === null)
|
|
63464
|
+
continue;
|
|
63465
|
+
seenPaths.add(artifactPath);
|
|
63466
|
+
artifacts.push({
|
|
63467
|
+
relativePath,
|
|
63468
|
+
path: artifactPath,
|
|
63469
|
+
kind: entryStat.isDirectory() ? "directory" : entryStat.isFile() ? "file" : "other"
|
|
63470
|
+
});
|
|
63471
|
+
}
|
|
63472
|
+
}
|
|
63473
|
+
return artifacts;
|
|
63474
|
+
}
|
|
63475
|
+
function isMultiAgentV2Enabled(config) {
|
|
63476
|
+
const featuresSection = findTomlSection(config, "features");
|
|
63477
|
+
if (featuresSection !== null && settingIsBooleanTrue(featuresSection.text, "multi_agent_v2"))
|
|
63478
|
+
return true;
|
|
63479
|
+
const multiAgentSection = findTomlSection(config, "features.multi_agent_v2");
|
|
63480
|
+
return multiAgentSection !== null && settingIsBooleanTrue(multiAgentSection.text, "enabled");
|
|
63481
|
+
}
|
|
63482
|
+
function settingIsBooleanTrue(sectionText, key) {
|
|
63483
|
+
return new RegExp(`^\\s*${escapeRegExp(key)}\\s*=\\s*true\\s*(?:#.*)?$`, "m").test(sectionText);
|
|
63484
|
+
}
|
|
63485
|
+
function hasSetting(sectionText, key) {
|
|
63486
|
+
return new RegExp(`^\\s*${escapeRegExp(key)}\\s*=`, "m").test(sectionText);
|
|
63487
|
+
}
|
|
63488
|
+
function formatBackupTimestamp(date) {
|
|
63489
|
+
return date.toISOString().replace(/[:.]/g, "-");
|
|
63490
|
+
}
|
|
63491
|
+
async function maybeLstat(path6) {
|
|
63492
|
+
try {
|
|
63493
|
+
return await lstat4(path6);
|
|
63494
|
+
} catch (error) {
|
|
63495
|
+
if (nodeErrorCode(error) === "ENOENT")
|
|
63496
|
+
return null;
|
|
63497
|
+
throw error;
|
|
63498
|
+
}
|
|
63499
|
+
}
|
|
63500
|
+
async function exists5(path6) {
|
|
63501
|
+
return await maybeLstat(path6) !== null;
|
|
63502
|
+
}
|
|
63503
|
+
function nodeErrorCode(error) {
|
|
63504
|
+
if (!(error instanceof Error) || !("code" in error))
|
|
63505
|
+
return null;
|
|
63506
|
+
return typeof error.code === "string" ? error.code : null;
|
|
63507
|
+
}
|
|
63508
|
+
|
|
63509
|
+
class ProjectLocalCleanupStartDirectoryError extends Error {
|
|
63510
|
+
constructor(startDirectory) {
|
|
63511
|
+
super(`Project-local Codex cleanup start path is not a directory: ${startDirectory}`);
|
|
63512
|
+
this.name = "ProjectLocalCleanupStartDirectoryError";
|
|
63513
|
+
}
|
|
63514
|
+
}
|
|
63515
|
+
|
|
63516
|
+
// src/cli/install-codex/codex-project-local-cleanup-best-effort.ts
|
|
63517
|
+
async function repairProjectLocalCodexArtifactsBestEffort(input) {
|
|
63518
|
+
try {
|
|
63519
|
+
return await repairNearestProjectLocalCodexArtifacts({
|
|
63520
|
+
startDirectory: input.startDirectory,
|
|
63521
|
+
codexHome: input.codexHome,
|
|
63522
|
+
now: input.now
|
|
63523
|
+
});
|
|
63524
|
+
} catch (error) {
|
|
63525
|
+
input.log(`Skipped project-local Codex cleanup: ${formatUnknownError(error)}`);
|
|
63526
|
+
return emptyProjectLocalCodexCleanupResult();
|
|
63527
|
+
}
|
|
63528
|
+
}
|
|
63529
|
+
function formatUnknownError(error) {
|
|
63530
|
+
return error instanceof Error ? error.message : String(error);
|
|
63531
|
+
}
|
|
63532
|
+
|
|
62874
63533
|
// src/cli/install-codex/install-codex.ts
|
|
62875
63534
|
var SISYPHUS_LEGACY_CACHE_MARKETPLACES = ["lazycodex", "code-yeongyu-codex-plugins"];
|
|
62876
63535
|
async function runCodexInstaller(options = {}) {
|
|
62877
|
-
const
|
|
62878
|
-
const
|
|
62879
|
-
const
|
|
63536
|
+
const env = options.env ?? process.env;
|
|
63537
|
+
const platform = options.platform ?? process.platform;
|
|
63538
|
+
const repoRoot = resolve9(options.repoRoot ?? findRepoRoot({ importerDir: import.meta.dir, env }));
|
|
63539
|
+
const codexHome = resolve9(options.codexHome ?? env.CODEX_HOME ?? join30(homedir5(), ".codex"));
|
|
63540
|
+
const projectDirectory = resolve9(options.projectDirectory ?? env.OMO_CODEX_PROJECT ?? process.cwd());
|
|
63541
|
+
const binDir = resolveCodexInstallerBinDir({ binDir: options.binDir, codexHome, env });
|
|
62880
63542
|
const runCommand = options.runCommand ?? defaultRunCommand;
|
|
62881
63543
|
const log2 = options.log ?? (() => {
|
|
62882
63544
|
return;
|
|
62883
63545
|
});
|
|
62884
|
-
const
|
|
63546
|
+
const buildSource = await shouldBuildSourcePackages(repoRoot);
|
|
63547
|
+
const gitBashResolution = await prepareGitBashForInstall({
|
|
63548
|
+
platform,
|
|
63549
|
+
env,
|
|
63550
|
+
cwd: repoRoot,
|
|
63551
|
+
runCommand,
|
|
63552
|
+
resolveGitBash: platform === "win32" ? options.gitBashResolver ?? (() => resolveGitBashForCurrentProcess({ platform, env })) : undefined
|
|
63553
|
+
});
|
|
63554
|
+
if (!gitBashResolution.found) {
|
|
63555
|
+
throw new Error(gitBashResolution.installHint);
|
|
63556
|
+
}
|
|
63557
|
+
const codexPackageRoot = join30(repoRoot, "packages", "omo-codex");
|
|
62885
63558
|
const marketplace = await readMarketplace(repoRoot, {
|
|
62886
|
-
marketplacePath:
|
|
63559
|
+
marketplacePath: join30(codexPackageRoot, "marketplace.json")
|
|
62887
63560
|
});
|
|
62888
63561
|
const installed = [];
|
|
62889
63562
|
const pluginSources = [];
|
|
@@ -62898,6 +63571,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
62898
63571
|
validatePathSegment(version2, "plugin version");
|
|
62899
63572
|
log2(`Building ${entry.name}@${version2}`);
|
|
62900
63573
|
const plugin = await installCachedPlugin({
|
|
63574
|
+
buildSource,
|
|
62901
63575
|
codexHome,
|
|
62902
63576
|
marketplaceName: marketplace.name,
|
|
62903
63577
|
name: entry.name,
|
|
@@ -62905,7 +63579,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
62905
63579
|
sourcePath,
|
|
62906
63580
|
version: version2
|
|
62907
63581
|
});
|
|
62908
|
-
const links = await linkCachedPluginBins({ binDir, pluginRoot: plugin.path });
|
|
63582
|
+
const links = await linkCachedPluginBins({ binDir, pluginRoot: plugin.path, platform });
|
|
62909
63583
|
for (const link of links) {
|
|
62910
63584
|
log2(`Linked ${link.name} -> ${link.target}`);
|
|
62911
63585
|
}
|
|
@@ -62920,7 +63594,7 @@ async function runCodexInstaller(options = {}) {
|
|
|
62920
63594
|
});
|
|
62921
63595
|
for (const plugin of installed) {
|
|
62922
63596
|
const pluginRoot = agentSourceRoots.get(plugin.name) ?? plugin.path;
|
|
62923
|
-
const agentLinks = await linkCachedPluginAgents({ codexHome, pluginRoot });
|
|
63597
|
+
const agentLinks = await linkCachedPluginAgents({ codexHome, pluginRoot, platform });
|
|
62924
63598
|
for (const link of agentLinks) {
|
|
62925
63599
|
log2(`Linked agent ${link.name} -> ${link.target}`);
|
|
62926
63600
|
const agentName = agentNameFromToml(link.name);
|
|
@@ -62944,41 +63618,57 @@ async function runCodexInstaller(options = {}) {
|
|
|
62944
63618
|
pluginNames: marketplace.plugins.map((plugin) => plugin.name)
|
|
62945
63619
|
});
|
|
62946
63620
|
}
|
|
62947
|
-
const marketplaceRoot =
|
|
63621
|
+
const marketplaceRoot = join30(codexHome, "plugins", "cache", marketplace.name);
|
|
62948
63622
|
await writeCachedMarketplaceManifest({
|
|
62949
63623
|
marketplaceName: marketplace.name,
|
|
62950
63624
|
marketplaceRoot,
|
|
62951
63625
|
plugins: installed
|
|
62952
63626
|
});
|
|
62953
|
-
const configPath =
|
|
63627
|
+
const configPath = join30(codexHome, "config.toml");
|
|
62954
63628
|
await updateCodexConfig({
|
|
62955
63629
|
configPath,
|
|
62956
63630
|
repoRoot: codexPackageRoot,
|
|
62957
63631
|
marketplaceName: marketplace.name,
|
|
62958
63632
|
marketplaceSource: codexMarketplaceSource(marketplaceRoot),
|
|
62959
63633
|
pluginNames: marketplace.plugins.map((plugin) => plugin.name),
|
|
63634
|
+
platform,
|
|
62960
63635
|
trustedHookStates,
|
|
62961
63636
|
agentConfigs: [...agentConfigs.values()].sort((left, right) => left.name.localeCompare(right.name)),
|
|
62962
63637
|
autonomousPermissions: options.autonomousPermissions === true
|
|
62963
63638
|
});
|
|
63639
|
+
const projectCleanup = await repairProjectLocalCodexArtifactsBestEffort({
|
|
63640
|
+
startDirectory: projectDirectory,
|
|
63641
|
+
codexHome,
|
|
63642
|
+
log: log2
|
|
63643
|
+
});
|
|
63644
|
+
for (const configCleanup of projectCleanup.configs) {
|
|
63645
|
+
if (!configCleanup.changed)
|
|
63646
|
+
continue;
|
|
63647
|
+
log2(`Repaired project Codex config ${configCleanup.configPath} (backup: ${configCleanup.backupPath})`);
|
|
63648
|
+
}
|
|
63649
|
+
for (const artifact of projectCleanup.artifacts) {
|
|
63650
|
+
log2(`Found project-local legacy artifact ${artifact.path}; left in place`);
|
|
63651
|
+
}
|
|
62964
63652
|
await trackCodexInstallTelemetry();
|
|
62965
63653
|
return {
|
|
62966
63654
|
marketplaceName: marketplace.name,
|
|
62967
63655
|
installed,
|
|
62968
63656
|
configPath,
|
|
62969
|
-
codexHome
|
|
63657
|
+
codexHome,
|
|
63658
|
+
gitBashPath: gitBashResolution.path,
|
|
63659
|
+
projectCleanup
|
|
62970
63660
|
};
|
|
62971
63661
|
}
|
|
62972
63662
|
function resolveCodexInstallerBinDir(input) {
|
|
62973
63663
|
const explicitBinDir = input.binDir ?? input.env?.CODEX_LOCAL_BIN_DIR;
|
|
62974
63664
|
if (explicitBinDir !== undefined && explicitBinDir.trim().length > 0)
|
|
62975
|
-
return
|
|
63665
|
+
return resolve9(explicitBinDir);
|
|
62976
63666
|
const homeDir = input.homeDir ?? homedir5();
|
|
62977
|
-
const defaultCodexHome =
|
|
62978
|
-
const resolvedCodexHome =
|
|
63667
|
+
const defaultCodexHome = resolve9(homeDir, ".codex");
|
|
63668
|
+
const resolvedCodexHome = resolve9(input.codexHome);
|
|
62979
63669
|
if (resolvedCodexHome !== defaultCodexHome)
|
|
62980
|
-
return
|
|
62981
|
-
return
|
|
63670
|
+
return join30(resolvedCodexHome, "bin");
|
|
63671
|
+
return resolve9(homeDir, ".local", "bin");
|
|
62982
63672
|
}
|
|
62983
63673
|
function agentNameFromToml(fileName) {
|
|
62984
63674
|
return fileName.endsWith(".toml") ? fileName.slice(0, -".toml".length) : fileName;
|
|
@@ -62995,9 +63685,9 @@ async function agentSourceRootsForInstall(input) {
|
|
|
62995
63685
|
return new Map(snapshotPlugins.map((plugin) => [plugin.name, plugin.path]));
|
|
62996
63686
|
}
|
|
62997
63687
|
async function writeCachedMarketplaceManifest(input) {
|
|
62998
|
-
const marketplaceDir =
|
|
63688
|
+
const marketplaceDir = join30(input.marketplaceRoot, ".agents", "plugins");
|
|
62999
63689
|
await mkdir6(marketplaceDir, { recursive: true });
|
|
63000
|
-
await
|
|
63690
|
+
await writeFile7(join30(marketplaceDir, "marketplace.json"), `${JSON.stringify({
|
|
63001
63691
|
name: input.marketplaceName,
|
|
63002
63692
|
plugins: input.plugins.map((plugin) => ({
|
|
63003
63693
|
name: plugin.name,
|
|
@@ -63009,36 +63699,33 @@ async function writeCachedMarketplaceManifest(input) {
|
|
|
63009
63699
|
function legacyCacheMarketplaces(marketplaceName) {
|
|
63010
63700
|
return marketplaceName === "sisyphuslabs" ? SISYPHUS_LEGACY_CACHE_MARKETPLACES : [];
|
|
63011
63701
|
}
|
|
63012
|
-
function codexMarketplaceSource(marketplaceRoot) {
|
|
63013
|
-
return { sourceType: "local", source: marketplaceRoot };
|
|
63014
|
-
}
|
|
63015
63702
|
function findRepoRootFromImporter(importerDir) {
|
|
63016
63703
|
let current = importerDir;
|
|
63017
63704
|
for (let depth = 0;depth <= 5; depth += 1) {
|
|
63018
63705
|
if (isRepoRootWithCodexPlugin(current))
|
|
63019
63706
|
return current;
|
|
63020
|
-
for (const wrapperPackageRoot of [
|
|
63707
|
+
for (const wrapperPackageRoot of [join30(current, "node_modules", "oh-my-openagent"), join30(current, "oh-my-openagent")]) {
|
|
63021
63708
|
if (isRepoRootWithCodexPlugin(wrapperPackageRoot))
|
|
63022
63709
|
return wrapperPackageRoot;
|
|
63023
63710
|
}
|
|
63024
|
-
current =
|
|
63711
|
+
current = resolve9(current, "..");
|
|
63025
63712
|
}
|
|
63026
63713
|
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
63714
|
}
|
|
63028
63715
|
function findRepoRoot(input) {
|
|
63029
63716
|
const wrapperPackageRoot = input.env?.OMO_WRAPPER_PACKAGE_ROOT;
|
|
63030
63717
|
if (wrapperPackageRoot !== undefined && wrapperPackageRoot.trim().length > 0) {
|
|
63031
|
-
const resolvedWrapperPackageRoot =
|
|
63718
|
+
const resolvedWrapperPackageRoot = resolve9(wrapperPackageRoot);
|
|
63032
63719
|
if (isRepoRootWithCodexPlugin(resolvedWrapperPackageRoot))
|
|
63033
63720
|
return resolvedWrapperPackageRoot;
|
|
63034
63721
|
}
|
|
63035
63722
|
return findRepoRootFromImporter(input.importerDir);
|
|
63036
63723
|
}
|
|
63037
63724
|
function isRepoRootWithCodexPlugin(repoRoot) {
|
|
63038
|
-
return
|
|
63725
|
+
return existsSync25(join30(repoRoot, "packages", "omo-codex", "plugin", ".codex-plugin", "plugin.json"));
|
|
63039
63726
|
}
|
|
63040
|
-
function
|
|
63041
|
-
return
|
|
63727
|
+
function codexMarketplaceSource(marketplaceRoot) {
|
|
63728
|
+
return { sourceType: "local", source: marketplaceRoot };
|
|
63042
63729
|
}
|
|
63043
63730
|
async function trackCodexInstallTelemetry() {
|
|
63044
63731
|
try {
|
|
@@ -63052,13 +63739,507 @@ async function trackCodexInstallTelemetry() {
|
|
|
63052
63739
|
return;
|
|
63053
63740
|
}
|
|
63054
63741
|
}
|
|
63742
|
+
// src/cli/install-codex/codex-installation-detection.ts
|
|
63743
|
+
import { execFile } from "child_process";
|
|
63744
|
+
import { existsSync as existsSync26 } from "fs";
|
|
63745
|
+
import { homedir as homedir6 } from "os";
|
|
63746
|
+
import { join as join32, win32 as win322 } from "path";
|
|
63747
|
+
|
|
63748
|
+
// src/shared/bun-which-shim.ts
|
|
63749
|
+
import { accessSync as accessSync3, constants as constants4 } from "fs";
|
|
63750
|
+
import { delimiter, join as join31 } from "path";
|
|
63751
|
+
var runtime3 = globalThis;
|
|
63752
|
+
var IS_BUN2 = typeof runtime3.Bun !== "undefined";
|
|
63753
|
+
function isUnsafeCommandName(commandName) {
|
|
63754
|
+
if (commandName.includes("/") || commandName.includes("\\"))
|
|
63755
|
+
return true;
|
|
63756
|
+
if (commandName === "." || commandName === ".." || commandName.includes(".."))
|
|
63757
|
+
return true;
|
|
63758
|
+
if (/^[a-zA-Z]:/.test(commandName))
|
|
63759
|
+
return true;
|
|
63760
|
+
if (commandName.includes("\x00"))
|
|
63761
|
+
return true;
|
|
63762
|
+
return false;
|
|
63763
|
+
}
|
|
63764
|
+
function isExecutable(filePath) {
|
|
63765
|
+
try {
|
|
63766
|
+
accessSync3(filePath, constants4.X_OK);
|
|
63767
|
+
return true;
|
|
63768
|
+
} catch {
|
|
63769
|
+
return false;
|
|
63770
|
+
}
|
|
63771
|
+
}
|
|
63772
|
+
function resolvePathValue() {
|
|
63773
|
+
if (process.platform === "win32")
|
|
63774
|
+
return process.env.Path ?? process.env.PATH;
|
|
63775
|
+
return process.env.PATH;
|
|
63776
|
+
}
|
|
63777
|
+
function getWindowsCandidates(commandName) {
|
|
63778
|
+
if (process.platform !== "win32")
|
|
63779
|
+
return [commandName];
|
|
63780
|
+
return [commandName, `${commandName}.exe`, `${commandName}.cmd`, `${commandName}.bat`, `${commandName}.com`];
|
|
63781
|
+
}
|
|
63782
|
+
function bunWhich(commandName) {
|
|
63783
|
+
if (!commandName)
|
|
63784
|
+
return null;
|
|
63785
|
+
if (isUnsafeCommandName(commandName))
|
|
63786
|
+
return null;
|
|
63787
|
+
if (IS_BUN2)
|
|
63788
|
+
return runtime3.Bun?.which(commandName) ?? null;
|
|
63789
|
+
const pathValue = resolvePathValue();
|
|
63790
|
+
if (!pathValue)
|
|
63791
|
+
return null;
|
|
63792
|
+
const pathEntries = pathValue.split(delimiter).filter((pathEntry) => pathEntry.length > 0);
|
|
63793
|
+
if (pathEntries.length === 0)
|
|
63794
|
+
return null;
|
|
63795
|
+
const candidateNames = getWindowsCandidates(commandName);
|
|
63796
|
+
for (const pathEntry of pathEntries) {
|
|
63797
|
+
for (const candidateName of candidateNames) {
|
|
63798
|
+
const candidatePath = join31(pathEntry, candidateName);
|
|
63799
|
+
if (isExecutable(candidatePath))
|
|
63800
|
+
return candidatePath;
|
|
63801
|
+
}
|
|
63802
|
+
}
|
|
63803
|
+
return null;
|
|
63804
|
+
}
|
|
63805
|
+
|
|
63806
|
+
// src/cli/install-codex/codex-installation-detection.ts
|
|
63807
|
+
var CODEX_PATH_CHECK_LABEL = "codex (PATH)";
|
|
63808
|
+
var WINDOWS_START_APPS_ARGS = [
|
|
63809
|
+
"-NoProfile",
|
|
63810
|
+
"-Command",
|
|
63811
|
+
"Get-StartApps -Name 'Codex' | Select-Object -First 1 -ExpandProperty AppID"
|
|
63812
|
+
];
|
|
63813
|
+
async function detectCodexInstallation(input = {}) {
|
|
63814
|
+
const platform = input.platform ?? process.platform;
|
|
63815
|
+
const env = input.env ?? process.env;
|
|
63816
|
+
const homeDir = input.homeDir ?? homedir6();
|
|
63817
|
+
const exists6 = input.exists ?? existsSync26;
|
|
63818
|
+
const which = input.which ?? bunWhich;
|
|
63819
|
+
const checkedPaths = [CODEX_PATH_CHECK_LABEL];
|
|
63820
|
+
const cliPath = nonEmptyValue(which("codex"));
|
|
63821
|
+
if (cliPath !== undefined)
|
|
63822
|
+
return { found: true, source: "cli", path: cliPath };
|
|
63823
|
+
if (platform === "darwin") {
|
|
63824
|
+
return detectMacCodexInstallation({ homeDir, exists: exists6, checkedPaths });
|
|
63825
|
+
}
|
|
63826
|
+
if (platform === "win32") {
|
|
63827
|
+
return detectWindowsCodexInstallation({
|
|
63828
|
+
env,
|
|
63829
|
+
exists: exists6,
|
|
63830
|
+
checkedPaths,
|
|
63831
|
+
runCommand: input.runCommand ?? defaultRunCommand2
|
|
63832
|
+
});
|
|
63833
|
+
}
|
|
63834
|
+
return missingCodexInstallation(checkedPaths, "Install OpenAI Codex CLI and make sure `codex` is on PATH.");
|
|
63835
|
+
}
|
|
63836
|
+
function formatCodexInstallationWarning(detection) {
|
|
63837
|
+
return [
|
|
63838
|
+
"Codex CLI or desktop app was not detected. LazyCodex will still install the Codex plugin, but Codex itself must be installed to use it.",
|
|
63839
|
+
detection.hint,
|
|
63840
|
+
`Checked: ${detection.checkedPaths.join(", ")}`
|
|
63841
|
+
].join(`
|
|
63842
|
+
`);
|
|
63843
|
+
}
|
|
63844
|
+
function detectMacCodexInstallation(input) {
|
|
63845
|
+
for (const appPath of macCodexAppPaths(input.homeDir)) {
|
|
63846
|
+
input.checkedPaths.push(appPath);
|
|
63847
|
+
if (input.exists(appPath))
|
|
63848
|
+
return { found: true, source: "mac-app", path: appPath };
|
|
63849
|
+
}
|
|
63850
|
+
for (const dmgPath of macCodexDmgPaths(input.homeDir)) {
|
|
63851
|
+
input.checkedPaths.push(dmgPath);
|
|
63852
|
+
if (input.exists(dmgPath)) {
|
|
63853
|
+
return missingCodexInstallation(input.checkedPaths, `Open ${dmgPath} to install Codex Desktop, or install OpenAI Codex CLI and make sure \`codex\` is on PATH.`, dmgPath);
|
|
63854
|
+
}
|
|
63855
|
+
}
|
|
63856
|
+
return missingCodexInstallation(input.checkedPaths, "Install OpenAI Codex CLI, or install Codex Desktop for macOS.");
|
|
63857
|
+
}
|
|
63858
|
+
async function detectWindowsCodexInstallation(input) {
|
|
63859
|
+
for (const candidate of windowsCodexCliPaths(input.env)) {
|
|
63860
|
+
input.checkedPaths.push(candidate);
|
|
63861
|
+
if (input.exists(candidate))
|
|
63862
|
+
return { found: true, source: "windows-standard-cli", path: candidate };
|
|
63863
|
+
}
|
|
63864
|
+
input.checkedPaths.push("Windows Start Apps: Codex");
|
|
63865
|
+
const appId = await findWindowsCodexStartApp(input.runCommand);
|
|
63866
|
+
if (appId !== null)
|
|
63867
|
+
return { found: true, source: "windows-start-app", appId };
|
|
63868
|
+
return missingCodexInstallation(input.checkedPaths, "Install OpenAI Codex CLI, or install Codex Desktop from Microsoft Store.");
|
|
63869
|
+
}
|
|
63870
|
+
async function findWindowsCodexStartApp(runCommand) {
|
|
63871
|
+
try {
|
|
63872
|
+
const result = await runCommand("powershell.exe", WINDOWS_START_APPS_ARGS);
|
|
63873
|
+
if (!result.success)
|
|
63874
|
+
return null;
|
|
63875
|
+
return nonEmptyValue(result.stdout.trim()) ?? null;
|
|
63876
|
+
} catch (error) {
|
|
63877
|
+
if (error instanceof Error)
|
|
63878
|
+
return null;
|
|
63879
|
+
throw error;
|
|
63880
|
+
}
|
|
63881
|
+
}
|
|
63882
|
+
function macCodexAppPaths(homeDir) {
|
|
63883
|
+
return ["/Applications/Codex.app", join32(homeDir, "Applications", "Codex.app")];
|
|
63884
|
+
}
|
|
63885
|
+
function macCodexDmgPaths(homeDir) {
|
|
63886
|
+
const downloads = join32(homeDir, "Downloads");
|
|
63887
|
+
return [join32(downloads, "codex.dmg"), join32(downloads, "Codex.dmg")];
|
|
63888
|
+
}
|
|
63889
|
+
function windowsCodexCliPaths(env) {
|
|
63890
|
+
const candidates = [];
|
|
63891
|
+
const explicitInstallDir = nonEmptyValue(env.CODEX_INSTALL_DIR);
|
|
63892
|
+
if (explicitInstallDir !== undefined)
|
|
63893
|
+
candidates.push(win322.join(explicitInstallDir, "codex.exe"));
|
|
63894
|
+
const localAppData = nonEmptyValue(env.LOCALAPPDATA) ?? nonEmptyValue(env.LocalAppData);
|
|
63895
|
+
if (localAppData !== undefined) {
|
|
63896
|
+
candidates.push(win322.join(localAppData, "Programs", "OpenAI", "Codex", "bin", "codex.exe"));
|
|
63897
|
+
}
|
|
63898
|
+
return dedupe(candidates);
|
|
63899
|
+
}
|
|
63900
|
+
function missingCodexInstallation(checkedPaths, hint, downloadedInstallerPath) {
|
|
63901
|
+
if (downloadedInstallerPath !== undefined) {
|
|
63902
|
+
return { found: false, checkedPaths, hint, downloadedInstallerPath };
|
|
63903
|
+
}
|
|
63904
|
+
return { found: false, checkedPaths, hint };
|
|
63905
|
+
}
|
|
63906
|
+
function nonEmptyValue(value) {
|
|
63907
|
+
if (value === null || value === undefined)
|
|
63908
|
+
return;
|
|
63909
|
+
const trimmed = value.trim();
|
|
63910
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
63911
|
+
}
|
|
63912
|
+
function dedupe(values) {
|
|
63913
|
+
const seen = new Set;
|
|
63914
|
+
const deduped = [];
|
|
63915
|
+
for (const value of values) {
|
|
63916
|
+
if (seen.has(value))
|
|
63917
|
+
continue;
|
|
63918
|
+
seen.add(value);
|
|
63919
|
+
deduped.push(value);
|
|
63920
|
+
}
|
|
63921
|
+
return deduped;
|
|
63922
|
+
}
|
|
63923
|
+
function defaultRunCommand2(command, args) {
|
|
63924
|
+
return new Promise((resolve10) => {
|
|
63925
|
+
execFile(command, [...args], { encoding: "utf8", windowsHide: true }, (error, stdout) => {
|
|
63926
|
+
resolve10({ success: error === null, stdout });
|
|
63927
|
+
});
|
|
63928
|
+
});
|
|
63929
|
+
}
|
|
63930
|
+
// src/cli/install-codex/codex-cleanup.ts
|
|
63931
|
+
import { lstat as lstat6, readFile as readFile11, readdir as readdir4, rm as rm5 } from "fs/promises";
|
|
63932
|
+
import { homedir as homedir7 } from "os";
|
|
63933
|
+
import { isAbsolute as isAbsolute6, join as join33, relative as relative5, resolve as resolve10 } from "path";
|
|
63934
|
+
|
|
63935
|
+
// src/cli/install-codex/codex-cleanup-config.ts
|
|
63936
|
+
import { lstat as lstat5, mkdir as mkdir7, readFile as readFile10, writeFile as writeFile8 } from "fs/promises";
|
|
63937
|
+
import { dirname as dirname15 } from "path";
|
|
63938
|
+
var MANAGED_MARKETPLACES = ["sisyphuslabs", "lazycodex", "code-yeongyu-codex-plugins"];
|
|
63939
|
+
var MANAGED_CODEX_AGENT_NAMES2 = [
|
|
63940
|
+
"codex-ultrawork-reviewer",
|
|
63941
|
+
"explorer",
|
|
63942
|
+
"librarian",
|
|
63943
|
+
"metis",
|
|
63944
|
+
"momus",
|
|
63945
|
+
"plan"
|
|
63946
|
+
];
|
|
63947
|
+
function cleanupCodexLightConfigText(config) {
|
|
63948
|
+
let nextConfig = config;
|
|
63949
|
+
for (const marketplace of MANAGED_MARKETPLACES) {
|
|
63950
|
+
nextConfig = removeTomlSections2(nextConfig, (header) => header === `marketplaces.${marketplace}`);
|
|
63951
|
+
nextConfig = removeTomlSections2(nextConfig, (header) => isManagedPluginHeader(header, marketplace));
|
|
63952
|
+
nextConfig = removeTomlSections2(nextConfig, (header) => isManagedHookStateHeader(header, marketplace));
|
|
63953
|
+
}
|
|
63954
|
+
nextConfig = removeManagedAgentBlocks(nextConfig);
|
|
63955
|
+
return nextConfig.replace(/\n{3,}/g, `
|
|
63956
|
+
|
|
63957
|
+
`);
|
|
63958
|
+
}
|
|
63959
|
+
async function cleanupCodexConfig(configPath, now) {
|
|
63960
|
+
if (!await configExists(configPath))
|
|
63961
|
+
return { changed: false };
|
|
63962
|
+
const original = await readFile10(configPath, "utf8");
|
|
63963
|
+
const next = cleanupCodexLightConfigText(original);
|
|
63964
|
+
if (next === original)
|
|
63965
|
+
return { changed: false };
|
|
63966
|
+
const backupPath = `${configPath}.backup-${formatBackupTimestamp2(now?.() ?? new Date)}`;
|
|
63967
|
+
await mkdir7(dirname15(configPath), { recursive: true });
|
|
63968
|
+
await writeFile8(backupPath, original);
|
|
63969
|
+
await writeFile8(configPath, `${next.trimEnd()}
|
|
63970
|
+
`);
|
|
63971
|
+
return { changed: true, backupPath };
|
|
63972
|
+
}
|
|
63973
|
+
function removeManagedAgentBlocks(config) {
|
|
63974
|
+
const managedAgentNames = new Set(MANAGED_CODEX_AGENT_NAMES2);
|
|
63975
|
+
return splitTomlSections2(config).filter((section) => {
|
|
63976
|
+
if (section.header === null)
|
|
63977
|
+
return true;
|
|
63978
|
+
const agentName = parseAgentHeaderName2(section.header);
|
|
63979
|
+
if (agentName === null || !managedAgentNames.has(agentName))
|
|
63980
|
+
return true;
|
|
63981
|
+
return !section.text.includes(`config_file = ${JSON.stringify(`./agents/${agentName}.toml`)}`);
|
|
63982
|
+
}).map((section) => section.text).join("");
|
|
63983
|
+
}
|
|
63984
|
+
function isManagedPluginHeader(header, marketplace) {
|
|
63985
|
+
const pluginKey = parsePluginHeaderKey2(header);
|
|
63986
|
+
return pluginKey !== null && pluginKey.endsWith(`@${marketplace}`);
|
|
63987
|
+
}
|
|
63988
|
+
function isManagedHookStateHeader(header, marketplace) {
|
|
63989
|
+
const prefix = "hooks.state.";
|
|
63990
|
+
if (!header.startsWith(prefix))
|
|
63991
|
+
return false;
|
|
63992
|
+
const hookKey = parseJsonString2(header.slice(prefix.length));
|
|
63993
|
+
if (hookKey === null)
|
|
63994
|
+
return false;
|
|
63995
|
+
const separator = hookKey.indexOf(":");
|
|
63996
|
+
if (separator === -1)
|
|
63997
|
+
return false;
|
|
63998
|
+
return hookKey.slice(0, separator).endsWith(`@${marketplace}`);
|
|
63999
|
+
}
|
|
64000
|
+
function removeTomlSections2(config, shouldRemove) {
|
|
64001
|
+
return splitTomlSections2(config).filter((section) => section.header === null || !shouldRemove(section.header)).map((section) => section.text).join("");
|
|
64002
|
+
}
|
|
64003
|
+
function splitTomlSections2(config) {
|
|
64004
|
+
const lines = config.match(/[^\n]*\n?|$/g) ?? [];
|
|
64005
|
+
const sections = [];
|
|
64006
|
+
let current = { header: null, text: "" };
|
|
64007
|
+
for (const line of lines) {
|
|
64008
|
+
if (line.length === 0)
|
|
64009
|
+
break;
|
|
64010
|
+
const header = parseTomlHeader2(line);
|
|
64011
|
+
if (header !== null) {
|
|
64012
|
+
if (current.text.length > 0)
|
|
64013
|
+
sections.push(current);
|
|
64014
|
+
current = { header, text: line };
|
|
64015
|
+
} else {
|
|
64016
|
+
current.text += line;
|
|
64017
|
+
}
|
|
64018
|
+
}
|
|
64019
|
+
if (current.text.length > 0)
|
|
64020
|
+
sections.push(current);
|
|
64021
|
+
return sections;
|
|
64022
|
+
}
|
|
64023
|
+
function parseTomlHeader2(line) {
|
|
64024
|
+
const trimmed = line.trim();
|
|
64025
|
+
if (!trimmed.startsWith("[") || !trimmed.endsWith("]") || trimmed.startsWith("[["))
|
|
64026
|
+
return null;
|
|
64027
|
+
return trimmed.slice(1, -1);
|
|
64028
|
+
}
|
|
64029
|
+
function parsePluginHeaderKey2(header) {
|
|
64030
|
+
const prefix = "plugins.";
|
|
64031
|
+
if (!header.startsWith(prefix))
|
|
64032
|
+
return null;
|
|
64033
|
+
return parseLeadingJsonString2(header.slice(prefix.length));
|
|
64034
|
+
}
|
|
64035
|
+
function parseAgentHeaderName2(header) {
|
|
64036
|
+
const prefix = "agents.";
|
|
64037
|
+
if (!header.startsWith(prefix))
|
|
64038
|
+
return null;
|
|
64039
|
+
const key = header.slice(prefix.length);
|
|
64040
|
+
return key.startsWith('"') ? parseLeadingJsonString2(key) : key;
|
|
64041
|
+
}
|
|
64042
|
+
function parseLeadingJsonString2(value) {
|
|
64043
|
+
if (!value.startsWith('"'))
|
|
64044
|
+
return parseJsonString2(value);
|
|
64045
|
+
let escaped = false;
|
|
64046
|
+
for (let index = 1;index < value.length; index += 1) {
|
|
64047
|
+
const char = value[index];
|
|
64048
|
+
if (escaped) {
|
|
64049
|
+
escaped = false;
|
|
64050
|
+
continue;
|
|
64051
|
+
}
|
|
64052
|
+
if (char === "\\") {
|
|
64053
|
+
escaped = true;
|
|
64054
|
+
continue;
|
|
64055
|
+
}
|
|
64056
|
+
if (char === '"')
|
|
64057
|
+
return parseJsonString2(value.slice(0, index + 1));
|
|
64058
|
+
}
|
|
64059
|
+
return null;
|
|
64060
|
+
}
|
|
64061
|
+
function parseJsonString2(value) {
|
|
64062
|
+
try {
|
|
64063
|
+
const parsed = JSON.parse(value);
|
|
64064
|
+
return typeof parsed === "string" ? parsed : null;
|
|
64065
|
+
} catch (error) {
|
|
64066
|
+
if (error instanceof Error)
|
|
64067
|
+
return null;
|
|
64068
|
+
return null;
|
|
64069
|
+
}
|
|
64070
|
+
}
|
|
64071
|
+
function formatBackupTimestamp2(date) {
|
|
64072
|
+
return date.toISOString().replace(/[:.]/g, "-");
|
|
64073
|
+
}
|
|
64074
|
+
async function configExists(path7) {
|
|
64075
|
+
try {
|
|
64076
|
+
await lstat5(path7);
|
|
64077
|
+
return true;
|
|
64078
|
+
} catch (error) {
|
|
64079
|
+
if (nodeErrorCode2(error) === "ENOENT")
|
|
64080
|
+
return false;
|
|
64081
|
+
throw error;
|
|
64082
|
+
}
|
|
64083
|
+
}
|
|
64084
|
+
function nodeErrorCode2(error) {
|
|
64085
|
+
if (!(error instanceof Error) || !("code" in error))
|
|
64086
|
+
return null;
|
|
64087
|
+
return typeof error.code === "string" ? error.code : null;
|
|
64088
|
+
}
|
|
64089
|
+
|
|
64090
|
+
// src/cli/install-codex/codex-cleanup.ts
|
|
64091
|
+
var INSTALLED_AGENTS_MANIFEST = ".installed-agents.json";
|
|
64092
|
+
async function cleanupCodexLight(input = {}) {
|
|
64093
|
+
const env = input.env ?? process.env;
|
|
64094
|
+
const codexHome = resolve10(input.codexHome ?? env.CODEX_HOME ?? join33(homedir7(), ".codex"));
|
|
64095
|
+
const configPath = join33(codexHome, "config.toml");
|
|
64096
|
+
const agentPaths = await collectInstalledAgentPaths(codexHome);
|
|
64097
|
+
const configCleanup = await cleanupCodexConfig(configPath, input.now);
|
|
64098
|
+
const agentCleanup = await removeManifestListedAgentLinks(codexHome, agentPaths);
|
|
64099
|
+
const removedPaths = [];
|
|
64100
|
+
for (const path7 of managedGlobalStatePaths(codexHome)) {
|
|
64101
|
+
if (await removePathIfExists(path7))
|
|
64102
|
+
removedPaths.push(path7);
|
|
64103
|
+
}
|
|
64104
|
+
const projectDirectory = input.projectDirectory ?? env.OMO_CODEX_PROJECT ?? process.cwd();
|
|
64105
|
+
const projectCleanup = await repairProjectLocalCodexArtifactsBestEffort({
|
|
64106
|
+
startDirectory: projectDirectory,
|
|
64107
|
+
codexHome,
|
|
64108
|
+
now: input.now,
|
|
64109
|
+
log: () => {
|
|
64110
|
+
return;
|
|
64111
|
+
}
|
|
64112
|
+
});
|
|
64113
|
+
return {
|
|
64114
|
+
codexHome,
|
|
64115
|
+
configPath,
|
|
64116
|
+
configChanged: configCleanup.changed,
|
|
64117
|
+
configBackupPath: configCleanup.backupPath,
|
|
64118
|
+
removedPaths,
|
|
64119
|
+
removedAgentLinks: agentCleanup.removed,
|
|
64120
|
+
skippedAgentLinks: agentCleanup.skipped,
|
|
64121
|
+
projectCleanup
|
|
64122
|
+
};
|
|
64123
|
+
}
|
|
64124
|
+
function managedGlobalStatePaths(codexHome) {
|
|
64125
|
+
return [
|
|
64126
|
+
join33(codexHome, "plugins", "cache", "sisyphuslabs"),
|
|
64127
|
+
join33(codexHome, ".tmp", "marketplaces", "sisyphuslabs")
|
|
64128
|
+
];
|
|
64129
|
+
}
|
|
64130
|
+
async function collectInstalledAgentPaths(codexHome) {
|
|
64131
|
+
const manifestPaths = [
|
|
64132
|
+
join33(codexHome, ".tmp", "marketplaces", "sisyphuslabs", "plugins", "omo", INSTALLED_AGENTS_MANIFEST)
|
|
64133
|
+
];
|
|
64134
|
+
const versionRoot = join33(codexHome, "plugins", "cache", "sisyphuslabs", "omo");
|
|
64135
|
+
if (await exists6(versionRoot)) {
|
|
64136
|
+
const entries = await readdir4(versionRoot, { withFileTypes: true });
|
|
64137
|
+
for (const entry of entries) {
|
|
64138
|
+
if (entry.isDirectory())
|
|
64139
|
+
manifestPaths.push(join33(versionRoot, entry.name, INSTALLED_AGENTS_MANIFEST));
|
|
64140
|
+
}
|
|
64141
|
+
}
|
|
64142
|
+
const paths = new Set;
|
|
64143
|
+
for (const manifestPath of manifestPaths) {
|
|
64144
|
+
for (const path7 of await readInstalledAgentManifest(manifestPath)) {
|
|
64145
|
+
paths.add(path7);
|
|
64146
|
+
}
|
|
64147
|
+
}
|
|
64148
|
+
return [...paths].sort();
|
|
64149
|
+
}
|
|
64150
|
+
async function readInstalledAgentManifest(manifestPath) {
|
|
64151
|
+
if (!await exists6(manifestPath))
|
|
64152
|
+
return [];
|
|
64153
|
+
const parsed = JSON.parse(await readFile11(manifestPath, "utf8"));
|
|
64154
|
+
if (!isRecord14(parsed) || !Array.isArray(parsed.agents))
|
|
64155
|
+
return [];
|
|
64156
|
+
return parsed.agents.filter((path7) => typeof path7 === "string");
|
|
64157
|
+
}
|
|
64158
|
+
async function removeManifestListedAgentLinks(codexHome, paths) {
|
|
64159
|
+
const agentsDir = join33(codexHome, "agents");
|
|
64160
|
+
const removed = [];
|
|
64161
|
+
const skipped = [];
|
|
64162
|
+
for (const path7 of paths) {
|
|
64163
|
+
if (!isSafeManagedAgentPath(agentsDir, path7)) {
|
|
64164
|
+
skipped.push(path7);
|
|
64165
|
+
continue;
|
|
64166
|
+
}
|
|
64167
|
+
const entryStat = await maybeLstat2(path7);
|
|
64168
|
+
if (entryStat === null)
|
|
64169
|
+
continue;
|
|
64170
|
+
if (entryStat.isDirectory() && !entryStat.isSymbolicLink()) {
|
|
64171
|
+
skipped.push(path7);
|
|
64172
|
+
continue;
|
|
64173
|
+
}
|
|
64174
|
+
await rm5(path7, { force: true });
|
|
64175
|
+
removed.push(path7);
|
|
64176
|
+
}
|
|
64177
|
+
return { removed, skipped };
|
|
64178
|
+
}
|
|
64179
|
+
function isSafeManagedAgentPath(agentsDir, path7) {
|
|
64180
|
+
if (!isAbsolute6(path7))
|
|
64181
|
+
return false;
|
|
64182
|
+
const relativePath = relative5(agentsDir, path7);
|
|
64183
|
+
if (relativePath === "" || relativePath.startsWith("..") || isAbsolute6(relativePath))
|
|
64184
|
+
return false;
|
|
64185
|
+
const fileName = relativePath.split(/[\\/]/).pop();
|
|
64186
|
+
if (fileName === undefined)
|
|
64187
|
+
return false;
|
|
64188
|
+
return MANAGED_CODEX_AGENT_NAMES2.some((agentName) => fileName === `${agentName}.toml`);
|
|
64189
|
+
}
|
|
64190
|
+
async function removePathIfExists(path7) {
|
|
64191
|
+
if (!await exists6(path7))
|
|
64192
|
+
return false;
|
|
64193
|
+
await rm5(path7, { recursive: true, force: true });
|
|
64194
|
+
return true;
|
|
64195
|
+
}
|
|
64196
|
+
async function exists6(path7) {
|
|
64197
|
+
return await maybeLstat2(path7) !== null;
|
|
64198
|
+
}
|
|
64199
|
+
async function maybeLstat2(path7) {
|
|
64200
|
+
try {
|
|
64201
|
+
return await lstat6(path7);
|
|
64202
|
+
} catch (error) {
|
|
64203
|
+
if (nodeErrorCode3(error) === "ENOENT")
|
|
64204
|
+
return null;
|
|
64205
|
+
throw error;
|
|
64206
|
+
}
|
|
64207
|
+
}
|
|
64208
|
+
function nodeErrorCode3(error) {
|
|
64209
|
+
if (!(error instanceof Error) || !("code" in error))
|
|
64210
|
+
return null;
|
|
64211
|
+
return typeof error.code === "string" ? error.code : null;
|
|
64212
|
+
}
|
|
64213
|
+
function isRecord14(value) {
|
|
64214
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
64215
|
+
}
|
|
63055
64216
|
// src/cli/star-request.ts
|
|
64217
|
+
import { execFile as execFile2 } from "child_process";
|
|
64218
|
+
import { promisify as promisify2 } from "util";
|
|
63056
64219
|
var STAR_REPOSITORIES = [
|
|
63057
64220
|
"code-yeongyu/oh-my-openagent",
|
|
63058
64221
|
"code-yeongyu/lazycodex"
|
|
63059
64222
|
];
|
|
63060
|
-
|
|
63061
|
-
|
|
64223
|
+
var PLATFORM_REPOSITORIES = {
|
|
64224
|
+
opencode: ["code-yeongyu/oh-my-openagent"],
|
|
64225
|
+
codex: STAR_REPOSITORIES,
|
|
64226
|
+
both: STAR_REPOSITORIES
|
|
64227
|
+
};
|
|
64228
|
+
var execFileAsync = promisify2(execFile2);
|
|
64229
|
+
async function runGitHubStarCommand(repository) {
|
|
64230
|
+
await execFileAsync("gh", ["api", "--silent", "--method", "PUT", `/user/starred/${repository}`]);
|
|
64231
|
+
}
|
|
64232
|
+
async function starGitHubRepositories(platform = "both", runCommand = runGitHubStarCommand) {
|
|
64233
|
+
const results = [];
|
|
64234
|
+
for (const repository of PLATFORM_REPOSITORIES[platform]) {
|
|
64235
|
+
try {
|
|
64236
|
+
await runCommand(repository);
|
|
64237
|
+
results.push({ repository, ok: true });
|
|
64238
|
+
} catch (error) {
|
|
64239
|
+
results.push({ repository, ok: false, error: error instanceof Error ? error.message : String(error) });
|
|
64240
|
+
}
|
|
64241
|
+
}
|
|
64242
|
+
return results;
|
|
63062
64243
|
}
|
|
63063
64244
|
|
|
63064
64245
|
// src/cli/cli-installer.ts
|
|
@@ -63133,10 +64314,10 @@ async function runCliInstaller(args, version2) {
|
|
|
63133
64314
|
printSuccess(`Config written ${SYMBOLS.arrow} ${import_picocolors3.default.dim(omoResult.configPath)}`);
|
|
63134
64315
|
}
|
|
63135
64316
|
printBox(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
|
|
63136
|
-
if (!config.hasClaude) {
|
|
64317
|
+
if (config.hasOpenCode && !config.hasClaude) {
|
|
63137
64318
|
printInfo("Note: Sisyphus agent performs best with Claude Opus 4.5+. " + "Other models work but may have reduced orchestration quality.");
|
|
63138
64319
|
}
|
|
63139
|
-
if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen && !config.hasVercelAiGateway) {
|
|
64320
|
+
if (config.hasOpenCode && !config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen && !config.hasVercelAiGateway) {
|
|
63140
64321
|
printWarning("No model providers configured. Using opencode/big-pickle as fallback.");
|
|
63141
64322
|
}
|
|
63142
64323
|
console.log(`${SYMBOLS.star} ${import_picocolors3.default.bold(import_picocolors3.default.green(isUpdate ? "Configuration updated!" : "Installation complete!"))}`);
|
|
@@ -63165,11 +64346,7 @@ async function runCliInstaller(args, version2) {
|
|
|
63165
64346
|
printBox(`${import_picocolors3.default.bold("Pro Tip:")} Include ${import_picocolors3.default.cyan("ultrawork")} (or ${import_picocolors3.default.cyan("ulw")}) in your prompt.
|
|
63166
64347
|
` + `All features work like magic-parallel agents, background tasks,
|
|
63167
64348
|
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
63168
|
-
|
|
63169
|
-
for (const repository of STAR_REPOSITORIES) {
|
|
63170
|
-
console.log(` ${import_picocolors3.default.dim(formatGitHubStarCommand(repository))}`);
|
|
63171
|
-
}
|
|
63172
|
-
console.log();
|
|
64349
|
+
await maybePromptForGitHubStars(config.platform);
|
|
63173
64350
|
console.log(import_picocolors3.default.dim("oMoMoMoMo... Enjoy!"));
|
|
63174
64351
|
console.log();
|
|
63175
64352
|
if (hasOpenCode && (config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
@@ -63180,6 +64357,34 @@ async function runCliInstaller(args, version2) {
|
|
|
63180
64357
|
}
|
|
63181
64358
|
return 0;
|
|
63182
64359
|
}
|
|
64360
|
+
async function maybePromptForGitHubStars(platform) {
|
|
64361
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY)
|
|
64362
|
+
return;
|
|
64363
|
+
const readline = createInterface2({ input: process.stdin, output: process.stdout });
|
|
64364
|
+
try {
|
|
64365
|
+
const answer = await readline.question(`${SYMBOLS.star} ${import_picocolors3.default.yellow("Star the repos on GitHub?")} ${import_picocolors3.default.dim("[y/N]")} `);
|
|
64366
|
+
if (!isYes(answer))
|
|
64367
|
+
return;
|
|
64368
|
+
} finally {
|
|
64369
|
+
readline.close();
|
|
64370
|
+
}
|
|
64371
|
+
const results = await starGitHubRepositories(platform);
|
|
64372
|
+
const failed = results.filter((result) => !result.ok);
|
|
64373
|
+
if (failed.length === 0) {
|
|
64374
|
+
printSuccess("Starred GitHub repositories");
|
|
64375
|
+
console.log();
|
|
64376
|
+
return;
|
|
64377
|
+
}
|
|
64378
|
+
printWarning("Could not star every repository. Make sure GitHub CLI is installed and authenticated.");
|
|
64379
|
+
for (const result of failed) {
|
|
64380
|
+
console.log(` ${SYMBOLS.bullet} ${result.repository}`);
|
|
64381
|
+
}
|
|
64382
|
+
console.log();
|
|
64383
|
+
}
|
|
64384
|
+
function isYes(value) {
|
|
64385
|
+
const normalized = value.trim().toLowerCase();
|
|
64386
|
+
return normalized === "y" || normalized === "yes";
|
|
64387
|
+
}
|
|
63183
64388
|
|
|
63184
64389
|
// node_modules/.bun/@clack+core@1.3.1/node_modules/@clack/core/dist/index.mjs
|
|
63185
64390
|
import { styleText as v } from "util";
|
|
@@ -63828,6 +65033,24 @@ var Q = class extends m {
|
|
|
63828
65033
|
}
|
|
63829
65034
|
}
|
|
63830
65035
|
};
|
|
65036
|
+
|
|
65037
|
+
class X extends m {
|
|
65038
|
+
get cursor() {
|
|
65039
|
+
return this.value ? 0 : 1;
|
|
65040
|
+
}
|
|
65041
|
+
get _value() {
|
|
65042
|
+
return this.cursor === 0;
|
|
65043
|
+
}
|
|
65044
|
+
constructor(t) {
|
|
65045
|
+
super(t, false), this.value = !!t.initialValue, this.on("userInput", () => {
|
|
65046
|
+
this.value = this._value;
|
|
65047
|
+
}), this.on("confirm", (s) => {
|
|
65048
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = s, this.state = "submit", this.close();
|
|
65049
|
+
}), this.on("cursor", () => {
|
|
65050
|
+
this.value = !this.value;
|
|
65051
|
+
});
|
|
65052
|
+
}
|
|
65053
|
+
}
|
|
63831
65054
|
var Z = { Y: { type: "year", len: 4 }, M: { type: "month", len: 2 }, D: { type: "day", len: 2 } };
|
|
63832
65055
|
function P(r) {
|
|
63833
65056
|
return [...r].map((t) => Z[t]);
|
|
@@ -64265,6 +65488,33 @@ var F2 = ({ cursor: t, options: i2, style: s, output: r = process.stdout, maxIte
|
|
|
64265
65488
|
S2.push(G2);
|
|
64266
65489
|
return h2 && S2.push(l), S2;
|
|
64267
65490
|
};
|
|
65491
|
+
var ue = (t) => {
|
|
65492
|
+
const i2 = t.active ?? "Yes", s = t.inactive ?? "No";
|
|
65493
|
+
return new X({ active: i2, inactive: s, signal: t.signal, input: t.input, output: t.output, initialValue: t.initialValue ?? true, render() {
|
|
65494
|
+
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)}
|
|
65495
|
+
` : ""}${a}
|
|
65496
|
+
`, o = this.value ? i2 : s;
|
|
65497
|
+
switch (this.state) {
|
|
65498
|
+
case "submit": {
|
|
65499
|
+
const l = r ? `${e("gray", $2)} ` : "";
|
|
65500
|
+
return `${c}${l}${e("dim", o)}`;
|
|
65501
|
+
}
|
|
65502
|
+
case "cancel": {
|
|
65503
|
+
const l = r ? `${e("gray", $2)} ` : "";
|
|
65504
|
+
return `${c}${l}${e(["strikethrough", "dim"], o)}${r ? `
|
|
65505
|
+
${e("gray", $2)}` : ""}`;
|
|
65506
|
+
}
|
|
65507
|
+
default: {
|
|
65508
|
+
const l = r ? `${e("cyan", $2)} ` : "", d = r ? e("cyan", x2) : "";
|
|
65509
|
+
return `${c}${l}${this.value ? `${e("green", z2)} ${i2}` : `${e("dim", U2)} ${e("dim", i2)}`}${t.vertical ? r ? `
|
|
65510
|
+
${e("cyan", $2)} ` : `
|
|
65511
|
+
` : ` ${e("dim", "/")} `}${this.value ? `${e("dim", U2)} ${e("dim", s)}` : `${e("green", z2)} ${s}`}
|
|
65512
|
+
${d}
|
|
65513
|
+
`;
|
|
65514
|
+
}
|
|
65515
|
+
}
|
|
65516
|
+
} }).prompt();
|
|
65517
|
+
};
|
|
64268
65518
|
var R2 = { message: (t = [], { symbol: i2 = e("gray", $2), secondarySymbol: s = e("gray", $2), output: r = process.stdout, spacing: u = 1, withGuide: n } = {}) => {
|
|
64269
65519
|
const a = [], c = n ?? h.withGuide, o = c ? s : "", l = c ? `${i2} ` : "", d = c ? `${s} ` : "";
|
|
64270
65520
|
for (let p2 = 0;p2 < u; p2++)
|
|
@@ -64687,15 +65937,19 @@ async function runTuiInstaller(args, version2) {
|
|
|
64687
65937
|
}
|
|
64688
65938
|
spinner.stop(`Config written to ${import_picocolors4.default.cyan(omoResult.configPath)}`);
|
|
64689
65939
|
}
|
|
64690
|
-
if (!config.hasClaude) {
|
|
65940
|
+
if (config.hasOpenCode && !config.hasClaude) {
|
|
64691
65941
|
R2.info(`${import_picocolors4.default.bold("Note:")} Sisyphus agent performs best with Claude Opus 4.5+.
|
|
64692
65942
|
` + `Other models work but may have reduced orchestration quality.`);
|
|
64693
65943
|
}
|
|
64694
|
-
if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen && !config.hasVercelAiGateway) {
|
|
65944
|
+
if (config.hasOpenCode && !config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen && !config.hasVercelAiGateway) {
|
|
64695
65945
|
R2.warn("No model providers configured. Using opencode/big-pickle as fallback.");
|
|
64696
65946
|
}
|
|
64697
65947
|
Se(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
|
|
64698
65948
|
if (config.hasCodex) {
|
|
65949
|
+
const codexInstallation = await detectCodexInstallation();
|
|
65950
|
+
if (!codexInstallation.found) {
|
|
65951
|
+
R2.warn(formatCodexInstallationWarning(codexInstallation));
|
|
65952
|
+
}
|
|
64699
65953
|
spinner.start("Installing Codex harness adapter");
|
|
64700
65954
|
try {
|
|
64701
65955
|
const codexResult = await runCodexInstaller({ autonomousPermissions: config.codexAutonomous });
|
|
@@ -64720,9 +65974,20 @@ async function runTuiInstaller(args, version2) {
|
|
|
64720
65974
|
Se(`Include ${import_picocolors4.default.cyan("ultrawork")} (or ${import_picocolors4.default.cyan("ulw")}) in your prompt.
|
|
64721
65975
|
` + `All features work like magic-parallel agents, background tasks,
|
|
64722
65976
|
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
64723
|
-
|
|
64724
|
-
|
|
64725
|
-
|
|
65977
|
+
const shouldStar = await ue({
|
|
65978
|
+
message: "Star the repos on GitHub?",
|
|
65979
|
+
initialValue: false
|
|
65980
|
+
});
|
|
65981
|
+
if (!q(shouldStar) && shouldStar) {
|
|
65982
|
+
spinner.start("Starring GitHub repositories");
|
|
65983
|
+
const results = await starGitHubRepositories(selectedPlatform);
|
|
65984
|
+
const failed = results.filter((result) => !result.ok);
|
|
65985
|
+
if (failed.length === 0) {
|
|
65986
|
+
spinner.stop("GitHub repositories starred");
|
|
65987
|
+
} else {
|
|
65988
|
+
spinner.stop("Could not star every repository");
|
|
65989
|
+
R2.warn("Make sure GitHub CLI is installed and authenticated.");
|
|
65990
|
+
}
|
|
64726
65991
|
}
|
|
64727
65992
|
ye(import_picocolors4.default.green("oMoMoMoMo... Enjoy!"));
|
|
64728
65993
|
if (config.hasOpenCode && (config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
@@ -64751,6 +66016,71 @@ async function install(args) {
|
|
|
64751
66016
|
return args.tui ? runTuiInstaller(args, VERSION) : runCliInstaller(args, VERSION);
|
|
64752
66017
|
}
|
|
64753
66018
|
|
|
66019
|
+
// src/cli/cleanup.ts
|
|
66020
|
+
function resolveCleanupPlatform(options, invocationName = process.env.OMO_INVOCATION_NAME) {
|
|
66021
|
+
if (options.platform !== undefined)
|
|
66022
|
+
return options.platform;
|
|
66023
|
+
return invocationName === "lazycodex" || invocationName === "lazycodex-ai" ? "codex" : undefined;
|
|
66024
|
+
}
|
|
66025
|
+
async function cleanup(options) {
|
|
66026
|
+
if (options.platform !== "codex") {
|
|
66027
|
+
console.error("Error: cleanup currently supports only --platform=codex");
|
|
66028
|
+
return 1;
|
|
66029
|
+
}
|
|
66030
|
+
const result = await cleanupCodexLight({
|
|
66031
|
+
codexHome: options.codexHome,
|
|
66032
|
+
projectDirectory: options.project
|
|
66033
|
+
});
|
|
66034
|
+
if (options.json === true) {
|
|
66035
|
+
console.log(JSON.stringify(result, null, 2));
|
|
66036
|
+
return 0;
|
|
66037
|
+
}
|
|
66038
|
+
console.log(`Codex Light cleanup complete: ${result.codexHome}`);
|
|
66039
|
+
if (result.configChanged) {
|
|
66040
|
+
console.log(`- Updated ${result.configPath}`);
|
|
66041
|
+
if (result.configBackupPath !== undefined)
|
|
66042
|
+
console.log(`- Backup ${result.configBackupPath}`);
|
|
66043
|
+
} else {
|
|
66044
|
+
console.log(`- No managed Codex config blocks found in ${result.configPath}`);
|
|
66045
|
+
}
|
|
66046
|
+
for (const path7 of result.removedPaths) {
|
|
66047
|
+
console.log(`- Removed ${path7}`);
|
|
66048
|
+
}
|
|
66049
|
+
for (const path7 of result.removedAgentLinks) {
|
|
66050
|
+
console.log(`- Removed managed agent link ${path7}`);
|
|
66051
|
+
}
|
|
66052
|
+
for (const path7 of result.skippedAgentLinks) {
|
|
66053
|
+
console.log(`- Skipped agent path outside managed scope ${path7}`);
|
|
66054
|
+
}
|
|
66055
|
+
if (result.projectCleanup.changed) {
|
|
66056
|
+
console.log(`- Repaired project-local Codex config ${result.projectCleanup.configPath}`);
|
|
66057
|
+
}
|
|
66058
|
+
for (const artifact of result.projectCleanup.artifacts) {
|
|
66059
|
+
console.log(`- Left project-local artifact in place ${artifact.path}`);
|
|
66060
|
+
}
|
|
66061
|
+
return 0;
|
|
66062
|
+
}
|
|
66063
|
+
|
|
66064
|
+
// src/cli/cleanup-command.ts
|
|
66065
|
+
function configureCleanupCommand(program2) {
|
|
66066
|
+
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", `
|
|
66067
|
+
Examples:
|
|
66068
|
+
$ npx lazycodex-ai cleanup
|
|
66069
|
+
$ omo cleanup --platform=codex
|
|
66070
|
+
$ omo cleanup --platform=codex --project /path/to/project
|
|
66071
|
+
`).action(async (options) => {
|
|
66072
|
+
const rootOptions = program2.opts();
|
|
66073
|
+
const platform = resolveCleanupPlatform({ platform: options.platform ?? rootOptions.platform });
|
|
66074
|
+
const exitCode = await cleanup({
|
|
66075
|
+
platform,
|
|
66076
|
+
codexHome: options.codexHome,
|
|
66077
|
+
project: options.project,
|
|
66078
|
+
json: options.json ?? false
|
|
66079
|
+
});
|
|
66080
|
+
process.exit(exitCode);
|
|
66081
|
+
});
|
|
66082
|
+
}
|
|
66083
|
+
|
|
64754
66084
|
// src/cli/run/runner.ts
|
|
64755
66085
|
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
64756
66086
|
|
|
@@ -64758,6 +66088,7 @@ var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
|
64758
66088
|
function createEventState() {
|
|
64759
66089
|
return {
|
|
64760
66090
|
mainSessionIdle: false,
|
|
66091
|
+
mainSessionStarted: false,
|
|
64761
66092
|
mainSessionError: false,
|
|
64762
66093
|
lastError: null,
|
|
64763
66094
|
lastOutput: "",
|
|
@@ -65173,10 +66504,12 @@ function handleSessionStatus(ctx, payload, state) {
|
|
|
65173
66504
|
return;
|
|
65174
66505
|
if (props?.status?.type === "busy") {
|
|
65175
66506
|
state.mainSessionIdle = false;
|
|
66507
|
+
state.mainSessionStarted = true;
|
|
65176
66508
|
} else if (props?.status?.type === "idle") {
|
|
65177
66509
|
state.mainSessionIdle = true;
|
|
65178
66510
|
} else if (props?.status?.type === "retry") {
|
|
65179
66511
|
state.mainSessionIdle = false;
|
|
66512
|
+
state.mainSessionStarted = true;
|
|
65180
66513
|
}
|
|
65181
66514
|
}
|
|
65182
66515
|
function handleSessionError(ctx, payload, state) {
|
|
@@ -65216,6 +66549,7 @@ function handleMessagePartUpdated(ctx, payload, state) {
|
|
|
65216
66549
|
const padded = writePaddedText(newText, state.thinkingAtLineStart);
|
|
65217
66550
|
process.stdout.write(import_picocolors7.default.dim(padded.output));
|
|
65218
66551
|
state.thinkingAtLineStart = padded.atLineStart;
|
|
66552
|
+
state.mainSessionStarted = true;
|
|
65219
66553
|
state.hasReceivedMeaningfulWork = true;
|
|
65220
66554
|
}
|
|
65221
66555
|
state.lastReasoningText = reasoningText;
|
|
@@ -65228,6 +66562,7 @@ function handleMessagePartUpdated(ctx, payload, state) {
|
|
|
65228
66562
|
const padded = writePaddedText(newText, state.textAtLineStart);
|
|
65229
66563
|
process.stdout.write(padded.output);
|
|
65230
66564
|
state.textAtLineStart = padded.atLineStart;
|
|
66565
|
+
state.mainSessionStarted = true;
|
|
65231
66566
|
state.hasReceivedMeaningfulWork = true;
|
|
65232
66567
|
}
|
|
65233
66568
|
state.lastPartText = part.text;
|
|
@@ -65239,6 +66574,7 @@ function handleMessagePartUpdated(ctx, payload, state) {
|
|
|
65239
66574
|
}
|
|
65240
66575
|
}
|
|
65241
66576
|
if (part.type === "tool") {
|
|
66577
|
+
state.mainSessionStarted = true;
|
|
65242
66578
|
handleToolPart(ctx, part, state);
|
|
65243
66579
|
}
|
|
65244
66580
|
}
|
|
@@ -65264,6 +66600,7 @@ function handleMessagePartDelta(ctx, payload, state) {
|
|
|
65264
66600
|
process.stdout.write(import_picocolors7.default.dim(padded2.output));
|
|
65265
66601
|
state.thinkingAtLineStart = padded2.atLineStart;
|
|
65266
66602
|
state.lastReasoningText += delta;
|
|
66603
|
+
state.mainSessionStarted = true;
|
|
65267
66604
|
state.hasReceivedMeaningfulWork = true;
|
|
65268
66605
|
return;
|
|
65269
66606
|
}
|
|
@@ -65272,6 +66609,7 @@ function handleMessagePartDelta(ctx, payload, state) {
|
|
|
65272
66609
|
process.stdout.write(padded.output);
|
|
65273
66610
|
state.textAtLineStart = padded.atLineStart;
|
|
65274
66611
|
state.lastPartText += delta;
|
|
66612
|
+
state.mainSessionStarted = true;
|
|
65275
66613
|
state.hasReceivedMeaningfulWork = true;
|
|
65276
66614
|
}
|
|
65277
66615
|
function handleToolPart(_ctx, part, state) {
|
|
@@ -65317,11 +66655,15 @@ function handleMessageUpdated(ctx, payload, state) {
|
|
|
65317
66655
|
if (messageID && role) {
|
|
65318
66656
|
state.messageRoleById[messageID] = role;
|
|
65319
66657
|
}
|
|
66658
|
+
if (messageID) {
|
|
66659
|
+
state.mainSessionStarted = true;
|
|
66660
|
+
}
|
|
65320
66661
|
if (props?.info?.role !== "assistant")
|
|
65321
66662
|
return;
|
|
65322
66663
|
const isNewMessage = !messageID || messageID !== state.currentMessageId;
|
|
65323
66664
|
if (isNewMessage) {
|
|
65324
66665
|
state.currentMessageId = messageID;
|
|
66666
|
+
state.mainSessionStarted = true;
|
|
65325
66667
|
state.hasReceivedMeaningfulWork = true;
|
|
65326
66668
|
state.messageCount++;
|
|
65327
66669
|
state.lastPartText = "";
|
|
@@ -65357,6 +66699,7 @@ function handleToolExecute(ctx, payload, state) {
|
|
|
65357
66699
|
return;
|
|
65358
66700
|
const toolName = props?.name || "unknown";
|
|
65359
66701
|
state.currentTool = toolName;
|
|
66702
|
+
state.mainSessionStarted = true;
|
|
65360
66703
|
const header = formatToolHeader(toolName, props?.input ?? {});
|
|
65361
66704
|
const suffix = header.description ? ` ${import_picocolors7.default.dim(header.description)}` : "";
|
|
65362
66705
|
state.hasReceivedMeaningfulWork = true;
|
|
@@ -65451,7 +66794,7 @@ async function processEvents(ctx, stream, state) {
|
|
|
65451
66794
|
}
|
|
65452
66795
|
// src/plugin-config.ts
|
|
65453
66796
|
import * as fs4 from "fs";
|
|
65454
|
-
import { homedir as
|
|
66797
|
+
import { homedir as homedir8 } from "os";
|
|
65455
66798
|
import * as path7 from "path";
|
|
65456
66799
|
|
|
65457
66800
|
// node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
@@ -67065,8 +68408,8 @@ function emoji() {
|
|
|
67065
68408
|
}
|
|
67066
68409
|
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
68410
|
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(
|
|
68411
|
+
var mac = (delimiter2) => {
|
|
68412
|
+
const escapedDelim = escapeRegex(delimiter2 ?? ":");
|
|
67070
68413
|
return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
|
|
67071
68414
|
};
|
|
67072
68415
|
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 +73156,9 @@ var error17 = () => {
|
|
|
71813
73156
|
if (issue2.values.length === 2) {
|
|
71814
73157
|
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
73158
|
}
|
|
71816
|
-
const
|
|
73159
|
+
const lastValue2 = stringified[stringified.length - 1];
|
|
71817
73160
|
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 ${
|
|
73161
|
+
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
73162
|
}
|
|
71820
73163
|
case "too_big": {
|
|
71821
73164
|
const sizing = getSizing(issue2.origin);
|
|
@@ -80025,7 +81368,6 @@ var GitMasterConfigSchema = exports_external.object({
|
|
|
80025
81368
|
// src/config/schema/hooks.ts
|
|
80026
81369
|
var HookNameSchema = exports_external.enum([
|
|
80027
81370
|
"todo-continuation-enforcer",
|
|
80028
|
-
"context-window-monitor",
|
|
80029
81371
|
"session-recovery",
|
|
80030
81372
|
"session-notification",
|
|
80031
81373
|
"comment-checker",
|
|
@@ -80480,7 +81822,7 @@ function addAgentOrderWarnings(configPath, agentOrder) {
|
|
|
80480
81822
|
});
|
|
80481
81823
|
}
|
|
80482
81824
|
function resolveHomeDirectory() {
|
|
80483
|
-
return process.env.HOME ?? process.env.USERPROFILE ??
|
|
81825
|
+
return process.env.HOME ?? process.env.USERPROFILE ?? homedir8();
|
|
80484
81826
|
}
|
|
80485
81827
|
function resolveConfigPathAfterLegacyMigration(detectedPath) {
|
|
80486
81828
|
if (!path7.basename(detectedPath).startsWith(LEGACY_CONFIG_BASENAME)) {
|
|
@@ -80776,7 +82118,7 @@ function loadPluginConfig(directory, ctx) {
|
|
|
80776
82118
|
// node_modules/.bun/@opencode-ai+sdk@1.15.10/node_modules/@opencode-ai/sdk/dist/gen/core/serverSentEvents.gen.js
|
|
80777
82119
|
var createSseClient = ({ onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url: url2, ...options }) => {
|
|
80778
82120
|
let lastEventId;
|
|
80779
|
-
const sleep = sseSleepFn ?? ((ms) => new Promise((
|
|
82121
|
+
const sleep = sseSleepFn ?? ((ms) => new Promise((resolve11) => setTimeout(resolve11, ms)));
|
|
80780
82122
|
const createStream = async function* () {
|
|
80781
82123
|
let retryDelay = sseDefaultRetryDelay ?? 3000;
|
|
80782
82124
|
let attempt = 0;
|
|
@@ -82239,7 +83581,7 @@ async function createOpencodeServer(options) {
|
|
|
82239
83581
|
}
|
|
82240
83582
|
});
|
|
82241
83583
|
let clear = () => {};
|
|
82242
|
-
const url2 = await new Promise((
|
|
83584
|
+
const url2 = await new Promise((resolve11, reject) => {
|
|
82243
83585
|
const id = setTimeout(() => {
|
|
82244
83586
|
clear();
|
|
82245
83587
|
stop(proc);
|
|
@@ -82265,7 +83607,7 @@ async function createOpencodeServer(options) {
|
|
|
82265
83607
|
}
|
|
82266
83608
|
clearTimeout(id);
|
|
82267
83609
|
resolved = true;
|
|
82268
|
-
|
|
83610
|
+
resolve11(match[1]);
|
|
82269
83611
|
return;
|
|
82270
83612
|
}
|
|
82271
83613
|
}
|
|
@@ -82320,7 +83662,7 @@ var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
|
82320
83662
|
|
|
82321
83663
|
// src/cli/run/opencode-binary-resolver.ts
|
|
82322
83664
|
init_spawn_with_windows_hide();
|
|
82323
|
-
import { delimiter, dirname as
|
|
83665
|
+
import { delimiter as delimiter2, dirname as dirname17, join as join35 } from "path";
|
|
82324
83666
|
var OPENCODE_COMMANDS = ["opencode", "opencode-desktop"];
|
|
82325
83667
|
var WINDOWS_SUFFIXES = ["", ".exe", ".cmd", ".bat", ".ps1"];
|
|
82326
83668
|
function getCommandCandidates(platform) {
|
|
@@ -82341,9 +83683,9 @@ function collectCandidateBinaryPaths(pathEnv, which = Bun.which, platform = proc
|
|
|
82341
83683
|
for (const command of commandCandidates) {
|
|
82342
83684
|
addCandidate(which(command));
|
|
82343
83685
|
}
|
|
82344
|
-
for (const entry of (pathEnv ?? "").split(
|
|
83686
|
+
for (const entry of (pathEnv ?? "").split(delimiter2).filter(Boolean)) {
|
|
82345
83687
|
for (const command of commandCandidates) {
|
|
82346
|
-
addCandidate(
|
|
83688
|
+
addCandidate(join35(entry, command));
|
|
82347
83689
|
}
|
|
82348
83690
|
}
|
|
82349
83691
|
return candidates;
|
|
@@ -82370,9 +83712,9 @@ async function findWorkingOpencodeBinary(pathEnv = process.env.PATH, probe = can
|
|
|
82370
83712
|
return null;
|
|
82371
83713
|
}
|
|
82372
83714
|
function buildPathWithBinaryFirst(pathEnv, binaryPath) {
|
|
82373
|
-
const preferredDir =
|
|
82374
|
-
const existing = (pathEnv ?? "").split(
|
|
82375
|
-
return [preferredDir, ...existing].join(
|
|
83715
|
+
const preferredDir = dirname17(binaryPath);
|
|
83716
|
+
const existing = (pathEnv ?? "").split(delimiter2).filter((entry) => entry.length > 0 && entry !== preferredDir);
|
|
83717
|
+
return [preferredDir, ...existing].join(delimiter2);
|
|
82376
83718
|
}
|
|
82377
83719
|
async function withWorkingOpencodePath(startServer, finder = findWorkingOpencodeBinary) {
|
|
82378
83720
|
const originalPath = process.env.PATH;
|
|
@@ -82534,7 +83876,7 @@ async function resolveSession(options) {
|
|
|
82534
83876
|
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
82535
83877
|
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
82536
83878
|
console.log(import_picocolors10.default.dim(` Retrying in ${delay}ms...`));
|
|
82537
|
-
await new Promise((
|
|
83879
|
+
await new Promise((resolve11) => setTimeout(resolve11, delay));
|
|
82538
83880
|
}
|
|
82539
83881
|
continue;
|
|
82540
83882
|
}
|
|
@@ -82545,7 +83887,7 @@ async function resolveSession(options) {
|
|
|
82545
83887
|
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
82546
83888
|
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
82547
83889
|
console.log(import_picocolors10.default.dim(` Retrying in ${delay}ms...`));
|
|
82548
|
-
await new Promise((
|
|
83890
|
+
await new Promise((resolve11) => setTimeout(resolve11, delay));
|
|
82549
83891
|
}
|
|
82550
83892
|
}
|
|
82551
83893
|
throw new Error("Failed to create session after all retries");
|
|
@@ -82756,7 +84098,7 @@ var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
|
|
|
82756
84098
|
var NOTEPAD_DIR = "notepads";
|
|
82757
84099
|
var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
|
|
82758
84100
|
// packages/boulder-state/src/top-level-task.ts
|
|
82759
|
-
import { existsSync as
|
|
84101
|
+
import { existsSync as existsSync28, readFileSync as readFileSync15 } from "fs";
|
|
82760
84102
|
var TODO_HEADING_PATTERN = /^##\s+TODOs\b/i;
|
|
82761
84103
|
var FINAL_VERIFICATION_HEADING_PATTERN = /^##\s+Final Verification Wave\b/i;
|
|
82762
84104
|
var SECOND_LEVEL_HEADING_PATTERN = /^##\s+/;
|
|
@@ -82779,7 +84121,7 @@ function buildTaskRef(section, taskLabel) {
|
|
|
82779
84121
|
};
|
|
82780
84122
|
}
|
|
82781
84123
|
function readCurrentTopLevelTask(planPath) {
|
|
82782
|
-
if (!
|
|
84124
|
+
if (!existsSync28(planPath)) {
|
|
82783
84125
|
return null;
|
|
82784
84126
|
}
|
|
82785
84127
|
try {
|
|
@@ -82808,13 +84150,13 @@ function readCurrentTopLevelTask(planPath) {
|
|
|
82808
84150
|
}
|
|
82809
84151
|
}
|
|
82810
84152
|
// packages/boulder-state/src/storage/path.ts
|
|
82811
|
-
import { existsSync as
|
|
82812
|
-
import { isAbsolute as
|
|
84153
|
+
import { existsSync as existsSync29 } from "fs";
|
|
84154
|
+
import { isAbsolute as isAbsolute7, join as join36, relative as relative6, resolve as resolve11 } from "path";
|
|
82813
84155
|
function getBoulderFilePath(directory) {
|
|
82814
|
-
return
|
|
84156
|
+
return join36(directory, BOULDER_DIR, BOULDER_FILE);
|
|
82815
84157
|
}
|
|
82816
84158
|
function resolveTrackedPath(baseDirectory, trackedPath) {
|
|
82817
|
-
return
|
|
84159
|
+
return isAbsolute7(trackedPath) ? resolve11(trackedPath) : resolve11(baseDirectory, trackedPath);
|
|
82818
84160
|
}
|
|
82819
84161
|
function resolveBoulderPlanPath(directory, state) {
|
|
82820
84162
|
const absolutePlanPath = resolveTrackedPath(directory, state.active_plan);
|
|
@@ -82822,20 +84164,20 @@ function resolveBoulderPlanPath(directory, state) {
|
|
|
82822
84164
|
if (!worktreePath) {
|
|
82823
84165
|
return absolutePlanPath;
|
|
82824
84166
|
}
|
|
82825
|
-
const absoluteDirectory =
|
|
82826
|
-
const relativePlanPath =
|
|
82827
|
-
if (relativePlanPath.length === 0 || relativePlanPath.startsWith("..") ||
|
|
84167
|
+
const absoluteDirectory = resolve11(directory);
|
|
84168
|
+
const relativePlanPath = relative6(absoluteDirectory, absolutePlanPath);
|
|
84169
|
+
if (relativePlanPath.length === 0 || relativePlanPath.startsWith("..") || isAbsolute7(relativePlanPath)) {
|
|
82828
84170
|
return absolutePlanPath;
|
|
82829
84171
|
}
|
|
82830
84172
|
const absoluteWorktreePath = resolveTrackedPath(directory, worktreePath);
|
|
82831
|
-
const worktreePlanPath =
|
|
82832
|
-
return
|
|
84173
|
+
const worktreePlanPath = resolve11(absoluteWorktreePath, relativePlanPath);
|
|
84174
|
+
return existsSync29(worktreePlanPath) ? worktreePlanPath : absolutePlanPath;
|
|
82833
84175
|
}
|
|
82834
84176
|
function resolveBoulderPlanPathForWork(directory, work) {
|
|
82835
84177
|
return resolveBoulderPlanPath(directory, work);
|
|
82836
84178
|
}
|
|
82837
84179
|
// packages/boulder-state/src/storage/plan-progress.ts
|
|
82838
|
-
import { existsSync as
|
|
84180
|
+
import { existsSync as existsSync30, readFileSync as readFileSync16, readdirSync as readdirSync4, statSync as statSync4 } from "fs";
|
|
82839
84181
|
var TODO_HEADING_PATTERN2 = /^##\s+TODOs\b/i;
|
|
82840
84182
|
var FINAL_VERIFICATION_HEADING_PATTERN2 = /^##\s+Final Verification Wave\b/i;
|
|
82841
84183
|
var SECOND_LEVEL_HEADING_PATTERN2 = /^##\s+/;
|
|
@@ -82844,7 +84186,7 @@ var CHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[[xX]\]\s*(.+)$/;
|
|
|
82844
84186
|
var TODO_TASK_PATTERN2 = /^\d+\.\s+/;
|
|
82845
84187
|
var FINAL_WAVE_TASK_PATTERN2 = /^F\d+\.\s+/i;
|
|
82846
84188
|
function getPlanProgress(planPath) {
|
|
82847
|
-
if (!
|
|
84189
|
+
if (!existsSync30(planPath)) {
|
|
82848
84190
|
return { total: 0, completed: 0, isComplete: false };
|
|
82849
84191
|
}
|
|
82850
84192
|
try {
|
|
@@ -82964,10 +84306,10 @@ function selectMirrorWork(state) {
|
|
|
82964
84306
|
return sorted[0] ?? null;
|
|
82965
84307
|
}
|
|
82966
84308
|
// packages/boulder-state/src/storage/read-state.ts
|
|
82967
|
-
import { existsSync as
|
|
84309
|
+
import { existsSync as existsSync31, readFileSync as readFileSync17 } from "fs";
|
|
82968
84310
|
function readBoulderState(directory) {
|
|
82969
84311
|
const filePath = getBoulderFilePath(directory);
|
|
82970
|
-
if (!
|
|
84312
|
+
if (!existsSync31(filePath)) {
|
|
82971
84313
|
return null;
|
|
82972
84314
|
}
|
|
82973
84315
|
try {
|
|
@@ -83047,14 +84389,14 @@ function getSessionAgent(sessionID) {
|
|
|
83047
84389
|
// src/features/run-continuation-state/constants.ts
|
|
83048
84390
|
var CONTINUATION_MARKER_DIR = ".omo/run-continuation";
|
|
83049
84391
|
// src/features/run-continuation-state/storage.ts
|
|
83050
|
-
import { existsSync as
|
|
83051
|
-
import { join as
|
|
84392
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync9, readFileSync as readFileSync18, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
84393
|
+
import { join as join37 } from "path";
|
|
83052
84394
|
function getMarkerPath(directory, sessionID) {
|
|
83053
|
-
return
|
|
84395
|
+
return join37(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
|
|
83054
84396
|
}
|
|
83055
84397
|
function readContinuationMarker(directory, sessionID) {
|
|
83056
84398
|
const markerPath = getMarkerPath(directory, sessionID);
|
|
83057
|
-
if (!
|
|
84399
|
+
if (!existsSync32(markerPath))
|
|
83058
84400
|
return null;
|
|
83059
84401
|
try {
|
|
83060
84402
|
const raw = readFileSync18(markerPath, "utf-8");
|
|
@@ -83120,7 +84462,7 @@ async function isSessionInBoulderLineage(input) {
|
|
|
83120
84462
|
init_shared();
|
|
83121
84463
|
init_compaction_marker();
|
|
83122
84464
|
import { readFileSync as readFileSync19, readdirSync as readdirSync5 } from "fs";
|
|
83123
|
-
import { join as
|
|
84465
|
+
import { join as join38 } from "path";
|
|
83124
84466
|
var defaultSessionLastAgentDeps = {
|
|
83125
84467
|
getMessageDir,
|
|
83126
84468
|
isSqliteBackend,
|
|
@@ -83174,7 +84516,7 @@ async function getLastAgentFromSession(sessionID, client3, deps = {}) {
|
|
|
83174
84516
|
try {
|
|
83175
84517
|
const messages = readdirSync5(messageDir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => {
|
|
83176
84518
|
try {
|
|
83177
|
-
const content = readFileSync19(
|
|
84519
|
+
const content = readFileSync19(join38(messageDir, fileName), "utf-8");
|
|
83178
84520
|
const parsed = JSON.parse(content);
|
|
83179
84521
|
return {
|
|
83180
84522
|
fileName,
|
|
@@ -83210,8 +84552,8 @@ init_agent_display_names();
|
|
|
83210
84552
|
|
|
83211
84553
|
// src/hooks/ralph-loop/storage.ts
|
|
83212
84554
|
init_frontmatter2();
|
|
83213
|
-
import { existsSync as
|
|
83214
|
-
import { dirname as
|
|
84555
|
+
import { existsSync as existsSync33, readFileSync as readFileSync20, writeFileSync as writeFileSync7, unlinkSync as unlinkSync5, mkdirSync as mkdirSync10 } from "fs";
|
|
84556
|
+
import { dirname as dirname18, join as join39 } from "path";
|
|
83215
84557
|
|
|
83216
84558
|
// src/hooks/ralph-loop/constants.ts
|
|
83217
84559
|
var DEFAULT_STATE_FILE = ".omo/ralph-loop.local.md";
|
|
@@ -83220,11 +84562,11 @@ var DEFAULT_COMPLETION_PROMISE = "DONE";
|
|
|
83220
84562
|
|
|
83221
84563
|
// src/hooks/ralph-loop/storage.ts
|
|
83222
84564
|
function getStateFilePath(directory, customPath) {
|
|
83223
|
-
return customPath ?
|
|
84565
|
+
return customPath ? join39(directory, customPath) : join39(directory, DEFAULT_STATE_FILE);
|
|
83224
84566
|
}
|
|
83225
84567
|
function readState(directory, customPath) {
|
|
83226
84568
|
const filePath = getStateFilePath(directory, customPath);
|
|
83227
|
-
if (!
|
|
84569
|
+
if (!existsSync33(filePath)) {
|
|
83228
84570
|
return null;
|
|
83229
84571
|
}
|
|
83230
84572
|
try {
|
|
@@ -83449,13 +84791,14 @@ async function pollForCompletion(ctx, eventState, abortController, options = {})
|
|
|
83449
84791
|
const minStabilizationMs = rawMinStabilizationMs > 0 ? rawMinStabilizationMs : MIN_STABILIZATION_MS;
|
|
83450
84792
|
const eventWatchdogMs = options.eventWatchdogMs ?? DEFAULT_EVENT_WATCHDOG_MS;
|
|
83451
84793
|
const secondaryMeaningfulWorkTimeoutMs = options.secondaryMeaningfulWorkTimeoutMs ?? DEFAULT_SECONDARY_MEANINGFUL_WORK_TIMEOUT_MS;
|
|
84794
|
+
const requireMeaningfulWork = options.requireMeaningfulWork ?? false;
|
|
83452
84795
|
let consecutiveCompleteChecks = 0;
|
|
83453
84796
|
let errorCycleCount = 0;
|
|
83454
84797
|
let firstWorkTimestamp = null;
|
|
83455
84798
|
let secondaryTimeoutChecked = false;
|
|
83456
84799
|
const pollStartTimestamp = Date.now();
|
|
83457
84800
|
while (!abortController.signal.aborted) {
|
|
83458
|
-
await new Promise((
|
|
84801
|
+
await new Promise((resolve12) => setTimeout(resolve12, pollIntervalMs));
|
|
83459
84802
|
if (abortController.signal.aborted) {
|
|
83460
84803
|
return 130;
|
|
83461
84804
|
}
|
|
@@ -83508,21 +84851,24 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
83508
84851
|
consecutiveCompleteChecks = 0;
|
|
83509
84852
|
continue;
|
|
83510
84853
|
}
|
|
84854
|
+
if (requireMeaningfulWork) {
|
|
84855
|
+
if (Date.now() - pollStartTimestamp <= secondaryMeaningfulWorkTimeoutMs) {
|
|
84856
|
+
consecutiveCompleteChecks = 0;
|
|
84857
|
+
continue;
|
|
84858
|
+
}
|
|
84859
|
+
const hasActiveWork = await hasActiveSessionWork(ctx);
|
|
84860
|
+
if (hasActiveWork) {
|
|
84861
|
+
consecutiveCompleteChecks = 0;
|
|
84862
|
+
continue;
|
|
84863
|
+
}
|
|
84864
|
+
console.error(import_picocolors13.default.red(`
|
|
84865
|
+
|
|
84866
|
+
Session never produced assistant output, tool activity, or reasoning after the prompt started.`));
|
|
84867
|
+
return 1;
|
|
84868
|
+
}
|
|
83511
84869
|
if (Date.now() - pollStartTimestamp > secondaryMeaningfulWorkTimeoutMs && !secondaryTimeoutChecked) {
|
|
83512
84870
|
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;
|
|
84871
|
+
const hasActiveWork = await hasActiveSessionWork(ctx);
|
|
83526
84872
|
if (hasActiveWork) {
|
|
83527
84873
|
eventState.hasReceivedMeaningfulWork = true;
|
|
83528
84874
|
console.log(import_picocolors13.default.yellow(`
|
|
@@ -83556,6 +84902,21 @@ All tasks completed.`));
|
|
|
83556
84902
|
}
|
|
83557
84903
|
return 130;
|
|
83558
84904
|
}
|
|
84905
|
+
async function hasActiveSessionWork(ctx) {
|
|
84906
|
+
const childrenRes = await ctx.client.session.children({
|
|
84907
|
+
path: { id: ctx.sessionID },
|
|
84908
|
+
query: { directory: ctx.directory }
|
|
84909
|
+
});
|
|
84910
|
+
const children = normalizeSDKResponse(childrenRes, []);
|
|
84911
|
+
const todosRes = await ctx.client.session.todo({
|
|
84912
|
+
path: { id: ctx.sessionID },
|
|
84913
|
+
query: { directory: ctx.directory }
|
|
84914
|
+
});
|
|
84915
|
+
const todos = normalizeSDKResponse(todosRes, []);
|
|
84916
|
+
const hasActiveChildren = Array.isArray(children) && children.length > 0;
|
|
84917
|
+
const hasActiveTodos = Array.isArray(todos) && todos.some(isIncompleteTodo);
|
|
84918
|
+
return hasActiveChildren || hasActiveTodos;
|
|
84919
|
+
}
|
|
83559
84920
|
async function getMainSessionStatus(ctx) {
|
|
83560
84921
|
try {
|
|
83561
84922
|
const statusesRes = await ctx.client.session.status({
|
|
@@ -83575,6 +84936,88 @@ async function getMainSessionStatus(ctx) {
|
|
|
83575
84936
|
}
|
|
83576
84937
|
}
|
|
83577
84938
|
|
|
84939
|
+
// src/cli/run/prompt-start.ts
|
|
84940
|
+
init_shared();
|
|
84941
|
+
var DEFAULT_PROMPT_START_TIMEOUT_MS = 30000;
|
|
84942
|
+
var DEFAULT_PROMPT_START_POLL_INTERVAL_MS = 100;
|
|
84943
|
+
function createAbortError() {
|
|
84944
|
+
const error51 = new Error("Prompt start wait aborted");
|
|
84945
|
+
error51.name = "AbortError";
|
|
84946
|
+
return error51;
|
|
84947
|
+
}
|
|
84948
|
+
function sleep(delayMs) {
|
|
84949
|
+
return new Promise((resolve12) => setTimeout(resolve12, delayMs));
|
|
84950
|
+
}
|
|
84951
|
+
function hasPromptStartEvidence(eventState) {
|
|
84952
|
+
return eventState.mainSessionStarted || eventState.hasReceivedMeaningfulWork || eventState.messageCount > 0 || eventState.currentTool !== null;
|
|
84953
|
+
}
|
|
84954
|
+
async function readMainSessionStatus(ctx) {
|
|
84955
|
+
if (typeof ctx.client.session.status !== "function") {
|
|
84956
|
+
return null;
|
|
84957
|
+
}
|
|
84958
|
+
try {
|
|
84959
|
+
const statusRes = await ctx.client.session.status({
|
|
84960
|
+
query: { directory: ctx.directory }
|
|
84961
|
+
});
|
|
84962
|
+
const statuses = normalizeSDKResponse(statusRes, {});
|
|
84963
|
+
return statuses[ctx.sessionID]?.type ?? "idle";
|
|
84964
|
+
} catch (error51) {
|
|
84965
|
+
if (ctx.verbose) {
|
|
84966
|
+
console.error(`[run] failed to read session status while waiting for prompt start: ${String(error51)}`);
|
|
84967
|
+
}
|
|
84968
|
+
return null;
|
|
84969
|
+
}
|
|
84970
|
+
}
|
|
84971
|
+
async function hasPersistedMessages(ctx) {
|
|
84972
|
+
if (typeof ctx.client.session.messages !== "function") {
|
|
84973
|
+
return false;
|
|
84974
|
+
}
|
|
84975
|
+
try {
|
|
84976
|
+
const messagesRes = await ctx.client.session.messages({
|
|
84977
|
+
path: { id: ctx.sessionID },
|
|
84978
|
+
query: { directory: ctx.directory }
|
|
84979
|
+
});
|
|
84980
|
+
const messages = normalizeSDKResponse(messagesRes, []);
|
|
84981
|
+
return messages.length > 0;
|
|
84982
|
+
} catch (error51) {
|
|
84983
|
+
if (ctx.verbose) {
|
|
84984
|
+
console.error(`[run] failed to read session messages while waiting for prompt start: ${String(error51)}`);
|
|
84985
|
+
}
|
|
84986
|
+
return false;
|
|
84987
|
+
}
|
|
84988
|
+
}
|
|
84989
|
+
async function waitForPromptStart(ctx, eventState, abortController, options = {}) {
|
|
84990
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_PROMPT_START_TIMEOUT_MS;
|
|
84991
|
+
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_PROMPT_START_POLL_INTERVAL_MS;
|
|
84992
|
+
const startedAt = Date.now();
|
|
84993
|
+
while (!abortController.signal.aborted) {
|
|
84994
|
+
if (hasPromptStartEvidence(eventState)) {
|
|
84995
|
+
return;
|
|
84996
|
+
}
|
|
84997
|
+
if (eventState.mainSessionError) {
|
|
84998
|
+
throw new Error(`Session errored before prompt started: ${eventState.lastError ?? "unknown error"}`);
|
|
84999
|
+
}
|
|
85000
|
+
const status = await readMainSessionStatus(ctx);
|
|
85001
|
+
if (status === "busy" || status === "retry") {
|
|
85002
|
+
eventState.mainSessionStarted = true;
|
|
85003
|
+
eventState.mainSessionIdle = false;
|
|
85004
|
+
return;
|
|
85005
|
+
}
|
|
85006
|
+
if (status === "idle") {
|
|
85007
|
+
eventState.mainSessionIdle = true;
|
|
85008
|
+
}
|
|
85009
|
+
if (await hasPersistedMessages(ctx)) {
|
|
85010
|
+
eventState.mainSessionStarted = true;
|
|
85011
|
+
return;
|
|
85012
|
+
}
|
|
85013
|
+
if (Date.now() - startedAt >= timeoutMs) {
|
|
85014
|
+
throw new Error(`Prompt did not start within ${timeoutMs}ms; no busy status, message event, or persisted message was observed.`);
|
|
85015
|
+
}
|
|
85016
|
+
await sleep(pollIntervalMs);
|
|
85017
|
+
}
|
|
85018
|
+
throw createAbortError();
|
|
85019
|
+
}
|
|
85020
|
+
|
|
83578
85021
|
// src/cli/run/agent-profile-colors.ts
|
|
83579
85022
|
init_shared();
|
|
83580
85023
|
async function loadAgentProfileColors(client3) {
|
|
@@ -83684,7 +85127,7 @@ function createTimestampedStdoutController(stdout = process.stdout) {
|
|
|
83684
85127
|
// src/shared/posthog.ts
|
|
83685
85128
|
init_index_node();
|
|
83686
85129
|
import os5 from "os";
|
|
83687
|
-
import { createHash as
|
|
85130
|
+
import { createHash as createHash4 } from "crypto";
|
|
83688
85131
|
init_plugin_identity();
|
|
83689
85132
|
|
|
83690
85133
|
// src/shared/posthog-activity-state.ts
|
|
@@ -83692,11 +85135,11 @@ init_data_path();
|
|
|
83692
85135
|
init_logger();
|
|
83693
85136
|
init_plugin_identity();
|
|
83694
85137
|
init_write_file_atomically();
|
|
83695
|
-
import { existsSync as
|
|
83696
|
-
import { join as
|
|
85138
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync11, readFileSync as readFileSync21 } from "fs";
|
|
85139
|
+
import { join as join40 } from "path";
|
|
83697
85140
|
var POSTHOG_ACTIVITY_STATE_FILE2 = "posthog-activity.json";
|
|
83698
85141
|
function getPostHogActivityStateFilePath2() {
|
|
83699
|
-
return
|
|
85142
|
+
return join40(getDataDir(), CACHE_DIR_NAME, POSTHOG_ACTIVITY_STATE_FILE2);
|
|
83700
85143
|
}
|
|
83701
85144
|
function getUtcDayString2(date5) {
|
|
83702
85145
|
return date5.toISOString().slice(0, 10);
|
|
@@ -83706,7 +85149,7 @@ function isPostHogActivityState2(value) {
|
|
|
83706
85149
|
}
|
|
83707
85150
|
function readPostHogActivityState2() {
|
|
83708
85151
|
const stateFilePath = getPostHogActivityStateFilePath2();
|
|
83709
|
-
if (!
|
|
85152
|
+
if (!existsSync34(stateFilePath)) {
|
|
83710
85153
|
return {};
|
|
83711
85154
|
}
|
|
83712
85155
|
try {
|
|
@@ -83727,7 +85170,7 @@ function readPostHogActivityState2() {
|
|
|
83727
85170
|
function writePostHogActivityState2(nextState) {
|
|
83728
85171
|
const stateFilePath = getPostHogActivityStateFilePath2();
|
|
83729
85172
|
try {
|
|
83730
|
-
mkdirSync11(
|
|
85173
|
+
mkdirSync11(join40(getDataDir(), CACHE_DIR_NAME), { recursive: true });
|
|
83731
85174
|
writeFileAtomically(stateFilePath, `${JSON.stringify(nextState, null, 2)}
|
|
83732
85175
|
`);
|
|
83733
85176
|
} catch (error51) {
|
|
@@ -83858,7 +85301,7 @@ function createPostHogClient2(source, options) {
|
|
|
83858
85301
|
};
|
|
83859
85302
|
}
|
|
83860
85303
|
function getPostHogDistinctId2() {
|
|
83861
|
-
return
|
|
85304
|
+
return createHash4("sha256").update(`${PUBLISHED_PACKAGE_NAME}:${resolveOsProvider2().hostname()}`).digest("hex");
|
|
83862
85305
|
}
|
|
83863
85306
|
function createCliPostHog2() {
|
|
83864
85307
|
return createPostHogClient2("cli", {
|
|
@@ -83877,7 +85320,7 @@ var EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS = 2000;
|
|
|
83877
85320
|
async function waitForEventProcessorShutdown(eventProcessor, timeoutMs = EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS) {
|
|
83878
85321
|
const completed = await Promise.race([
|
|
83879
85322
|
eventProcessor.then(() => true),
|
|
83880
|
-
new Promise((
|
|
85323
|
+
new Promise((resolve12) => setTimeout(() => resolve12(false), timeoutMs))
|
|
83881
85324
|
]);
|
|
83882
85325
|
}
|
|
83883
85326
|
async function run(options) {
|
|
@@ -83908,7 +85351,7 @@ async function run(options) {
|
|
|
83908
85351
|
attach: options.attach,
|
|
83909
85352
|
signal: abortController.signal
|
|
83910
85353
|
});
|
|
83911
|
-
const
|
|
85354
|
+
const cleanup2 = () => {
|
|
83912
85355
|
serverCleanup();
|
|
83913
85356
|
};
|
|
83914
85357
|
const restoreInput = suppressRunInput();
|
|
@@ -83916,7 +85359,7 @@ async function run(options) {
|
|
|
83916
85359
|
console.log(import_picocolors14.default.yellow(`
|
|
83917
85360
|
Interrupted. Shutting down...`));
|
|
83918
85361
|
restoreInput();
|
|
83919
|
-
|
|
85362
|
+
cleanup2();
|
|
83920
85363
|
process.exit(130);
|
|
83921
85364
|
};
|
|
83922
85365
|
process.on("SIGINT", handleSigint);
|
|
@@ -83974,10 +85417,13 @@ Interrupted. Shutting down...`));
|
|
|
83974
85417
|
if (!promptMayHaveBeenAccepted && !isInternalPromptDispatchAccepted(promptResult)) {
|
|
83975
85418
|
throw new Error(`Session ${sessionID} is not idle; promptAsync skipped by gate: ${promptResult.status}`);
|
|
83976
85419
|
}
|
|
83977
|
-
|
|
85420
|
+
await waitForPromptStart(ctx, eventState, abortController);
|
|
85421
|
+
const exitCode = await pollForCompletion(ctx, eventState, abortController, {
|
|
85422
|
+
requireMeaningfulWork: true
|
|
85423
|
+
});
|
|
83978
85424
|
abortController.abort();
|
|
83979
85425
|
await waitForEventProcessorShutdown(eventProcessor);
|
|
83980
|
-
|
|
85426
|
+
cleanup2();
|
|
83981
85427
|
const durationMs = Date.now() - startTime;
|
|
83982
85428
|
if (options.onComplete) {
|
|
83983
85429
|
await executeOnCompleteHook({
|
|
@@ -83999,7 +85445,7 @@ Interrupted. Shutting down...`));
|
|
|
83999
85445
|
}
|
|
84000
85446
|
return exitCode;
|
|
84001
85447
|
} catch (err) {
|
|
84002
|
-
|
|
85448
|
+
cleanup2();
|
|
84003
85449
|
throw err;
|
|
84004
85450
|
} finally {
|
|
84005
85451
|
process.removeListener("SIGINT", handleSigint);
|
|
@@ -84172,13 +85618,13 @@ async function getLocalVersion(options = {}) {
|
|
|
84172
85618
|
}
|
|
84173
85619
|
}
|
|
84174
85620
|
// src/cli/doctor/checks/system.ts
|
|
84175
|
-
import { existsSync as
|
|
85621
|
+
import { existsSync as existsSync45, readFileSync as readFileSync31 } from "fs";
|
|
84176
85622
|
|
|
84177
85623
|
// src/cli/doctor/checks/system-binary.ts
|
|
84178
85624
|
init_extract_semver();
|
|
84179
|
-
import { existsSync as
|
|
84180
|
-
import { homedir as
|
|
84181
|
-
import { join as
|
|
85625
|
+
import { existsSync as existsSync42, accessSync as accessSync4, constants as constants7 } from "fs";
|
|
85626
|
+
import { homedir as homedir11 } from "os";
|
|
85627
|
+
import { join as join47 } from "path";
|
|
84182
85628
|
|
|
84183
85629
|
// src/cli/doctor/spawn-with-timeout.ts
|
|
84184
85630
|
init_spawn_with_windows_hide();
|
|
@@ -84191,8 +85637,8 @@ async function spawnWithTimeout(command, options, timeoutMs = DEFAULT_SPAWN_TIME
|
|
|
84191
85637
|
return { stdout: "", stderr: "", exitCode: 1, timedOut: false };
|
|
84192
85638
|
}
|
|
84193
85639
|
let timer;
|
|
84194
|
-
const timeoutPromise = new Promise((
|
|
84195
|
-
timer = setTimeout(() =>
|
|
85640
|
+
const timeoutPromise = new Promise((resolve12) => {
|
|
85641
|
+
timer = setTimeout(() => resolve12("timeout"), timeoutMs);
|
|
84196
85642
|
});
|
|
84197
85643
|
const processPromise = (async () => {
|
|
84198
85644
|
await proc.exited;
|
|
@@ -84212,31 +85658,31 @@ async function spawnWithTimeout(command, options, timeoutMs = DEFAULT_SPAWN_TIME
|
|
|
84212
85658
|
|
|
84213
85659
|
// src/cli/doctor/checks/system-binary.ts
|
|
84214
85660
|
var WINDOWS_EXECUTABLE_EXTS = [".exe", ".cmd", ".bat", ".ps1"];
|
|
84215
|
-
function
|
|
85661
|
+
function isExecutable2(path14) {
|
|
84216
85662
|
try {
|
|
84217
|
-
|
|
85663
|
+
accessSync4(path14, constants7.X_OK);
|
|
84218
85664
|
return true;
|
|
84219
85665
|
} catch {
|
|
84220
85666
|
return false;
|
|
84221
85667
|
}
|
|
84222
85668
|
}
|
|
84223
85669
|
function getDesktopAppPaths(platform) {
|
|
84224
|
-
const home =
|
|
85670
|
+
const home = homedir11();
|
|
84225
85671
|
switch (platform) {
|
|
84226
85672
|
case "darwin":
|
|
84227
85673
|
return [
|
|
84228
85674
|
"/Applications/OpenCode.app/Contents/MacOS/OpenCode",
|
|
84229
|
-
|
|
85675
|
+
join47(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
|
|
84230
85676
|
];
|
|
84231
85677
|
case "win32": {
|
|
84232
85678
|
const programFiles = process.env.ProgramFiles;
|
|
84233
85679
|
const localAppData = process.env.LOCALAPPDATA;
|
|
84234
85680
|
const paths = [];
|
|
84235
85681
|
if (programFiles) {
|
|
84236
|
-
paths.push(
|
|
85682
|
+
paths.push(join47(programFiles, "OpenCode", "OpenCode.exe"));
|
|
84237
85683
|
}
|
|
84238
85684
|
if (localAppData) {
|
|
84239
|
-
paths.push(
|
|
85685
|
+
paths.push(join47(localAppData, "OpenCode", "OpenCode.exe"));
|
|
84240
85686
|
}
|
|
84241
85687
|
return paths;
|
|
84242
85688
|
}
|
|
@@ -84244,8 +85690,8 @@ function getDesktopAppPaths(platform) {
|
|
|
84244
85690
|
return [
|
|
84245
85691
|
"/usr/bin/opencode",
|
|
84246
85692
|
"/usr/lib/opencode/opencode",
|
|
84247
|
-
|
|
84248
|
-
|
|
85693
|
+
join47(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
|
|
85694
|
+
join47(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
|
|
84249
85695
|
];
|
|
84250
85696
|
default:
|
|
84251
85697
|
return [];
|
|
@@ -84257,7 +85703,7 @@ function buildVersionCommand(binaryPath, platform) {
|
|
|
84257
85703
|
}
|
|
84258
85704
|
return [binaryPath, "--version"];
|
|
84259
85705
|
}
|
|
84260
|
-
function findDesktopBinary(platform = process.platform, checkExists =
|
|
85706
|
+
function findDesktopBinary(platform = process.platform, checkExists = existsSync42) {
|
|
84261
85707
|
for (const desktopPath of getDesktopAppPaths(platform)) {
|
|
84262
85708
|
if (checkExists(desktopPath)) {
|
|
84263
85709
|
return { binary: "opencode", path: desktopPath };
|
|
@@ -84265,7 +85711,7 @@ function findDesktopBinary(platform = process.platform, checkExists = existsSync
|
|
|
84265
85711
|
}
|
|
84266
85712
|
return null;
|
|
84267
85713
|
}
|
|
84268
|
-
async function findOpenCodeBinary(platform = process.platform, checkExists =
|
|
85714
|
+
async function findOpenCodeBinary(platform = process.platform, checkExists = existsSync42) {
|
|
84269
85715
|
for (const binary2 of OPENCODE_BINARIES2) {
|
|
84270
85716
|
const path14 = Bun.which(binary2);
|
|
84271
85717
|
if (path14 && checkExists(path14)) {
|
|
@@ -84273,12 +85719,12 @@ async function findOpenCodeBinary(platform = process.platform, checkExists = exi
|
|
|
84273
85719
|
}
|
|
84274
85720
|
}
|
|
84275
85721
|
const pathEnv = process.env.PATH ?? "";
|
|
84276
|
-
const
|
|
85722
|
+
const delimiter3 = platform === "win32" ? ";" : ":";
|
|
84277
85723
|
const candidates = getCommandCandidates2(platform);
|
|
84278
|
-
for (const entry of pathEnv.split(
|
|
85724
|
+
for (const entry of pathEnv.split(delimiter3).filter(Boolean)) {
|
|
84279
85725
|
for (const command of candidates) {
|
|
84280
|
-
const fullPath =
|
|
84281
|
-
if (checkExists(fullPath) &&
|
|
85726
|
+
const fullPath = join47(entry, command);
|
|
85727
|
+
if (checkExists(fullPath) && isExecutable2(fullPath)) {
|
|
84282
85728
|
return { binary: command, path: fullPath };
|
|
84283
85729
|
}
|
|
84284
85730
|
}
|
|
@@ -84320,12 +85766,12 @@ function compareVersions3(current, minimum) {
|
|
|
84320
85766
|
|
|
84321
85767
|
// src/cli/doctor/checks/system-plugin.ts
|
|
84322
85768
|
init_shared();
|
|
84323
|
-
import { existsSync as
|
|
85769
|
+
import { existsSync as existsSync43, readFileSync as readFileSync29 } from "fs";
|
|
84324
85770
|
function detectConfigPath() {
|
|
84325
85771
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
84326
|
-
if (
|
|
85772
|
+
if (existsSync43(paths.configJsonc))
|
|
84327
85773
|
return paths.configJsonc;
|
|
84328
|
-
if (
|
|
85774
|
+
if (existsSync43(paths.configJson))
|
|
84329
85775
|
return paths.configJson;
|
|
84330
85776
|
return null;
|
|
84331
85777
|
}
|
|
@@ -84409,35 +85855,35 @@ function getPluginInfo() {
|
|
|
84409
85855
|
init_file_utils2();
|
|
84410
85856
|
init_checker();
|
|
84411
85857
|
init_auto_update_checker();
|
|
84412
|
-
import { existsSync as
|
|
85858
|
+
import { existsSync as existsSync44, readFileSync as readFileSync30 } from "fs";
|
|
84413
85859
|
import { createRequire } from "module";
|
|
84414
|
-
import { homedir as
|
|
84415
|
-
import { join as
|
|
85860
|
+
import { homedir as homedir12 } from "os";
|
|
85861
|
+
import { join as join48 } from "path";
|
|
84416
85862
|
init_shared();
|
|
84417
85863
|
function getPlatformDefaultCacheDir(platform = process.platform) {
|
|
84418
85864
|
if (platform === "darwin")
|
|
84419
|
-
return
|
|
85865
|
+
return join48(homedir12(), "Library", "Caches");
|
|
84420
85866
|
if (platform === "win32")
|
|
84421
|
-
return process.env.LOCALAPPDATA ??
|
|
84422
|
-
return
|
|
85867
|
+
return process.env.LOCALAPPDATA ?? join48(homedir12(), "AppData", "Local");
|
|
85868
|
+
return join48(homedir12(), ".cache");
|
|
84423
85869
|
}
|
|
84424
85870
|
function resolveOpenCodeCacheDir() {
|
|
84425
85871
|
const xdgCacheHome = process.env.XDG_CACHE_HOME;
|
|
84426
85872
|
if (xdgCacheHome)
|
|
84427
|
-
return
|
|
85873
|
+
return join48(xdgCacheHome, "opencode");
|
|
84428
85874
|
const fromShared = getOpenCodeCacheDir();
|
|
84429
|
-
const platformDefault =
|
|
84430
|
-
if (
|
|
85875
|
+
const platformDefault = join48(getPlatformDefaultCacheDir(), "opencode");
|
|
85876
|
+
if (existsSync44(fromShared) || !existsSync44(platformDefault))
|
|
84431
85877
|
return fromShared;
|
|
84432
85878
|
return platformDefault;
|
|
84433
85879
|
}
|
|
84434
85880
|
function resolveExistingDir(dirPath) {
|
|
84435
|
-
if (!
|
|
85881
|
+
if (!existsSync44(dirPath))
|
|
84436
85882
|
return dirPath;
|
|
84437
85883
|
return resolveSymlink(dirPath);
|
|
84438
85884
|
}
|
|
84439
85885
|
function readPackageJson(filePath) {
|
|
84440
|
-
if (!
|
|
85886
|
+
if (!existsSync44(filePath))
|
|
84441
85887
|
return null;
|
|
84442
85888
|
try {
|
|
84443
85889
|
const content = readFileSync30(filePath, "utf-8");
|
|
@@ -84455,11 +85901,11 @@ function normalizeVersion(value) {
|
|
|
84455
85901
|
function createPackageCandidates(rootDir) {
|
|
84456
85902
|
return ACCEPTED_PACKAGE_NAMES.map((packageName) => ({
|
|
84457
85903
|
packageName,
|
|
84458
|
-
installedPackagePath:
|
|
85904
|
+
installedPackagePath: join48(rootDir, "node_modules", packageName, "package.json")
|
|
84459
85905
|
}));
|
|
84460
85906
|
}
|
|
84461
85907
|
function selectInstalledPackage(candidate) {
|
|
84462
|
-
return candidate.packageCandidates.find((packageCandidate) =>
|
|
85908
|
+
return candidate.packageCandidates.find((packageCandidate) => existsSync44(packageCandidate.installedPackagePath)) ?? candidate.packageCandidates[0];
|
|
84463
85909
|
}
|
|
84464
85910
|
function getExpectedVersion(cachePackage, packageName) {
|
|
84465
85911
|
return normalizeVersion(cachePackage?.dependencies?.[packageName]) ?? normalizeVersion(cachePackage?.dependencies?.[PACKAGE_NAME]);
|
|
@@ -84470,7 +85916,7 @@ function resolveInstalledPackageJsonPath() {
|
|
|
84470
85916
|
for (const packageName of ACCEPTED_PACKAGE_NAMES) {
|
|
84471
85917
|
try {
|
|
84472
85918
|
const packageJsonPath = require2.resolve(`${packageName}/package.json`);
|
|
84473
|
-
if (
|
|
85919
|
+
if (existsSync44(packageJsonPath)) {
|
|
84474
85920
|
return { packageName, packageJsonPath };
|
|
84475
85921
|
}
|
|
84476
85922
|
} catch {
|
|
@@ -84489,20 +85935,20 @@ function getLoadedPluginVersion() {
|
|
|
84489
85935
|
const candidates = [
|
|
84490
85936
|
{
|
|
84491
85937
|
cacheDir: configDir,
|
|
84492
|
-
cachePackagePath:
|
|
85938
|
+
cachePackagePath: join48(configDir, "package.json"),
|
|
84493
85939
|
packageCandidates: createPackageCandidates(configDir)
|
|
84494
85940
|
},
|
|
84495
85941
|
{
|
|
84496
85942
|
cacheDir,
|
|
84497
|
-
cachePackagePath:
|
|
85943
|
+
cachePackagePath: join48(cacheDir, "package.json"),
|
|
84498
85944
|
packageCandidates: createPackageCandidates(cacheDir)
|
|
84499
85945
|
}
|
|
84500
85946
|
];
|
|
84501
|
-
const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) =>
|
|
85947
|
+
const selectedCandidate = candidates.find((candidate) => candidate.packageCandidates.some((packageCandidate) => existsSync44(packageCandidate.installedPackagePath))) ?? candidates[0];
|
|
84502
85948
|
const { cacheDir: selectedDir, cachePackagePath } = selectedCandidate;
|
|
84503
85949
|
const selectedPackage = selectInstalledPackage(selectedCandidate);
|
|
84504
85950
|
const candidateInstalledPath = selectedPackage.installedPackagePath;
|
|
84505
|
-
const candidateExists =
|
|
85951
|
+
const candidateExists = existsSync44(candidateInstalledPath);
|
|
84506
85952
|
const resolvedFallback = candidateExists ? null : resolveInstalledPackageJsonPath();
|
|
84507
85953
|
const installedPackagePath = resolvedFallback?.packageJsonPath ?? candidateInstalledPath;
|
|
84508
85954
|
const resolvedPackageName = resolvedFallback?.packageName ?? selectedPackage.packageName;
|
|
@@ -84541,7 +85987,7 @@ var defaultDeps5 = {
|
|
|
84541
85987
|
function isConfigValid(configPath) {
|
|
84542
85988
|
if (!configPath)
|
|
84543
85989
|
return true;
|
|
84544
|
-
if (!
|
|
85990
|
+
if (!existsSync45(configPath))
|
|
84545
85991
|
return false;
|
|
84546
85992
|
try {
|
|
84547
85993
|
parseJsonc(readFileSync31(configPath, "utf-8"));
|
|
@@ -84667,29 +86113,29 @@ async function checkSystem(deps = defaultDeps5) {
|
|
|
84667
86113
|
|
|
84668
86114
|
// src/cli/doctor/checks/config.ts
|
|
84669
86115
|
import { readFileSync as readFileSync34 } from "fs";
|
|
84670
|
-
import { join as
|
|
86116
|
+
import { join as join52 } from "path";
|
|
84671
86117
|
init_shared();
|
|
84672
86118
|
init_plugin_identity();
|
|
84673
86119
|
|
|
84674
86120
|
// src/cli/doctor/checks/model-resolution-cache.ts
|
|
84675
86121
|
init_shared();
|
|
84676
|
-
import { existsSync as
|
|
84677
|
-
import { homedir as
|
|
84678
|
-
import { join as
|
|
86122
|
+
import { existsSync as existsSync46, readFileSync as readFileSync32 } from "fs";
|
|
86123
|
+
import { homedir as homedir13 } from "os";
|
|
86124
|
+
import { join as join49 } from "path";
|
|
84679
86125
|
function getUserConfigDir2() {
|
|
84680
86126
|
const xdgConfig = process.env.XDG_CONFIG_HOME;
|
|
84681
86127
|
if (xdgConfig)
|
|
84682
|
-
return
|
|
84683
|
-
return
|
|
86128
|
+
return join49(xdgConfig, "opencode");
|
|
86129
|
+
return join49(homedir13(), ".config", "opencode");
|
|
84684
86130
|
}
|
|
84685
86131
|
function loadCustomProviderNames() {
|
|
84686
86132
|
const configDir = getUserConfigDir2();
|
|
84687
86133
|
const candidatePaths = [
|
|
84688
|
-
|
|
84689
|
-
|
|
86134
|
+
join49(configDir, "opencode.json"),
|
|
86135
|
+
join49(configDir, "opencode.jsonc")
|
|
84690
86136
|
];
|
|
84691
86137
|
for (const configPath of candidatePaths) {
|
|
84692
|
-
if (!
|
|
86138
|
+
if (!existsSync46(configPath))
|
|
84693
86139
|
continue;
|
|
84694
86140
|
try {
|
|
84695
86141
|
const content = readFileSync32(configPath, "utf-8");
|
|
@@ -84702,9 +86148,9 @@ function loadCustomProviderNames() {
|
|
|
84702
86148
|
return [];
|
|
84703
86149
|
}
|
|
84704
86150
|
function loadAvailableModelsFromCache() {
|
|
84705
|
-
const cacheFile =
|
|
86151
|
+
const cacheFile = join49(getOpenCodeCacheDir(), "models.json");
|
|
84706
86152
|
const customProviders = loadCustomProviderNames();
|
|
84707
|
-
if (!
|
|
86153
|
+
if (!existsSync46(cacheFile)) {
|
|
84708
86154
|
if (customProviders.length > 0) {
|
|
84709
86155
|
return { providers: customProviders, modelCount: 0, cacheExists: true };
|
|
84710
86156
|
}
|
|
@@ -84736,8 +86182,8 @@ init_model_capabilities2();
|
|
|
84736
86182
|
init_shared();
|
|
84737
86183
|
init_plugin_identity();
|
|
84738
86184
|
import { readFileSync as readFileSync33 } from "fs";
|
|
84739
|
-
import { join as
|
|
84740
|
-
var PROJECT_CONFIG_DIR =
|
|
86185
|
+
import { join as join50 } from "path";
|
|
86186
|
+
var PROJECT_CONFIG_DIR = join50(process.cwd(), ".opencode");
|
|
84741
86187
|
function loadOmoConfig() {
|
|
84742
86188
|
const projectDetected = detectPluginConfigFile(PROJECT_CONFIG_DIR, {
|
|
84743
86189
|
basenames: [CONFIG_BASENAME],
|
|
@@ -84769,7 +86215,7 @@ function loadOmoConfig() {
|
|
|
84769
86215
|
|
|
84770
86216
|
// src/cli/doctor/checks/model-resolution-details.ts
|
|
84771
86217
|
init_shared();
|
|
84772
|
-
import { join as
|
|
86218
|
+
import { join as join51 } from "path";
|
|
84773
86219
|
|
|
84774
86220
|
// src/cli/doctor/checks/model-resolution-variant.ts
|
|
84775
86221
|
function formatModelWithVariant(model, variant) {
|
|
@@ -84811,7 +86257,7 @@ function formatCapabilityResolutionLabel(mode) {
|
|
|
84811
86257
|
}
|
|
84812
86258
|
function buildModelResolutionDetails(options) {
|
|
84813
86259
|
const details = [];
|
|
84814
|
-
const cacheFile =
|
|
86260
|
+
const cacheFile = join51(getOpenCodeCacheDir(), "models.json");
|
|
84815
86261
|
details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
|
|
84816
86262
|
details.push("");
|
|
84817
86263
|
if (options.available.cacheExists) {
|
|
@@ -84966,7 +86412,7 @@ async function checkModels() {
|
|
|
84966
86412
|
}
|
|
84967
86413
|
|
|
84968
86414
|
// src/cli/doctor/checks/config.ts
|
|
84969
|
-
var PROJECT_CONFIG_DIR2 =
|
|
86415
|
+
var PROJECT_CONFIG_DIR2 = join52(process.cwd(), ".opencode");
|
|
84970
86416
|
function findConfigPath() {
|
|
84971
86417
|
const projectConfig = detectPluginConfigFile(PROJECT_CONFIG_DIR2, {
|
|
84972
86418
|
basenames: [CONFIG_BASENAME],
|
|
@@ -85092,27 +86538,27 @@ async function checkConfig() {
|
|
|
85092
86538
|
}
|
|
85093
86539
|
|
|
85094
86540
|
// src/cli/doctor/checks/dependencies.ts
|
|
85095
|
-
import { existsSync as
|
|
86541
|
+
import { existsSync as existsSync47 } from "fs";
|
|
85096
86542
|
import { createRequire as createRequire2 } from "module";
|
|
85097
|
-
import { dirname as
|
|
86543
|
+
import { dirname as dirname22, join as join54 } from "path";
|
|
85098
86544
|
|
|
85099
86545
|
// src/hooks/comment-checker/downloader.ts
|
|
85100
|
-
import { join as
|
|
85101
|
-
import { homedir as
|
|
86546
|
+
import { join as join53 } from "path";
|
|
86547
|
+
import { homedir as homedir14, tmpdir as tmpdir3 } from "os";
|
|
85102
86548
|
init_binary_downloader();
|
|
85103
86549
|
init_logger();
|
|
85104
86550
|
init_plugin_identity();
|
|
85105
86551
|
var DEBUG = process.env.COMMENT_CHECKER_DEBUG === "1";
|
|
85106
|
-
var DEBUG_FILE =
|
|
86552
|
+
var DEBUG_FILE = join53(tmpdir3(), "comment-checker-debug.log");
|
|
85107
86553
|
function getCacheDir2() {
|
|
85108
86554
|
if (process.platform === "win32") {
|
|
85109
86555
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
85110
|
-
const base2 = localAppData ||
|
|
85111
|
-
return
|
|
86556
|
+
const base2 = localAppData || join53(homedir14(), "AppData", "Local");
|
|
86557
|
+
return join53(base2, CACHE_DIR_NAME, "bin");
|
|
85112
86558
|
}
|
|
85113
86559
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
85114
|
-
const base = xdgCache ||
|
|
85115
|
-
return
|
|
86560
|
+
const base = xdgCache || join53(homedir14(), ".cache");
|
|
86561
|
+
return join53(base, CACHE_DIR_NAME, "bin");
|
|
85116
86562
|
}
|
|
85117
86563
|
function getBinaryName() {
|
|
85118
86564
|
return process.platform === "win32" ? "comment-checker.exe" : "comment-checker";
|
|
@@ -85176,15 +86622,15 @@ async function checkAstGrepNapi() {
|
|
|
85176
86622
|
path: null
|
|
85177
86623
|
};
|
|
85178
86624
|
} catch {
|
|
85179
|
-
const { existsSync:
|
|
85180
|
-
const { join:
|
|
85181
|
-
const { homedir:
|
|
86625
|
+
const { existsSync: existsSync48 } = await import("fs");
|
|
86626
|
+
const { join: join55 } = await import("path");
|
|
86627
|
+
const { homedir: homedir15 } = await import("os");
|
|
85182
86628
|
const pathsToCheck = [
|
|
85183
|
-
|
|
85184
|
-
|
|
86629
|
+
join55(homedir15(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
|
|
86630
|
+
join55(process.cwd(), "node_modules", "@ast-grep", "napi")
|
|
85185
86631
|
];
|
|
85186
86632
|
for (const napiPath of pathsToCheck) {
|
|
85187
|
-
if (
|
|
86633
|
+
if (existsSync48(napiPath)) {
|
|
85188
86634
|
return {
|
|
85189
86635
|
name: "AST-Grep NAPI",
|
|
85190
86636
|
required: false,
|
|
@@ -85209,8 +86655,8 @@ function findCommentCheckerPackageBinary() {
|
|
|
85209
86655
|
try {
|
|
85210
86656
|
const require2 = createRequire2(import.meta.url);
|
|
85211
86657
|
const pkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
|
|
85212
|
-
const binaryPath =
|
|
85213
|
-
if (
|
|
86658
|
+
const binaryPath = join54(dirname22(pkgPath), "bin", binaryName);
|
|
86659
|
+
if (existsSync47(binaryPath))
|
|
85214
86660
|
return binaryPath;
|
|
85215
86661
|
} catch {}
|
|
85216
86662
|
return null;
|
|
@@ -85343,11 +86789,11 @@ async function getGhCliInfo() {
|
|
|
85343
86789
|
|
|
85344
86790
|
// src/cli/doctor/checks/tools-lsp.ts
|
|
85345
86791
|
import { readFileSync as readFileSync35 } from "fs";
|
|
85346
|
-
import { join as
|
|
86792
|
+
import { join as join55 } from "path";
|
|
85347
86793
|
|
|
85348
86794
|
// src/mcp/lsp.ts
|
|
85349
|
-
import { existsSync as
|
|
85350
|
-
import { dirname as
|
|
86795
|
+
import { existsSync as existsSync48 } from "fs";
|
|
86796
|
+
import { dirname as dirname23, resolve as resolve12 } from "path";
|
|
85351
86797
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
85352
86798
|
|
|
85353
86799
|
// src/mcp/cli-suffix.ts
|
|
@@ -85360,66 +86806,6 @@ function hasCliSuffix(candidatePath, suffix) {
|
|
|
85360
86806
|
|
|
85361
86807
|
// src/mcp/runtime-executable.ts
|
|
85362
86808
|
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
86809
|
var NODE_EXECUTABLE_NAMES = new Set(["node", "node.exe"]);
|
|
85424
86810
|
function isUnsafeCommandName2(commandName) {
|
|
85425
86811
|
if (commandName.length === 0)
|
|
@@ -85481,9 +86867,9 @@ var LSP_BOOTSTRAP_SCRIPT = [
|
|
|
85481
86867
|
"finish(run(process.execPath, [dist, 'mcp'], 'inherit'))"
|
|
85482
86868
|
].join(";");
|
|
85483
86869
|
function addAncestorCommandCandidates(startDirectory, target, seenPaths, pathExists, resolveExecutable) {
|
|
85484
|
-
let currentDirectory =
|
|
86870
|
+
let currentDirectory = resolve12(startDirectory);
|
|
85485
86871
|
while (true) {
|
|
85486
|
-
const distCliPath =
|
|
86872
|
+
const distCliPath = resolve12(currentDirectory, SUBMODULE_REL, DIST_CLI_REL);
|
|
85487
86873
|
if (!seenPaths.has(distCliPath)) {
|
|
85488
86874
|
const runtime4 = resolveJavaScriptRuntime(resolveExecutable);
|
|
85489
86875
|
seenPaths.add(distCliPath);
|
|
@@ -85494,7 +86880,7 @@ function addAncestorCommandCandidates(startDirectory, target, seenPaths, pathExi
|
|
|
85494
86880
|
exists: runtime4.available && pathExists(distCliPath)
|
|
85495
86881
|
});
|
|
85496
86882
|
}
|
|
85497
|
-
const sourceCliPath =
|
|
86883
|
+
const sourceCliPath = resolve12(currentDirectory, SUBMODULE_REL, SOURCE_CLI_REL);
|
|
85498
86884
|
if (!seenPaths.has(sourceCliPath)) {
|
|
85499
86885
|
const runtime4 = resolveExecutable("bun");
|
|
85500
86886
|
seenPaths.add(sourceCliPath);
|
|
@@ -85505,7 +86891,7 @@ function addAncestorCommandCandidates(startDirectory, target, seenPaths, pathExi
|
|
|
85505
86891
|
exists: runtime4.available && pathExists(sourceCliPath)
|
|
85506
86892
|
});
|
|
85507
86893
|
}
|
|
85508
|
-
const parentDirectory =
|
|
86894
|
+
const parentDirectory = resolve12(currentDirectory, "..");
|
|
85509
86895
|
if (parentDirectory === currentDirectory) {
|
|
85510
86896
|
return;
|
|
85511
86897
|
}
|
|
@@ -85514,13 +86900,13 @@ function addAncestorCommandCandidates(startDirectory, target, seenPaths, pathExi
|
|
|
85514
86900
|
}
|
|
85515
86901
|
function getModuleDirectory(moduleUrl) {
|
|
85516
86902
|
try {
|
|
85517
|
-
return
|
|
86903
|
+
return dirname23(fileURLToPath3(moduleUrl));
|
|
85518
86904
|
} catch {
|
|
85519
86905
|
return null;
|
|
85520
86906
|
}
|
|
85521
86907
|
}
|
|
85522
86908
|
function findBootstrapRoot(candidates, pathExists) {
|
|
85523
|
-
return candidates.find((candidate) => pathExists(
|
|
86909
|
+
return candidates.find((candidate) => pathExists(resolve12(candidate.root, "package.json")))?.root ?? process.cwd();
|
|
85524
86910
|
}
|
|
85525
86911
|
function resolveJavaScriptRuntime(resolveExecutable) {
|
|
85526
86912
|
const node = resolveExecutable("node");
|
|
@@ -85534,12 +86920,12 @@ function createBootstrapCandidate(root, resolveExecutable) {
|
|
|
85534
86920
|
return {
|
|
85535
86921
|
command: [runtime4.command, "-e", LSP_BOOTSTRAP_SCRIPT, root, git.command, npm.command, bun.command],
|
|
85536
86922
|
root,
|
|
85537
|
-
path:
|
|
86923
|
+
path: resolve12(root, SUBMODULE_REL, DIST_CLI_REL),
|
|
85538
86924
|
exists: runtime4.available && git.available && npm.available
|
|
85539
86925
|
};
|
|
85540
86926
|
}
|
|
85541
86927
|
function resolveLspCommand(options = {}) {
|
|
85542
|
-
const pathExists = options.exists ??
|
|
86928
|
+
const pathExists = options.exists ?? existsSync48;
|
|
85543
86929
|
const resolveExecutable = options.resolveExecutable ?? resolveRuntimeExecutable;
|
|
85544
86930
|
const candidates = [];
|
|
85545
86931
|
const seenPaths = new Set;
|
|
@@ -85589,7 +86975,7 @@ function readOmoConfig(configDirectory) {
|
|
|
85589
86975
|
}
|
|
85590
86976
|
function isLspMcpDisabled(options) {
|
|
85591
86977
|
const userConfigDirectory = options.configDirectory ?? getOpenCodeConfigDir({ binary: "opencode" });
|
|
85592
|
-
const projectConfigDirectory =
|
|
86978
|
+
const projectConfigDirectory = join55(options.cwd ?? process.cwd(), ".opencode");
|
|
85593
86979
|
const userConfig = readOmoConfig(userConfigDirectory);
|
|
85594
86980
|
const projectConfig = readOmoConfig(projectConfigDirectory);
|
|
85595
86981
|
const disabledMcps = new Set([
|
|
@@ -85608,21 +86994,21 @@ function getInstalledLspServers(options = {}) {
|
|
|
85608
86994
|
|
|
85609
86995
|
// src/cli/doctor/checks/tools-mcp.ts
|
|
85610
86996
|
init_shared();
|
|
85611
|
-
import { existsSync as
|
|
85612
|
-
import { homedir as
|
|
85613
|
-
import { join as
|
|
86997
|
+
import { existsSync as existsSync49, readFileSync as readFileSync36 } from "fs";
|
|
86998
|
+
import { homedir as homedir15 } from "os";
|
|
86999
|
+
import { join as join56 } from "path";
|
|
85614
87000
|
var BUILTIN_MCP_SERVERS = ["websearch", "context7", "grep_app", "lsp", "ast_grep"];
|
|
85615
87001
|
function getMcpConfigPaths() {
|
|
85616
87002
|
return [
|
|
85617
|
-
|
|
85618
|
-
|
|
85619
|
-
|
|
87003
|
+
join56(homedir15(), ".claude", ".mcp.json"),
|
|
87004
|
+
join56(process.cwd(), ".mcp.json"),
|
|
87005
|
+
join56(process.cwd(), ".claude", ".mcp.json")
|
|
85620
87006
|
];
|
|
85621
87007
|
}
|
|
85622
87008
|
function loadUserMcpConfig() {
|
|
85623
87009
|
const servers = {};
|
|
85624
87010
|
for (const configPath of getMcpConfigPaths()) {
|
|
85625
|
-
if (!
|
|
87011
|
+
if (!existsSync49(configPath))
|
|
85626
87012
|
continue;
|
|
85627
87013
|
try {
|
|
85628
87014
|
const content = readFileSync36(configPath, "utf-8");
|
|
@@ -85779,10 +87165,10 @@ async function probeBinary(cmd, args) {
|
|
|
85779
87165
|
|
|
85780
87166
|
// src/features/team-mode/team-registry/paths.ts
|
|
85781
87167
|
init_logger();
|
|
85782
|
-
import { homedir as
|
|
87168
|
+
import { homedir as homedir16 } from "os";
|
|
85783
87169
|
import path14 from "path";
|
|
85784
87170
|
function resolveBaseDir(config2) {
|
|
85785
|
-
return config2.base_dir ?? path14.join(
|
|
87171
|
+
return config2.base_dir ?? path14.join(homedir16(), ".omo");
|
|
85786
87172
|
}
|
|
85787
87173
|
|
|
85788
87174
|
// src/cli/doctor/checks/team-mode.ts
|
|
@@ -85849,8 +87235,8 @@ async function pathExists(dir) {
|
|
|
85849
87235
|
|
|
85850
87236
|
// src/cli/doctor/checks/tui-plugin-config.ts
|
|
85851
87237
|
init_shared();
|
|
85852
|
-
import { existsSync as
|
|
85853
|
-
import { join as
|
|
87238
|
+
import { existsSync as existsSync50, readFileSync as readFileSync38 } from "fs";
|
|
87239
|
+
import { join as join57 } from "path";
|
|
85854
87240
|
var TUI_SUBPATH = "tui";
|
|
85855
87241
|
function isOurFilePluginEntry(entry) {
|
|
85856
87242
|
if (!entry.startsWith("file:"))
|
|
@@ -85859,8 +87245,8 @@ function isOurFilePluginEntry(entry) {
|
|
|
85859
87245
|
if (path16.startsWith("//"))
|
|
85860
87246
|
path16 = path16.slice(2);
|
|
85861
87247
|
try {
|
|
85862
|
-
const pkgJsonPath =
|
|
85863
|
-
if (!
|
|
87248
|
+
const pkgJsonPath = join57(path16, "package.json");
|
|
87249
|
+
if (!existsSync50(pkgJsonPath))
|
|
85864
87250
|
return false;
|
|
85865
87251
|
const parsed = JSON.parse(readFileSync38(pkgJsonPath, "utf-8"));
|
|
85866
87252
|
return typeof parsed.name === "string" && ACCEPTED_PACKAGE_NAMES.includes(parsed.name);
|
|
@@ -85890,7 +87276,7 @@ function isTuiPluginEntry(entry) {
|
|
|
85890
87276
|
}
|
|
85891
87277
|
function detectServerPluginRegistration() {
|
|
85892
87278
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
85893
|
-
const configPath =
|
|
87279
|
+
const configPath = existsSync50(paths.configJsonc) ? paths.configJsonc : existsSync50(paths.configJson) ? paths.configJson : null;
|
|
85894
87280
|
if (!configPath) {
|
|
85895
87281
|
return { registered: false, configPath: null };
|
|
85896
87282
|
}
|
|
@@ -85903,8 +87289,8 @@ function detectServerPluginRegistration() {
|
|
|
85903
87289
|
}
|
|
85904
87290
|
}
|
|
85905
87291
|
function detectTuiPluginRegistration() {
|
|
85906
|
-
const tuiJsonPath =
|
|
85907
|
-
if (!
|
|
87292
|
+
const tuiJsonPath = join57(getOpenCodeConfigDir({ binary: "opencode" }), "tui.json");
|
|
87293
|
+
if (!existsSync50(tuiJsonPath)) {
|
|
85908
87294
|
return { registered: false, configPath: tuiJsonPath, exists: false };
|
|
85909
87295
|
}
|
|
85910
87296
|
try {
|
|
@@ -86361,11 +87747,11 @@ async function refreshModelCapabilities(options, deps = {}) {
|
|
|
86361
87747
|
|
|
86362
87748
|
// src/features/mcp-oauth/storage.ts
|
|
86363
87749
|
init_shared();
|
|
86364
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
86365
|
-
import { dirname as
|
|
87750
|
+
import { chmodSync as chmodSync2, existsSync as existsSync51, mkdirSync as mkdirSync13, readFileSync as readFileSync39, renameSync as renameSync6, unlinkSync as unlinkSync8, writeFileSync as writeFileSync10 } from "fs";
|
|
87751
|
+
import { dirname as dirname24, join as join58 } from "path";
|
|
86366
87752
|
var STORAGE_FILE_NAME = "mcp-oauth.json";
|
|
86367
87753
|
function getMcpOauthStoragePath() {
|
|
86368
|
-
return
|
|
87754
|
+
return join58(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
|
|
86369
87755
|
}
|
|
86370
87756
|
function normalizeHost2(serverHost) {
|
|
86371
87757
|
let host = serverHost.trim();
|
|
@@ -86402,7 +87788,7 @@ function buildKey(serverHost, resource) {
|
|
|
86402
87788
|
}
|
|
86403
87789
|
function readStore() {
|
|
86404
87790
|
const filePath = getMcpOauthStoragePath();
|
|
86405
|
-
if (!
|
|
87791
|
+
if (!existsSync51(filePath)) {
|
|
86406
87792
|
return null;
|
|
86407
87793
|
}
|
|
86408
87794
|
try {
|
|
@@ -86415,8 +87801,8 @@ function readStore() {
|
|
|
86415
87801
|
function writeStore(store2) {
|
|
86416
87802
|
const filePath = getMcpOauthStoragePath();
|
|
86417
87803
|
try {
|
|
86418
|
-
const dir =
|
|
86419
|
-
if (!
|
|
87804
|
+
const dir = dirname24(filePath);
|
|
87805
|
+
if (!existsSync51(dir)) {
|
|
86420
87806
|
mkdirSync13(dir, { recursive: true });
|
|
86421
87807
|
}
|
|
86422
87808
|
const tempPath = `${filePath}.tmp.${Date.now()}`;
|
|
@@ -86453,7 +87839,7 @@ function deleteToken(serverHost, resource) {
|
|
|
86453
87839
|
if (Object.keys(store2).length === 0) {
|
|
86454
87840
|
try {
|
|
86455
87841
|
const filePath = getMcpOauthStoragePath();
|
|
86456
|
-
if (
|
|
87842
|
+
if (existsSync51(filePath)) {
|
|
86457
87843
|
unlinkSync8(filePath);
|
|
86458
87844
|
}
|
|
86459
87845
|
return true;
|
|
@@ -86622,7 +88008,7 @@ async function getOrRegisterClient(options) {
|
|
|
86622
88008
|
}
|
|
86623
88009
|
}
|
|
86624
88010
|
function parseRegistrationResponse(data) {
|
|
86625
|
-
if (!
|
|
88011
|
+
if (!isRecord16(data))
|
|
86626
88012
|
return null;
|
|
86627
88013
|
const clientId = data.client_id;
|
|
86628
88014
|
if (typeof clientId !== "string" || clientId.length === 0)
|
|
@@ -86633,7 +88019,7 @@ function parseRegistrationResponse(data) {
|
|
|
86633
88019
|
}
|
|
86634
88020
|
return { clientId };
|
|
86635
88021
|
}
|
|
86636
|
-
function
|
|
88022
|
+
function isRecord16(value) {
|
|
86637
88023
|
return typeof value === "object" && value !== null;
|
|
86638
88024
|
}
|
|
86639
88025
|
|
|
@@ -86647,13 +88033,13 @@ async function findAvailablePort2(startPort = DEFAULT_PORT) {
|
|
|
86647
88033
|
|
|
86648
88034
|
// src/features/mcp-oauth/oauth-authorization-flow.ts
|
|
86649
88035
|
import { spawn as spawn2 } from "child_process";
|
|
86650
|
-
import { createHash as
|
|
88036
|
+
import { createHash as createHash5, randomBytes as randomBytes2 } from "crypto";
|
|
86651
88037
|
import { createServer as createServer2 } from "http";
|
|
86652
88038
|
function generateCodeVerifier() {
|
|
86653
88039
|
return randomBytes2(32).toString("base64url");
|
|
86654
88040
|
}
|
|
86655
88041
|
function generateCodeChallenge(verifier) {
|
|
86656
|
-
return
|
|
88042
|
+
return createHash5("sha256").update(verifier).digest("base64url");
|
|
86657
88043
|
}
|
|
86658
88044
|
function buildAuthorizationUrl(authorizationEndpoint, options) {
|
|
86659
88045
|
const url2 = new URL(authorizationEndpoint);
|
|
@@ -86673,7 +88059,7 @@ function buildAuthorizationUrl(authorizationEndpoint, options) {
|
|
|
86673
88059
|
}
|
|
86674
88060
|
var CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
|
|
86675
88061
|
function startCallbackServer(port) {
|
|
86676
|
-
return new Promise((
|
|
88062
|
+
return new Promise((resolve13, reject) => {
|
|
86677
88063
|
let timeoutId;
|
|
86678
88064
|
const server2 = createServer2((request, response) => {
|
|
86679
88065
|
clearTimeout(timeoutId);
|
|
@@ -86699,7 +88085,7 @@ function startCallbackServer(port) {
|
|
|
86699
88085
|
response.writeHead(200, { "content-type": "text/html" });
|
|
86700
88086
|
response.end("<html><body><h1>Authorization successful. You can close this tab.</h1></body></html>");
|
|
86701
88087
|
server2.close();
|
|
86702
|
-
|
|
88088
|
+
resolve13({ code, state: state2 });
|
|
86703
88089
|
});
|
|
86704
88090
|
timeoutId = setTimeout(() => {
|
|
86705
88091
|
server2.close();
|
|
@@ -87033,7 +88419,7 @@ function createMcpOAuthCommand() {
|
|
|
87033
88419
|
}
|
|
87034
88420
|
|
|
87035
88421
|
// src/cli/boulder/boulder.ts
|
|
87036
|
-
import { existsSync as
|
|
88422
|
+
import { existsSync as existsSync52 } from "fs";
|
|
87037
88423
|
|
|
87038
88424
|
// src/cli/boulder/formatter.ts
|
|
87039
88425
|
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
@@ -87170,10 +88556,10 @@ async function boulder(options) {
|
|
|
87170
88556
|
const boulderFilePath = getBoulderFilePath(directory);
|
|
87171
88557
|
const state2 = readBoulderState(directory);
|
|
87172
88558
|
if (!state2) {
|
|
87173
|
-
const message =
|
|
88559
|
+
const message = existsSync52(boulderFilePath) ? formatReadErrorMessage(options.json) : formatNoBoulderMessage(options.json);
|
|
87174
88560
|
process.stderr.write(`${message}
|
|
87175
88561
|
`);
|
|
87176
|
-
return
|
|
88562
|
+
return existsSync52(boulderFilePath) ? 2 : 1;
|
|
87177
88563
|
}
|
|
87178
88564
|
const works = getBoulderWorks(state2);
|
|
87179
88565
|
const filteredWorks = options.workId ? works.filter((work) => work.work_id === options.workId) : works;
|
|
@@ -87193,7 +88579,7 @@ async function boulder(options) {
|
|
|
87193
88579
|
var VERSION2 = package_default.version;
|
|
87194
88580
|
var program2 = new Command;
|
|
87195
88581
|
function resolveInstallArgs(options, invocationName = process.env.OMO_INVOCATION_NAME) {
|
|
87196
|
-
const defaultPlatform = invocationName === "lazycodex" ? "codex" : undefined;
|
|
88582
|
+
const defaultPlatform = invocationName === "lazycodex" || invocationName === "lazycodex-ai" ? "codex" : undefined;
|
|
87197
88583
|
return {
|
|
87198
88584
|
tui: options.tui !== false,
|
|
87199
88585
|
claude: options.claude,
|
|
@@ -87214,7 +88600,7 @@ program2.name("oh-my-opencode").description("The ultimate OpenCode plugin - mult
|
|
|
87214
88600
|
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
88601
|
Examples:
|
|
87216
88602
|
$ bunx oh-my-opencode install
|
|
87217
|
-
$
|
|
88603
|
+
$ npx lazycodex-ai install --no-tui
|
|
87218
88604
|
$ bunx oh-my-opencode install --no-tui --platform=both --claude=max20 --openai=yes --gemini=yes --copilot=no
|
|
87219
88605
|
$ omo install --platform=codex --codex-autonomous
|
|
87220
88606
|
$ bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=yes --opencode-zen=yes
|
|
@@ -87234,6 +88620,7 @@ Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi > Verce
|
|
|
87234
88620
|
const exitCode = await install(args);
|
|
87235
88621
|
process.exit(exitCode);
|
|
87236
88622
|
});
|
|
88623
|
+
configureCleanupCommand(program2);
|
|
87237
88624
|
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
88625
|
Examples:
|
|
87239
88626
|
$ bunx oh-my-opencode run "Fix the bug in index.ts"
|