oh-my-codex 0.18.16 → 0.19.1
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/Cargo.lock +6 -6
- package/Cargo.toml +1 -1
- package/README.md +5 -0
- package/crates/omx-sparkshell/tests/execution.rs +8 -1
- package/dist/agents/__tests__/definitions.test.js +5 -5
- package/dist/agents/__tests__/definitions.test.js.map +1 -1
- package/dist/agents/__tests__/native-config.test.js +18 -14
- package/dist/agents/__tests__/native-config.test.js.map +1 -1
- package/dist/agents/definitions.d.ts +2 -2
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +4 -4
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/native-config.d.ts +1 -0
- package/dist/agents/native-config.d.ts.map +1 -1
- package/dist/agents/native-config.js +18 -16
- package/dist/agents/native-config.js.map +1 -1
- package/dist/auth/hotswap.d.ts.map +1 -1
- package/dist/auth/hotswap.js +17 -4
- package/dist/auth/hotswap.js.map +1 -1
- package/dist/autopilot/__tests__/planner-routing.test.js +2 -2
- package/dist/autopilot/__tests__/planner-routing.test.js.map +1 -1
- package/dist/autopilot/fsm.d.ts +1 -1
- package/dist/autopilot/fsm.d.ts.map +1 -1
- package/dist/autopilot/fsm.js +1 -1
- package/dist/autopilot/fsm.js.map +1 -1
- package/dist/cli/__tests__/auth.test.js +78 -3
- package/dist/cli/__tests__/auth.test.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js +30 -5
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +2 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +96 -8
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +135 -1
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/mcp-parity.test.js +2 -4
- package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
- package/dist/cli/__tests__/mission.test.d.ts +2 -0
- package/dist/cli/__tests__/mission.test.d.ts.map +1 -0
- package/dist/cli/__tests__/mission.test.js +239 -0
- package/dist/cli/__tests__/mission.test.js.map +1 -0
- package/dist/cli/__tests__/plugin-marketplace-idempotent.test.js +14 -0
- package/dist/cli/__tests__/plugin-marketplace-idempotent.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +8 -0
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
- package/dist/cli/__tests__/resume.test.js +229 -1
- package/dist/cli/__tests__/resume.test.js.map +1 -1
- package/dist/cli/__tests__/session-scoped-runtime.test.js +113 -0
- package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.js +37 -0
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/__tests__/ultragoal.test.js +22 -1
- package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
- package/dist/cli/__tests__/version.test.js +13 -1
- package/dist/cli/__tests__/version.test.js.map +1 -1
- package/dist/cli/auth.d.ts +1 -1
- package/dist/cli/auth.d.ts.map +1 -1
- package/dist/cli/auth.js +49 -9
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/index.d.ts +27 -4
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +263 -36
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mission.d.ts +36 -0
- package/dist/cli/mission.d.ts.map +1 -0
- package/dist/cli/mission.js +443 -0
- package/dist/cli/mission.js.map +1 -0
- package/dist/cli/plugin-marketplace.d.ts.map +1 -1
- package/dist/cli/plugin-marketplace.js +22 -1
- package/dist/cli/plugin-marketplace.js.map +1 -1
- package/dist/cli/ralph.d.ts.map +1 -1
- package/dist/cli/ralph.js +4 -0
- package/dist/cli/ralph.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +3 -1
- package/dist/cli/setup.js.map +1 -1
- package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js +7 -0
- package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js.map +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.js +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js +12 -0
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +267 -7
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +143 -30
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hud/__tests__/reconcile.test.js +121 -0
- package/dist/hud/__tests__/reconcile.test.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +141 -6
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/__tests__/tmux.test.js +1 -1
- package/dist/hud/__tests__/tmux.test.js.map +1 -1
- package/dist/hud/reconcile.d.ts +3 -1
- package/dist/hud/reconcile.d.ts.map +1 -1
- package/dist/hud/reconcile.js +281 -151
- package/dist/hud/reconcile.js.map +1 -1
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +4 -2
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +51 -15
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/tmux.d.ts.map +1 -1
- package/dist/hud/tmux.js +1 -4
- package/dist/hud/tmux.js.map +1 -1
- package/dist/hud/types.d.ts +5 -0
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js.map +1 -1
- package/dist/leader/__tests__/contract.test.d.ts +2 -0
- package/dist/leader/__tests__/contract.test.d.ts.map +1 -0
- package/dist/leader/__tests__/contract.test.js +75 -0
- package/dist/leader/__tests__/contract.test.js.map +1 -0
- package/dist/leader/contract.d.ts +26 -0
- package/dist/leader/contract.d.ts.map +1 -0
- package/dist/leader/contract.js +97 -0
- package/dist/leader/contract.js.map +1 -0
- package/dist/mcp/__tests__/state-paths.test.js +32 -1
- package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
- package/dist/mcp/state-paths.d.ts +4 -0
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +6 -15
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +22 -7
- package/dist/modes/base.js.map +1 -1
- package/dist/notifications/__tests__/dispatcher.test.js +16 -0
- package/dist/notifications/__tests__/dispatcher.test.js.map +1 -1
- package/dist/notifications/__tests__/profiles.test.js +87 -0
- package/dist/notifications/__tests__/profiles.test.js.map +1 -1
- package/dist/notifications/config.d.ts +1 -0
- package/dist/notifications/config.d.ts.map +1 -1
- package/dist/notifications/config.js +60 -22
- package/dist/notifications/config.js.map +1 -1
- package/dist/notifications/dispatcher.d.ts.map +1 -1
- package/dist/notifications/dispatcher.js +6 -16
- package/dist/notifications/dispatcher.js.map +1 -1
- package/dist/pipeline/__tests__/stages.test.js +2 -0
- package/dist/pipeline/__tests__/stages.test.js.map +1 -1
- package/dist/pipeline/stages/ultragoal.d.ts.map +1 -1
- package/dist/pipeline/stages/ultragoal.js +6 -1
- package/dist/pipeline/stages/ultragoal.js.map +1 -1
- package/dist/question/__tests__/renderer.test.js +58 -4
- package/dist/question/__tests__/renderer.test.js.map +1 -1
- package/dist/question/renderer.d.ts +1 -1
- package/dist/question/renderer.d.ts.map +1 -1
- package/dist/question/renderer.js +73 -5
- package/dist/question/renderer.js.map +1 -1
- package/dist/ralplan/__tests__/consensus-gate.test.js +193 -0
- package/dist/ralplan/__tests__/consensus-gate.test.js.map +1 -1
- package/dist/ralplan/__tests__/runtime.test.js +202 -0
- package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
- package/dist/ralplan/consensus-gate.js +24 -3
- package/dist/ralplan/consensus-gate.js.map +1 -1
- package/dist/ralplan/runtime.d.ts +7 -0
- package/dist/ralplan/runtime.d.ts.map +1 -1
- package/dist/ralplan/runtime.js +63 -4
- package/dist/ralplan/runtime.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +6935 -2681
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/codex-native-hook.d.ts +1 -0
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +4442 -187
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/generate-catalog-docs.js +1 -0
- package/dist/scripts/generate-catalog-docs.js.map +1 -1
- package/dist/state/__tests__/operations.test.js +1424 -0
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/state/__tests__/planning-gate.test.js +410 -0
- package/dist/state/__tests__/planning-gate.test.js.map +1 -1
- package/dist/state/__tests__/skill-active.test.js +59 -0
- package/dist/state/__tests__/skill-active.test.js.map +1 -1
- package/dist/state/operations.d.ts +10 -0
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +250 -14
- package/dist/state/operations.js.map +1 -1
- package/dist/state/skill-active.d.ts +4 -1
- package/dist/state/skill-active.d.ts.map +1 -1
- package/dist/state/skill-active.js +8 -6
- package/dist/state/skill-active.js.map +1 -1
- package/dist/state/workflow-transition.d.ts.map +1 -1
- package/dist/state/workflow-transition.js +642 -1
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/subagents/__tests__/tracker.test.js +248 -1
- package/dist/subagents/__tests__/tracker.test.js.map +1 -1
- package/dist/subagents/tracker.d.ts +60 -0
- package/dist/subagents/tracker.d.ts.map +1 -1
- package/dist/subagents/tracker.js +225 -1
- package/dist/subagents/tracker.js.map +1 -1
- package/dist/team/__tests__/model-contract.test.js +72 -4
- package/dist/team/__tests__/model-contract.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +44 -2
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +127 -8
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worker-runtime-identity.test.js +89 -0
- package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
- package/dist/team/model-contract.d.ts +3 -0
- package/dist/team/model-contract.d.ts.map +1 -1
- package/dist/team/model-contract.js +42 -5
- package/dist/team/model-contract.js.map +1 -1
- package/dist/team/runtime.d.ts +2 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +21 -11
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +13 -11
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/tmux-session.d.ts +1 -0
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +63 -13
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/ultragoal/__tests__/artifacts.test.js +21 -4
- package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
- package/dist/ultragoal/artifacts.d.ts.map +1 -1
- package/dist/ultragoal/artifacts.js +75 -5
- package/dist/ultragoal/artifacts.js.map +1 -1
- package/dist/utils/__tests__/agents-model-table.test.js +2 -2
- package/dist/utils/__tests__/agents-model-table.test.js.map +1 -1
- package/package.json +1 -1
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +19 -7
- package/plugins/oh-my-codex/skills/code-review/SKILL.md +16 -0
- package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +23 -0
- package/plugins/oh-my-codex/skills/ultrawork/references/agent-tiers.md +3 -2
- package/skills/code-review/SKILL.md +16 -0
- package/skills/ecomode/references/agent-tiers.md +1 -1
- package/skills/ultragoal/SKILL.md +23 -0
- package/skills/ultrawork/references/agent-tiers.md +3 -2
- package/src/scripts/__tests__/codex-native-hook.test.ts +14843 -9586
- package/src/scripts/codex-native-hook.ts +4520 -194
- package/src/scripts/generate-catalog-docs.ts +1 -0
package/dist/cli/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { execFileSync, spawn } from "child_process";
|
|
6
6
|
import { basename, dirname, join, posix, resolve, win32 } from "path";
|
|
7
7
|
import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, rmSync, statSync, writeFileSync } from "fs";
|
|
8
|
-
import { copyFile, cp, lstat, mkdir, readFile, readdir, rm, symlink, writeFile } from "fs/promises";
|
|
8
|
+
import { copyFile, cp, lstat, mkdir, readFile, readdir, rm, stat, symlink, writeFile } from "fs/promises";
|
|
9
9
|
import { constants as osConstants, homedir } from "os";
|
|
10
10
|
import { createHash } from "crypto";
|
|
11
11
|
import { setup, SETUP_MCP_MODES, SETUP_SCOPES, SETUP_TEAM_MODES, } from "./setup.js";
|
|
@@ -37,12 +37,14 @@ import { mcpServeCommand } from "./mcp-serve.js";
|
|
|
37
37
|
import { adaptCommand } from "./adapt.js";
|
|
38
38
|
import { listCommand } from "./list.js";
|
|
39
39
|
import { authCommand } from "./auth.js";
|
|
40
|
+
import { missionCommand } from "./mission.js";
|
|
40
41
|
import { runAuthHotswap } from "../auth/hotswap.js";
|
|
41
42
|
import { MADMAX_FLAG, CODEX_BYPASS_FLAG, HIGH_REASONING_FLAG, XHIGH_REASONING_FLAG, SPARK_FLAG, MADMAX_SPARK_FLAG, CONFIG_FLAG, LONG_CONFIG_FLAG, } from "./constants.js";
|
|
42
43
|
import { getBaseStateDir, getStateDir, listModeStateFilesWithScopePreference, } from "../mcp/state-paths.js";
|
|
43
44
|
import { evaluateRalphCompletionAuditEvidence, isRalphCompletePhase } from "../ralph/completion-audit.js";
|
|
44
45
|
import { readPersistedSetupPreferences, resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, resolveProjectLocalCodexHomeForLaunch, } from "./codex-home.js";
|
|
45
46
|
import { discoverProjectRuntimeCodexHomes } from "./project-runtime-codex-homes.js";
|
|
47
|
+
import { materializePackagedOmxPluginCache, packagedOmxPluginVersion, resolvePackagedOmxMarketplace, upsertLocalOmxMarketplaceRegistration, upsertLocalOmxPluginEnablement, } from "./plugin-marketplace.js";
|
|
46
48
|
import { escapeTomlString, readTopLevelTomlString, upsertTopLevelTomlString } from "../utils/toml.js";
|
|
47
49
|
export { readPersistedSetupPreferences, readPersistedSetupScope, resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, resolveProjectLocalCodexHomeForLaunch, } from "./codex-home.js";
|
|
48
50
|
import { SKILL_ACTIVE_STATE_MODE, extractSessionIdFromInitializedStatePath, getSkillActiveStatePathsForStateDir, listActiveSkills, readSkillActiveState, syncCanonicalSkillStateForMode, } from "../state/skill-active.js";
|
|
@@ -65,7 +67,7 @@ rememberOmxLaunchContext({ argv1: process.argv[1], cwd: process.cwd(), env: proc
|
|
|
65
67
|
import { classifySpawnError, resolveTmuxBinaryForPlatform, spawnPlatformCommandSync, } from "../utils/platform-command.js";
|
|
66
68
|
import { buildHookEvent } from "../hooks/extensibility/events.js";
|
|
67
69
|
import { dispatchHookEvent } from "../hooks/extensibility/dispatcher.js";
|
|
68
|
-
import { collectInheritableTeamWorkerArgs as collectInheritableTeamWorkerArgsShared, resolveTeamWorkerLaunchArgs, resolveTeamLowComplexityDefaultModel, } from "../team/model-contract.js";
|
|
70
|
+
import { collectInheritableTeamWorkerArgs as collectInheritableTeamWorkerArgsShared, parseTeamWorkerLaunchArgs, resolveTeamWorkerLaunchArgs, resolveTeamLowComplexityDefaultModel, TEAM_WORKER_INHERITED_MODEL_ENV, } from "../team/model-contract.js";
|
|
69
71
|
import { parseWorktreeMode, planWorktreeTarget, ensureWorktree, } from "../team/worktree.js";
|
|
70
72
|
import { ensureReusableNodeModules } from "../utils/repo-deps.js";
|
|
71
73
|
import { OMX_NOTIFY_TEMP_CONTRACT_ENV, parseNotifyTempContractFromArgs, serializeNotifyTempContract, } from "../notifications/temp-contract.js";
|
|
@@ -91,6 +93,8 @@ Usage:
|
|
|
91
93
|
omx exec Run codex exec non-interactively with OMX AGENTS/overlay injection
|
|
92
94
|
omx exec inject <session-id> --prompt <text>
|
|
93
95
|
Queue audited follow-up instructions for a running non-interactive exec job
|
|
96
|
+
omx mission <file>
|
|
97
|
+
Run a prompt/checklist file sequentially through omx exec with durable summary
|
|
94
98
|
omx imagegen continuation <session-id> --artifact <name>
|
|
95
99
|
Queue a Stop-hook continuation for built-in image generation turns
|
|
96
100
|
omx setup Install skills, prompts, CLI-first config, and scope-specific AGENTS.md
|
|
@@ -260,6 +264,7 @@ const NESTED_HELP_COMMANDS = new Set([
|
|
|
260
264
|
"agents-init",
|
|
261
265
|
"deepinit",
|
|
262
266
|
"exec",
|
|
267
|
+
"mission",
|
|
263
268
|
"imagegen",
|
|
264
269
|
"hooks",
|
|
265
270
|
"list",
|
|
@@ -667,26 +672,43 @@ async function materializeProjectLaunchRuntimeHistoryEntries(runtimeCodexHome, s
|
|
|
667
672
|
await copyFile(source, destination);
|
|
668
673
|
}
|
|
669
674
|
}
|
|
670
|
-
async function mergeProjectLaunchRuntimeHistoryEntries(runtimeCodexHome, sourceCodexHome) {
|
|
675
|
+
async function mergeProjectLaunchRuntimeHistoryEntries(runtimeCodexHome, sourceCodexHome, mergedHistorySourceRealpaths) {
|
|
671
676
|
for (const entryName of PROJECT_LAUNCH_DURABLE_HISTORY_ENTRY_NAMES) {
|
|
672
677
|
const source = join(sourceCodexHome, entryName);
|
|
673
678
|
if (!existsSync(source))
|
|
674
679
|
continue;
|
|
680
|
+
const sourceRealpath = realpathSync(source);
|
|
681
|
+
if (mergedHistorySourceRealpaths.has(sourceRealpath))
|
|
682
|
+
continue;
|
|
675
683
|
const destination = join(runtimeCodexHome, entryName);
|
|
676
|
-
const sourceStat = await
|
|
684
|
+
const sourceStat = await stat(source);
|
|
677
685
|
if (sourceStat.isDirectory()) {
|
|
678
686
|
await mkdir(destination, { recursive: true });
|
|
679
687
|
await cp(source, destination, { recursive: true, force: true, dereference: true });
|
|
688
|
+
mergedHistorySourceRealpaths.add(sourceRealpath);
|
|
680
689
|
continue;
|
|
681
690
|
}
|
|
691
|
+
if (entryName === "sessions")
|
|
692
|
+
continue;
|
|
693
|
+
if (!sourceStat.isFile())
|
|
694
|
+
continue;
|
|
682
695
|
if (existsSync(destination)) {
|
|
696
|
+
const destinationStat = await stat(destination);
|
|
697
|
+
if (!destinationStat.isFile()) {
|
|
698
|
+
await rm(destination, { recursive: true, force: true });
|
|
699
|
+
await copyFile(source, destination);
|
|
700
|
+
mergedHistorySourceRealpaths.add(sourceRealpath);
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
683
703
|
const existing = await readFile(destination, "utf-8").catch(() => "");
|
|
684
704
|
const addition = await readFile(source, "utf-8");
|
|
685
705
|
const separator = existing === "" || existing.endsWith("\n") || addition === "" ? "" : "\n";
|
|
686
706
|
await writeFile(destination, `${existing}${separator}${addition}`, "utf-8");
|
|
707
|
+
mergedHistorySourceRealpaths.add(sourceRealpath);
|
|
687
708
|
continue;
|
|
688
709
|
}
|
|
689
710
|
await copyFile(source, destination);
|
|
711
|
+
mergedHistorySourceRealpaths.add(sourceRealpath);
|
|
690
712
|
}
|
|
691
713
|
}
|
|
692
714
|
export async function persistProjectLaunchRuntimeAuthState(runtimeCodexHome, projectCodexHome) {
|
|
@@ -730,9 +752,15 @@ export async function prepareRuntimeCodexHomeForProjectLaunch(cwd, sessionId, pr
|
|
|
730
752
|
}
|
|
731
753
|
await ensureProjectLaunchRuntimeHistoryLinks(runtimeCodexHome, projectCodexHome);
|
|
732
754
|
if (options.includeHistoryArtifacts === true && (options.extraHistoryCodexHomes?.length ?? 0) > 0) {
|
|
755
|
+
const mergedHistorySourceRealpaths = new Set();
|
|
756
|
+
for (const entryName of PROJECT_LAUNCH_DURABLE_HISTORY_ENTRY_NAMES) {
|
|
757
|
+
const source = join(projectCodexHome, entryName);
|
|
758
|
+
if (existsSync(source))
|
|
759
|
+
mergedHistorySourceRealpaths.add(realpathSync(source));
|
|
760
|
+
}
|
|
733
761
|
await materializeProjectLaunchRuntimeHistoryEntries(runtimeCodexHome, projectCodexHome);
|
|
734
762
|
for (const extraCodexHome of options.extraHistoryCodexHomes ?? []) {
|
|
735
|
-
await mergeProjectLaunchRuntimeHistoryEntries(runtimeCodexHome, extraCodexHome);
|
|
763
|
+
await mergeProjectLaunchRuntimeHistoryEntries(runtimeCodexHome, extraCodexHome, mergedHistorySourceRealpaths);
|
|
736
764
|
}
|
|
737
765
|
}
|
|
738
766
|
return runtimeCodexHome;
|
|
@@ -793,13 +821,46 @@ export function parseResumeCodexHomeSelection(args) {
|
|
|
793
821
|
projectOnly,
|
|
794
822
|
};
|
|
795
823
|
}
|
|
824
|
+
export async function preflightResumeOmxPluginState(codexHomeDir, pkgRoot = getPackageRoot()) {
|
|
825
|
+
const selectedCodexHomeDir = codexHomeDir && codexHomeDir.trim() !== ""
|
|
826
|
+
? codexHomeDir
|
|
827
|
+
: join(homedir(), ".codex");
|
|
828
|
+
const packagedMarketplace = await resolvePackagedOmxMarketplace(pkgRoot);
|
|
829
|
+
if (!packagedMarketplace) {
|
|
830
|
+
return { status: "unavailable", prunedStaleDirs: [], configUpdated: false };
|
|
831
|
+
}
|
|
832
|
+
const materialized = await materializePackagedOmxPluginCache(selectedCodexHomeDir, packagedMarketplace);
|
|
833
|
+
const version = materialized.version ?? (await packagedOmxPluginVersion(packagedMarketplace)) ?? undefined;
|
|
834
|
+
const currentCacheDir = materialized.cacheDir ?? (version ? join(selectedCodexHomeDir, "plugins", "cache", "oh-my-codex-local", "oh-my-codex", version) : undefined);
|
|
835
|
+
const prunedStaleDirs = [];
|
|
836
|
+
const configPath = join(selectedCodexHomeDir, "config.toml");
|
|
837
|
+
const existingConfig = existsSync(configPath) ? await readFile(configPath, "utf-8") : "";
|
|
838
|
+
const nextConfig = upsertLocalOmxMarketplaceRegistration(upsertLocalOmxPluginEnablement(existingConfig), pkgRoot);
|
|
839
|
+
const configUpdated = nextConfig !== existingConfig;
|
|
840
|
+
if (configUpdated) {
|
|
841
|
+
await mkdir(dirname(configPath), { recursive: true });
|
|
842
|
+
await writeFile(configPath, nextConfig, "utf-8");
|
|
843
|
+
}
|
|
844
|
+
return {
|
|
845
|
+
status: "prepared",
|
|
846
|
+
version,
|
|
847
|
+
cacheDir: currentCacheDir,
|
|
848
|
+
prunedStaleDirs,
|
|
849
|
+
configUpdated,
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
function isResumeCodexLaunch(args) {
|
|
853
|
+
return args.includes("resume");
|
|
854
|
+
}
|
|
796
855
|
async function prepareResumeCodexHomeForLaunch(cwd, sessionId, args, env = process.env) {
|
|
797
856
|
const selection = parseResumeCodexHomeSelection(args);
|
|
798
857
|
if (selection.explicitCodexHome) {
|
|
858
|
+
const codexHomeOverride = resolve(selection.explicitCodexHome);
|
|
859
|
+
await preflightResumeOmxPluginState(codexHomeOverride);
|
|
799
860
|
return {
|
|
800
861
|
args: selection.args,
|
|
801
862
|
prepared: {
|
|
802
|
-
codexHomeOverride
|
|
863
|
+
codexHomeOverride,
|
|
803
864
|
},
|
|
804
865
|
};
|
|
805
866
|
}
|
|
@@ -809,6 +870,7 @@ async function prepareResumeCodexHomeForLaunch(cwd, sessionId, args, env = proce
|
|
|
809
870
|
const emptyRuntimeCodexHome = runtimeCodexHomePath(cwd, sessionId);
|
|
810
871
|
await rm(emptyRuntimeCodexHome, { recursive: true, force: true });
|
|
811
872
|
await mkdir(join(emptyRuntimeCodexHome, "sessions"), { recursive: true });
|
|
873
|
+
await preflightResumeOmxPluginState(emptyRuntimeCodexHome);
|
|
812
874
|
return {
|
|
813
875
|
args: selection.args,
|
|
814
876
|
prepared: {
|
|
@@ -821,6 +883,7 @@ async function prepareResumeCodexHomeForLaunch(cwd, sessionId, args, env = proce
|
|
|
821
883
|
includeHistoryArtifacts: true,
|
|
822
884
|
extraHistoryCodexHomes: projectHomes.slice(1).map((home) => home.path),
|
|
823
885
|
});
|
|
886
|
+
await preflightResumeOmxPluginState(runtimeCodexHome);
|
|
824
887
|
return {
|
|
825
888
|
args: selection.args,
|
|
826
889
|
prepared: {
|
|
@@ -832,6 +895,7 @@ async function prepareResumeCodexHomeForLaunch(cwd, sessionId, args, env = proce
|
|
|
832
895
|
includeHistoryArtifacts: true,
|
|
833
896
|
extraHistoryCodexHomes: projectHomes.map((home) => home.path),
|
|
834
897
|
});
|
|
898
|
+
await preflightResumeOmxPluginState(prepared.codexHomeOverride);
|
|
835
899
|
return { args: selection.args, prepared };
|
|
836
900
|
}
|
|
837
901
|
export async function persistProjectLaunchRuntimeProjectTrustState(runtimeCodexHome, projectCodexHome) {
|
|
@@ -1362,20 +1426,88 @@ export function resolveDisposableWorktreeOmxRootForLaunch(ensuredWorktree, env =
|
|
|
1362
1426
|
return undefined;
|
|
1363
1427
|
return ensuredWorktree.repoRoot;
|
|
1364
1428
|
}
|
|
1429
|
+
function buildMadmaxWorktreeRuntimeEnvOverlay(runtimeContext) {
|
|
1430
|
+
if (!runtimeContext)
|
|
1431
|
+
return {};
|
|
1432
|
+
return {
|
|
1433
|
+
OMX_ROOT: runtimeContext.omxRoot,
|
|
1434
|
+
...(runtimeContext.omxStateRoot ? { OMX_STATE_ROOT: runtimeContext.omxStateRoot } : {}),
|
|
1435
|
+
...(runtimeContext.boxedActive ? { OMXBOX_ACTIVE: "1" } : {}),
|
|
1436
|
+
OMX_SOURCE_CWD: runtimeContext.sourceCwd,
|
|
1437
|
+
...(runtimeContext.madmaxDetachedContext
|
|
1438
|
+
? { [OMX_MADMAX_DETACHED_CONTEXT_ENV]: runtimeContext.madmaxDetachedContext }
|
|
1439
|
+
: {}),
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1442
|
+
export function captureMadmaxWorktreeRuntimeContext(options) {
|
|
1443
|
+
const env = options.env ?? process.env;
|
|
1444
|
+
if (!options.worktreeEnabled)
|
|
1445
|
+
return undefined;
|
|
1446
|
+
if (!launchArgsRequestMadmaxIsolation(options.originalLaunchArgs))
|
|
1447
|
+
return undefined;
|
|
1448
|
+
if (env.OMXBOX_ACTIVE !== "1")
|
|
1449
|
+
return undefined;
|
|
1450
|
+
const inheritedRoot = resolveInheritedMadmaxRoot(env);
|
|
1451
|
+
if (!inheritedRoot)
|
|
1452
|
+
return undefined;
|
|
1453
|
+
const sourceCwd = env.OMX_SOURCE_CWD?.trim() || options.sourceCwd;
|
|
1454
|
+
const worktreeCwd = options.worktreeCwd?.trim();
|
|
1455
|
+
const omxStateRoot = env.OMX_STATE_ROOT?.trim();
|
|
1456
|
+
const madmaxDetachedContext = env[OMX_MADMAX_DETACHED_CONTEXT_ENV]?.trim();
|
|
1457
|
+
return {
|
|
1458
|
+
omxRoot: resolveLaunchPath(options.sourceCwd, inheritedRoot),
|
|
1459
|
+
...(omxStateRoot ? { omxStateRoot: resolveLaunchPath(options.sourceCwd, omxStateRoot) } : {}),
|
|
1460
|
+
sourceCwd,
|
|
1461
|
+
...(worktreeCwd && worktreeCwd !== sourceCwd ? { worktreeCwd } : {}),
|
|
1462
|
+
...(madmaxDetachedContext ? { madmaxDetachedContext } : {}),
|
|
1463
|
+
boxedActive: true,
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1365
1466
|
function applyDisposableWorktreeOmxRootForLaunch(ensuredWorktree, env = process.env) {
|
|
1366
1467
|
const omxRootOverride = resolveDisposableWorktreeOmxRootForLaunch(ensuredWorktree, env);
|
|
1367
1468
|
if (!omxRootOverride)
|
|
1368
1469
|
return;
|
|
1369
1470
|
env.OMX_ROOT = omxRootOverride;
|
|
1370
1471
|
}
|
|
1371
|
-
|
|
1472
|
+
function launchArgRequestsDisposableWorktree(arg) {
|
|
1473
|
+
return arg === "--worktree" ||
|
|
1474
|
+
arg === "-w" ||
|
|
1475
|
+
arg.startsWith("--worktree=") ||
|
|
1476
|
+
// Covers both `-w=<name>` and `-w<name>`; an explicit `-w=` check would be a
|
|
1477
|
+
// strict subset of this clause, so it is omitted as redundant.
|
|
1478
|
+
(arg.startsWith("-w") && arg.length > 2);
|
|
1479
|
+
}
|
|
1480
|
+
function launchArgsRequestMadmaxIsolation(launchArgs) {
|
|
1481
|
+
return launchArgs.some((arg) => arg === MADMAX_FLAG || arg === MADMAX_SPARK_FLAG);
|
|
1482
|
+
}
|
|
1483
|
+
function launchArgsRequestDisposableWorktree(launchArgs) {
|
|
1484
|
+
return launchArgs.some((arg) => launchArgRequestsDisposableWorktree(arg));
|
|
1485
|
+
}
|
|
1486
|
+
function clearInheritedMadmaxRootForDisposableWorktreeLaunch(launchArgs, env = process.env) {
|
|
1487
|
+
if (!launchArgsRequestDisposableWorktree(launchArgs))
|
|
1488
|
+
return;
|
|
1489
|
+
if (env.OMXBOX_ACTIVE !== "1")
|
|
1490
|
+
return;
|
|
1491
|
+
delete env.OMX_ROOT;
|
|
1492
|
+
delete env.OMX_STATE_ROOT;
|
|
1493
|
+
delete env.OMXBOX_ACTIVE;
|
|
1494
|
+
delete env.OMX_SOURCE_CWD;
|
|
1495
|
+
delete env[OMX_MADMAX_DETACHED_CONTEXT_ENV];
|
|
1496
|
+
}
|
|
1497
|
+
export function shouldAutoIsolateMadmaxLaunch(command, launchArgs, env = process.env, cwd = process.cwd()) {
|
|
1372
1498
|
if (command !== "launch" && command !== "exec")
|
|
1373
1499
|
return false;
|
|
1374
|
-
if (env.OMX_NO_BOX === "1"
|
|
1500
|
+
if (env.OMX_NO_BOX === "1")
|
|
1375
1501
|
return false;
|
|
1376
|
-
if (
|
|
1502
|
+
if (!launchArgsRequestMadmaxIsolation(launchArgs))
|
|
1377
1503
|
return false;
|
|
1378
|
-
|
|
1504
|
+
const inheritedContext = env[OMX_MADMAX_DETACHED_CONTEXT_ENV]?.trim();
|
|
1505
|
+
if (env.OMXBOX_ACTIVE === "1" && inheritedContext && !resolveInheritedMadmaxRoot(env)) {
|
|
1506
|
+
return false;
|
|
1507
|
+
}
|
|
1508
|
+
if (madmaxInheritedContextMatchesLaunch(cwd, launchArgs, env))
|
|
1509
|
+
return false;
|
|
1510
|
+
return true;
|
|
1379
1511
|
}
|
|
1380
1512
|
function sanitizeRunIdSegment(value) {
|
|
1381
1513
|
return value.replace(/[^a-zA-Z0-9._-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
@@ -1474,6 +1606,7 @@ function readMadmaxDetachedActiveRecord(recordPath) {
|
|
|
1474
1606
|
tmux_session_name: parsed.tmux_session_name,
|
|
1475
1607
|
...(typeof parsed.session_id === "string" ? { session_id: parsed.session_id } : {}),
|
|
1476
1608
|
...(typeof parsed.tmux_pane_id === "string" ? { tmux_pane_id: parsed.tmux_pane_id } : {}),
|
|
1609
|
+
...(typeof parsed.worktree_cwd === "string" ? { worktree_cwd: parsed.worktree_cwd } : {}),
|
|
1477
1610
|
};
|
|
1478
1611
|
}
|
|
1479
1612
|
catch {
|
|
@@ -1607,6 +1740,43 @@ export function withMadmaxDetachedContextLock(runsRoot, contextKey, run, options
|
|
|
1607
1740
|
}
|
|
1608
1741
|
throw new MadmaxDetachedGuardError(`timed out waiting for madmax detached launch context lock: ${lockPath} (${lastDiagnostic})`);
|
|
1609
1742
|
}
|
|
1743
|
+
function readMadmaxRunMetadata(runRoot) {
|
|
1744
|
+
try {
|
|
1745
|
+
const parsed = JSON.parse(readFileSync(join(runRoot, ".omxbox-run.json"), "utf-8"));
|
|
1746
|
+
return {
|
|
1747
|
+
...(typeof parsed.cwd === "string" ? { cwd: parsed.cwd } : {}),
|
|
1748
|
+
...(typeof parsed.detached_launch_context === "string"
|
|
1749
|
+
? { detached_launch_context: parsed.detached_launch_context }
|
|
1750
|
+
: {}),
|
|
1751
|
+
};
|
|
1752
|
+
}
|
|
1753
|
+
catch {
|
|
1754
|
+
return null;
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
function resolveInheritedMadmaxRoot(env) {
|
|
1758
|
+
const root = env.OMX_ROOT?.trim() || env.OMX_STATE_ROOT?.trim();
|
|
1759
|
+
return root || undefined;
|
|
1760
|
+
}
|
|
1761
|
+
function madmaxInheritedContextMatchesLaunch(cwd, launchArgs, env) {
|
|
1762
|
+
if (env.OMXBOX_ACTIVE !== "1")
|
|
1763
|
+
return false;
|
|
1764
|
+
const context = env[OMX_MADMAX_DETACHED_CONTEXT_ENV]?.trim();
|
|
1765
|
+
if (!context)
|
|
1766
|
+
return false;
|
|
1767
|
+
const inheritedRoot = resolveInheritedMadmaxRoot(env);
|
|
1768
|
+
if (!inheritedRoot)
|
|
1769
|
+
return false;
|
|
1770
|
+
const metadata = readMadmaxRunMetadata(inheritedRoot);
|
|
1771
|
+
if (!metadata)
|
|
1772
|
+
return false;
|
|
1773
|
+
if (metadata.cwd && metadata.cwd !== inheritedRoot)
|
|
1774
|
+
return false;
|
|
1775
|
+
if (metadata.detached_launch_context !== context)
|
|
1776
|
+
return false;
|
|
1777
|
+
const expectedContext = buildMadmaxDetachedLaunchContextKey(cwd, [...launchArgs], inheritedRoot);
|
|
1778
|
+
return expectedContext === context;
|
|
1779
|
+
}
|
|
1610
1780
|
function isMadmaxDetachedGuardEnabled(env) {
|
|
1611
1781
|
return env.OMXBOX_ACTIVE === "1" && typeof env[OMX_MADMAX_DETACHED_CONTEXT_ENV] === "string";
|
|
1612
1782
|
}
|
|
@@ -1651,7 +1821,7 @@ export function createMadmaxIsolatedRoot(sourceCwd, argv, env = process.env) {
|
|
|
1651
1821
|
return runDir;
|
|
1652
1822
|
}
|
|
1653
1823
|
function activateMadmaxIsolationIfNeeded(command, launchArgs, cwd, env = process.env) {
|
|
1654
|
-
if (!shouldAutoIsolateMadmaxLaunch(command, launchArgs, env))
|
|
1824
|
+
if (!shouldAutoIsolateMadmaxLaunch(command, launchArgs, env, cwd))
|
|
1655
1825
|
return;
|
|
1656
1826
|
const runDir = createMadmaxIsolatedRoot(cwd, launchArgs, env);
|
|
1657
1827
|
env.OMX_ROOT = runDir;
|
|
@@ -1663,6 +1833,7 @@ export async function main(args) {
|
|
|
1663
1833
|
const knownCommands = new Set([
|
|
1664
1834
|
"launch",
|
|
1665
1835
|
"exec",
|
|
1836
|
+
"mission",
|
|
1666
1837
|
"imagegen",
|
|
1667
1838
|
"setup",
|
|
1668
1839
|
"update",
|
|
@@ -1804,6 +1975,18 @@ export async function main(args) {
|
|
|
1804
1975
|
await execWithOverlay(launchArgs);
|
|
1805
1976
|
}
|
|
1806
1977
|
break;
|
|
1978
|
+
case "mission":
|
|
1979
|
+
await missionCommand(args.slice(1), {
|
|
1980
|
+
runTask: async (prompt, codexArgs) => {
|
|
1981
|
+
const priorExitCode = process.exitCode;
|
|
1982
|
+
process.exitCode = undefined;
|
|
1983
|
+
await execWithOverlay([...codexArgs, prompt]);
|
|
1984
|
+
const exitCode = typeof process.exitCode === "number" ? process.exitCode : 0;
|
|
1985
|
+
process.exitCode = priorExitCode;
|
|
1986
|
+
return exitCode;
|
|
1987
|
+
},
|
|
1988
|
+
});
|
|
1989
|
+
break;
|
|
1807
1990
|
case "imagegen":
|
|
1808
1991
|
await imagegenCommand(args.slice(1));
|
|
1809
1992
|
break;
|
|
@@ -1926,6 +2109,11 @@ async function readStaleCurrentAutopilotStatus(cwd) {
|
|
|
1926
2109
|
return null;
|
|
1927
2110
|
return { phase: phase ?? "active" };
|
|
1928
2111
|
}
|
|
2112
|
+
function formatDurableUltragoalStatusForCli(status) {
|
|
2113
|
+
return status === "failed"
|
|
2114
|
+
? "ultragoal: FAILED (phase: failed)"
|
|
2115
|
+
: `ultragoal: ACTIVE (phase: ${status})`;
|
|
2116
|
+
}
|
|
1929
2117
|
async function showStatus() {
|
|
1930
2118
|
const { readFile } = await import("fs/promises");
|
|
1931
2119
|
const cwd = process.cwd();
|
|
@@ -1962,7 +2150,7 @@ async function showStatus() {
|
|
|
1962
2150
|
const ultragoalState = await readUltragoalState(cwd).catch(() => null);
|
|
1963
2151
|
if (states.length === 0) {
|
|
1964
2152
|
if (ultragoalState?.active) {
|
|
1965
|
-
console.log(
|
|
2153
|
+
console.log(formatDurableUltragoalStatusForCli(ultragoalState.status ?? "active"));
|
|
1966
2154
|
return;
|
|
1967
2155
|
}
|
|
1968
2156
|
const staleAutopilot = await readStaleCurrentAutopilotStatus(cwd);
|
|
@@ -1973,6 +2161,7 @@ async function showStatus() {
|
|
|
1973
2161
|
console.log("No active modes.");
|
|
1974
2162
|
return;
|
|
1975
2163
|
}
|
|
2164
|
+
let hasAuthoritativeActiveUltragoalMode = false;
|
|
1976
2165
|
for (const path of states) {
|
|
1977
2166
|
const content = await readFile(path, "utf-8");
|
|
1978
2167
|
let state;
|
|
@@ -1985,12 +2174,15 @@ async function showStatus() {
|
|
|
1985
2174
|
}
|
|
1986
2175
|
const file = basename(path);
|
|
1987
2176
|
const mode = file.replace("-state.json", "");
|
|
1988
|
-
if (mode === "ultragoal" &&
|
|
2177
|
+
if (mode === "ultragoal" && state.active === true) {
|
|
2178
|
+
hasAuthoritativeActiveUltragoalMode = true;
|
|
2179
|
+
}
|
|
2180
|
+
if (mode === "ultragoal" && ultragoalState?.active && state.active !== true)
|
|
1989
2181
|
continue;
|
|
1990
2182
|
console.log(`${mode}: ${state.active === true ? "ACTIVE" : "inactive"} (phase: ${String(state.current_phase || "n/a")})`);
|
|
1991
2183
|
}
|
|
1992
|
-
if (ultragoalState?.active) {
|
|
1993
|
-
console.log(
|
|
2184
|
+
if (ultragoalState?.active && !hasAuthoritativeActiveUltragoalMode) {
|
|
2185
|
+
console.log(formatDurableUltragoalStatusForCli(ultragoalState.status ?? "active"));
|
|
1994
2186
|
}
|
|
1995
2187
|
if (!hasAuthoritativeActiveMode && !ultragoalState?.active) {
|
|
1996
2188
|
const staleAutopilot = await readStaleCurrentAutopilotStatus(cwd);
|
|
@@ -2066,6 +2258,7 @@ export async function launchWithAuthHotswap(args) {
|
|
|
2066
2258
|
}
|
|
2067
2259
|
}
|
|
2068
2260
|
}
|
|
2261
|
+
clearInheritedMadmaxRootForDisposableWorktreeLaunch(parsedWorktree.remainingArgs);
|
|
2069
2262
|
applyDisposableWorktreeOmxRootForLaunch(ensuredLaunchWorktree);
|
|
2070
2263
|
try {
|
|
2071
2264
|
await maybeCheckAndPromptUpdate(cwd);
|
|
@@ -2165,6 +2358,14 @@ export async function launchWithHud(args) {
|
|
|
2165
2358
|
}
|
|
2166
2359
|
}
|
|
2167
2360
|
}
|
|
2361
|
+
const madmaxWorktreeRuntimeContext = captureMadmaxWorktreeRuntimeContext({
|
|
2362
|
+
originalLaunchArgs: args,
|
|
2363
|
+
worktreeEnabled: Boolean(parsedWorktree.mode.enabled && ensuredLaunchWorktree?.enabled),
|
|
2364
|
+
sourceCwd: launchCwd,
|
|
2365
|
+
worktreeCwd: ensuredLaunchWorktree?.enabled ? ensuredLaunchWorktree.worktreePath : undefined,
|
|
2366
|
+
env: process.env,
|
|
2367
|
+
});
|
|
2368
|
+
clearInheritedMadmaxRootForDisposableWorktreeLaunch(parsedWorktree.remainingArgs);
|
|
2168
2369
|
applyDisposableWorktreeOmxRootForLaunch(ensuredLaunchWorktree);
|
|
2169
2370
|
const sessionId = `omx-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
2170
2371
|
try {
|
|
@@ -2195,14 +2396,14 @@ export async function launchWithHud(args) {
|
|
|
2195
2396
|
catch {
|
|
2196
2397
|
// Non-fatal: repair failure must not block launch
|
|
2197
2398
|
}
|
|
2198
|
-
const resumePrepared = normalizedArgs
|
|
2399
|
+
const resumePrepared = isResumeCodexLaunch(normalizedArgs)
|
|
2199
2400
|
? await prepareResumeCodexHomeForLaunch(launchCwd, sessionId, normalizedArgs, process.env)
|
|
2200
2401
|
: null;
|
|
2201
2402
|
if (resumePrepared) {
|
|
2202
2403
|
normalizedArgs = resumePrepared.args;
|
|
2203
2404
|
}
|
|
2204
2405
|
const preparedCodexHome = resumePrepared?.prepared ?? await prepareCodexHomeForLaunch(launchCwd, sessionId, process.env, {
|
|
2205
|
-
includeHistoryArtifacts: normalizedArgs
|
|
2406
|
+
includeHistoryArtifacts: isResumeCodexLaunch(normalizedArgs),
|
|
2206
2407
|
});
|
|
2207
2408
|
const codexHomeOverride = preparedCodexHome.codexHomeOverride;
|
|
2208
2409
|
const sqliteHomeOverride = preparedCodexHome.sqliteHomeOverride;
|
|
@@ -2221,7 +2422,7 @@ export async function launchWithHud(args) {
|
|
|
2221
2422
|
const notifyTempContractRaw = notifyTempResult.contract.active
|
|
2222
2423
|
? serializeNotifyTempContract(notifyTempResult.contract)
|
|
2223
2424
|
: null;
|
|
2224
|
-
const launchResult = runCodex(cwd, normalizedArgs, sessionId, workerSparkModel, codexHomeOverride, sqliteHomeOverride, notifyTempContractRaw, effectiveExplicitLaunchPolicy, projectLocalCodexHomeForCleanup, preparedCodexHome.runtimeCodexHomeForCleanup);
|
|
2425
|
+
const launchResult = runCodex(cwd, normalizedArgs, sessionId, workerSparkModel, codexHomeOverride, sqliteHomeOverride, notifyTempContractRaw, effectiveExplicitLaunchPolicy, projectLocalCodexHomeForCleanup, preparedCodexHome.runtimeCodexHomeForCleanup, madmaxWorktreeRuntimeContext);
|
|
2225
2426
|
postLaunchHandledExternally = launchResult.postLaunchHandledExternally;
|
|
2226
2427
|
}
|
|
2227
2428
|
finally {
|
|
@@ -2264,6 +2465,7 @@ export async function execWithOverlay(args) {
|
|
|
2264
2465
|
}
|
|
2265
2466
|
}
|
|
2266
2467
|
}
|
|
2468
|
+
clearInheritedMadmaxRootForDisposableWorktreeLaunch(parsedWorktree.remainingArgs);
|
|
2267
2469
|
applyDisposableWorktreeOmxRootForLaunch(ensuredLaunchWorktree);
|
|
2268
2470
|
const sessionId = `omx-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
2269
2471
|
try {
|
|
@@ -2982,7 +3184,7 @@ export function withTmuxExtendedKeys(cwd, run, execFileSyncImpl = (file, tmuxArg
|
|
|
2982
3184
|
releaseTmuxExtendedKeysLease(cwd, leaseHandle, execFileSyncImpl);
|
|
2983
3185
|
}
|
|
2984
3186
|
}
|
|
2985
|
-
export function buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw, nativeWindows = false, sessionId, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, omxRootOverride, env = process.env, sqliteHomeOverride, parentEnvFilePath) {
|
|
3187
|
+
export function buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw, nativeWindows = false, sessionId, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, omxRootOverride, env = process.env, sqliteHomeOverride, parentEnvFilePath, inheritedWorkerModel) {
|
|
2986
3188
|
const detachedLeaderCmd = nativeWindows
|
|
2987
3189
|
? "powershell.exe"
|
|
2988
3190
|
: buildDetachedSessionLeaderCommand(cwd, sessionName, codexCmd, sessionId, codexHomeOverride, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, parentEnvFilePath);
|
|
@@ -3013,17 +3215,19 @@ export function buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, h
|
|
|
3013
3215
|
sessionName,
|
|
3014
3216
|
"-c",
|
|
3015
3217
|
cwd,
|
|
3016
|
-
...(workerLaunchArgs
|
|
3017
|
-
? ["-e", `${TEAM_WORKER_LAUNCH_ARGS_ENV}=${workerLaunchArgs}`]
|
|
3018
|
-
: []),
|
|
3218
|
+
...(workerLaunchArgs ? ["-e", `${TEAM_WORKER_LAUNCH_ARGS_ENV}=${workerLaunchArgs}`] : []),
|
|
3019
3219
|
...Object.entries(hudRuntimeEnv).map(([key, value]) => ["-e", `${key}=${value}`]).flat(),
|
|
3020
3220
|
...(codexHomeOverride ? ["-e", `CODEX_HOME=${codexHomeOverride}`] : []),
|
|
3021
3221
|
...(sqliteHomeOverride ? ["-e", `${CODEX_SQLITE_HOME_ENV}=${sqliteHomeOverride}`] : []),
|
|
3022
3222
|
...(env.OMXBOX_ACTIVE ? ["-e", `OMXBOX_ACTIVE=${env.OMXBOX_ACTIVE}`] : []),
|
|
3023
3223
|
...(env.OMX_SOURCE_CWD ? ["-e", `OMX_SOURCE_CWD=${env.OMX_SOURCE_CWD}`] : []),
|
|
3224
|
+
...(env[OMX_MADMAX_DETACHED_CONTEXT_ENV]
|
|
3225
|
+
? ["-e", `${OMX_MADMAX_DETACHED_CONTEXT_ENV}=${env[OMX_MADMAX_DETACHED_CONTEXT_ENV]}`]
|
|
3226
|
+
: []),
|
|
3024
3227
|
...(notifyTempContractRaw
|
|
3025
3228
|
? ["-e", `${OMX_NOTIFY_TEMP_CONTRACT_ENV}=${notifyTempContractRaw}`]
|
|
3026
3229
|
: []),
|
|
3230
|
+
...(inheritedWorkerModel ? ["-e", `${TEAM_WORKER_INHERITED_MODEL_ENV}=${inheritedWorkerModel}`] : []),
|
|
3027
3231
|
detachedLeaderCmd,
|
|
3028
3232
|
];
|
|
3029
3233
|
const splitCaptureArgs = [
|
|
@@ -3606,42 +3810,59 @@ ${launchAppendix}${dirtyWorktreeGuidance}`
|
|
|
3606
3810
|
* runCodex: Launch Codex CLI (blocks until exit).
|
|
3607
3811
|
* All 3 paths (new tmux, existing tmux, no tmux) block via execSync/execFileSync.
|
|
3608
3812
|
*/
|
|
3609
|
-
function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, sqliteHomeOverride, notifyTempContractRaw, explicitLaunchPolicy, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup) {
|
|
3813
|
+
function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, sqliteHomeOverride, notifyTempContractRaw, explicitLaunchPolicy, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, runtimeContext) {
|
|
3610
3814
|
const launchArgs = injectModelInstructionsBypassArgs(cwd, args, process.env, sessionModelInstructionsPath(cwd, sessionId));
|
|
3611
3815
|
const nativeWindows = isNativeWindows();
|
|
3612
3816
|
const omxBin = resolveOmxCliEntryPath({ argv1: process.argv[1], cwd, env: process.env });
|
|
3613
3817
|
if (!omxBin) {
|
|
3614
3818
|
throw new Error("Unable to resolve OMX launcher path for tmux HUD bootstrap");
|
|
3615
3819
|
}
|
|
3616
|
-
const
|
|
3820
|
+
const runtimeEnvOverlay = buildMadmaxWorktreeRuntimeEnvOverlay(runtimeContext);
|
|
3821
|
+
const omxRootOverride = runtimeContext?.omxRoot ?? resolveOmxRootForLaunch(cwd, process.env);
|
|
3617
3822
|
const currentPaneId = process.env.TMUX_PANE;
|
|
3618
|
-
const hudRuntimeRoot =
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
...
|
|
3623
|
-
|
|
3823
|
+
const hudRuntimeRoot = runtimeContext
|
|
3824
|
+
? { omxRoot: runtimeContext.omxRoot, rootSource: 'omx-root-env' }
|
|
3825
|
+
: resolveHudRuntimeRootForLaunch(cwd, process.env);
|
|
3826
|
+
const hudRuntimeEnv = {
|
|
3827
|
+
...buildHudRuntimeEnv({
|
|
3828
|
+
sessionId,
|
|
3829
|
+
leaderPaneId: currentPaneId,
|
|
3830
|
+
...hudRuntimeRoot,
|
|
3831
|
+
}).env,
|
|
3832
|
+
...runtimeEnvOverlay,
|
|
3833
|
+
};
|
|
3834
|
+
const hudEnvArgs = Object.entries(hudRuntimeEnv).map(([key, value]) => `${key}=${value}`);
|
|
3624
3835
|
const hudCmd = nativeWindows
|
|
3625
3836
|
? buildWindowsPromptCommand("node", [omxBin, "hud", "--watch"])
|
|
3626
3837
|
: buildTmuxPaneCommand("env", [...hudEnvArgs, "node", omxBin, "hud", "--watch"]);
|
|
3627
3838
|
const inheritLeaderFlags = process.env[TEAM_INHERIT_LEADER_FLAGS_ENV] !== "0";
|
|
3839
|
+
const inheritedWorkerLaunchArgs = inheritLeaderFlags
|
|
3840
|
+
? collectInheritableTeamWorkerArgsShared(launchArgs)
|
|
3841
|
+
: [];
|
|
3842
|
+
const inheritedWorkerModel = parseTeamWorkerLaunchArgs(inheritedWorkerLaunchArgs).modelOverride ?? undefined;
|
|
3628
3843
|
const workerLaunchArgs = resolveTeamWorkerLaunchArgsEnv(process.env[TEAM_WORKER_LAUNCH_ARGS_ENV], launchArgs, inheritLeaderFlags, workerDefaultModel);
|
|
3629
3844
|
const codexBaseEnv = prependOmxRuntimeCommandShimToEnv(cwd, {
|
|
3630
3845
|
...stripHermesMcpBridgeEnv(process.env),
|
|
3631
3846
|
...(codexHomeOverride ? { CODEX_HOME: codexHomeOverride } : {}),
|
|
3632
3847
|
...(sqliteHomeOverride ? { [CODEX_SQLITE_HOME_ENV]: sqliteHomeOverride } : {}),
|
|
3633
3848
|
...(omxRootOverride ? { OMX_ROOT: omxRootOverride } : {}),
|
|
3849
|
+
...runtimeEnvOverlay,
|
|
3634
3850
|
}, omxBin);
|
|
3635
3851
|
const codexEnvWithSession = {
|
|
3636
3852
|
...codexBaseEnv,
|
|
3637
3853
|
...buildHudRuntimeEnv({ sessionId }).env,
|
|
3638
3854
|
};
|
|
3639
3855
|
const codexEnv = workerLaunchArgs
|
|
3640
|
-
? {
|
|
3856
|
+
? {
|
|
3857
|
+
...codexEnvWithSession,
|
|
3858
|
+
[TEAM_WORKER_LAUNCH_ARGS_ENV]: workerLaunchArgs,
|
|
3859
|
+
...(inheritedWorkerModel ? { [TEAM_WORKER_INHERITED_MODEL_ENV]: inheritedWorkerModel } : {}),
|
|
3860
|
+
}
|
|
3641
3861
|
: codexEnvWithSession;
|
|
3642
3862
|
const codexEnvWithNotify = notifyTempContractRaw
|
|
3643
3863
|
? { ...codexEnv, [OMX_NOTIFY_TEMP_CONTRACT_ENV]: notifyTempContractRaw }
|
|
3644
3864
|
: codexEnv;
|
|
3865
|
+
const runtimeHookEnv = { ...process.env, ...runtimeEnvOverlay };
|
|
3645
3866
|
const { launchPolicy } = resolveTmuxAwareLaunchPolicy(explicitLaunchPolicy, nativeWindows);
|
|
3646
3867
|
if (isCodexVersionRequest(launchArgs)) {
|
|
3647
3868
|
runCodexBlocking(cwd, launchArgs, codexEnvWithNotify);
|
|
@@ -3679,6 +3900,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, s
|
|
|
3679
3900
|
cwd,
|
|
3680
3901
|
sessionId,
|
|
3681
3902
|
omxRootOverride,
|
|
3903
|
+
baseEnv: runtimeHookEnv,
|
|
3682
3904
|
});
|
|
3683
3905
|
}
|
|
3684
3906
|
catch (err) {
|
|
@@ -3705,6 +3927,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, s
|
|
|
3705
3927
|
cwd,
|
|
3706
3928
|
sessionId,
|
|
3707
3929
|
omxRootOverride,
|
|
3930
|
+
baseEnv: runtimeHookEnv,
|
|
3708
3931
|
});
|
|
3709
3932
|
}
|
|
3710
3933
|
catch (err) {
|
|
@@ -3771,7 +3994,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, s
|
|
|
3771
3994
|
: null;
|
|
3772
3995
|
const sessionName = buildDetachedTmuxSessionName(cwd, sessionId);
|
|
3773
3996
|
const launchDetachedSession = () => {
|
|
3774
|
-
const contextKey = process.env[OMX_MADMAX_DETACHED_CONTEXT_ENV]?.trim();
|
|
3997
|
+
const contextKey = runtimeContext?.madmaxDetachedContext ?? process.env[OMX_MADMAX_DETACHED_CONTEXT_ENV]?.trim();
|
|
3775
3998
|
const runsRoot = resolveMadmaxRunsRoot(process.env);
|
|
3776
3999
|
const activeRecordPath = contextKey
|
|
3777
4000
|
? madmaxDetachedActiveRecordPath(runsRoot, contextKey)
|
|
@@ -3836,7 +4059,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, s
|
|
|
3836
4059
|
if (!nativeWindows) {
|
|
3837
4060
|
detachedParentEnvFilePath = writeDetachedSessionParentEnvFile(cwd, sessionId, codexEnvWithNotify);
|
|
3838
4061
|
}
|
|
3839
|
-
const bootstrapSteps = buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw, nativeWindows, sessionId, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, omxRootOverride,
|
|
4062
|
+
const bootstrapSteps = buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw, nativeWindows, sessionId, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, omxRootOverride, runtimeHookEnv, sqliteHomeOverride, detachedParentEnvFilePath, inheritedWorkerModel);
|
|
3840
4063
|
for (const step of bootstrapSteps) {
|
|
3841
4064
|
const output = execTmuxFileSync(step.args, {
|
|
3842
4065
|
stdio: "pipe",
|
|
@@ -3853,9 +4076,10 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, s
|
|
|
3853
4076
|
version: 1,
|
|
3854
4077
|
context_key: contextKey,
|
|
3855
4078
|
created_at: new Date().toISOString(),
|
|
3856
|
-
source_cwd: process.env.OMX_SOURCE_CWD
|
|
4079
|
+
source_cwd: runtimeContext?.sourceCwd ?? process.env.OMX_SOURCE_CWD ?? cwd,
|
|
4080
|
+
...(runtimeContext?.worktreeCwd ? { worktree_cwd: runtimeContext.worktreeCwd } : {}),
|
|
3857
4081
|
argv: args,
|
|
3858
|
-
run_dir: process.env.OMX_ROOT
|
|
4082
|
+
run_dir: runtimeContext?.omxRoot ?? process.env.OMX_ROOT ?? cwd,
|
|
3859
4083
|
tmux_session_name: sessionName,
|
|
3860
4084
|
session_id: sessionId,
|
|
3861
4085
|
tmux_pane_id: leaderPaneId,
|
|
@@ -3924,6 +4148,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, s
|
|
|
3924
4148
|
sessionId,
|
|
3925
4149
|
omxBin,
|
|
3926
4150
|
omxRootOverride,
|
|
4151
|
+
baseEnv: runtimeHookEnv,
|
|
3927
4152
|
});
|
|
3928
4153
|
}
|
|
3929
4154
|
}
|
|
@@ -4663,6 +4888,7 @@ async function listHookVisibleRunDirStateRefs(cwd) {
|
|
|
4663
4888
|
return;
|
|
4664
4889
|
const record = raw;
|
|
4665
4890
|
const sourceCwd = typeof record.source_cwd === "string" ? record.source_cwd.trim() : "";
|
|
4891
|
+
const worktreeCwd = typeof record.worktree_cwd === "string" ? record.worktree_cwd.trim() : "";
|
|
4666
4892
|
const runDir = typeof record.run_dir === "string"
|
|
4667
4893
|
? record.run_dir.trim()
|
|
4668
4894
|
: typeof record.cwd === "string"
|
|
@@ -4671,7 +4897,8 @@ async function listHookVisibleRunDirStateRefs(cwd) {
|
|
|
4671
4897
|
if (!sourceCwd || !runDir)
|
|
4672
4898
|
return;
|
|
4673
4899
|
try {
|
|
4674
|
-
if (canonicalizePathForRunDirMatch(sourceCwd) !== canonicalCwd
|
|
4900
|
+
if (canonicalizePathForRunDirMatch(sourceCwd) !== canonicalCwd &&
|
|
4901
|
+
(!worktreeCwd || canonicalizePathForRunDirMatch(worktreeCwd) !== canonicalCwd))
|
|
4675
4902
|
return;
|
|
4676
4903
|
const resolvedRunDir = resolve(runDir);
|
|
4677
4904
|
if (resolvedRunDir !== canonicalRunsRoot
|