oh-my-codex 0.18.16 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +6 -6
- package/Cargo.toml +1 -1
- 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__/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 +46 -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 +21 -0
- 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 +25 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +233 -32
- package/dist/cli/index.js.map +1 -1
- 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 +110 -0
- 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 +44 -12
- 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/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__/runtime.test.js +202 -0
- package/dist/ralplan/__tests__/runtime.test.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 +8484 -4560
- 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 +4387 -190
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/state/__tests__/operations.test.js +1137 -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/operations.d.ts +10 -0
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +242 -8
- 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 +5 -3
- 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 +7 -0
- package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
- package/dist/ultragoal/artifacts.d.ts.map +1 -1
- package/dist/ultragoal/artifacts.js +5 -0
- 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 +14014 -9097
- package/src/scripts/codex-native-hook.ts +4459 -199
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";
|
|
@@ -43,6 +43,7 @@ import { getBaseStateDir, getStateDir, listModeStateFilesWithScopePreference, }
|
|
|
43
43
|
import { evaluateRalphCompletionAuditEvidence, isRalphCompletePhase } from "../ralph/completion-audit.js";
|
|
44
44
|
import { readPersistedSetupPreferences, resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, resolveProjectLocalCodexHomeForLaunch, } from "./codex-home.js";
|
|
45
45
|
import { discoverProjectRuntimeCodexHomes } from "./project-runtime-codex-homes.js";
|
|
46
|
+
import { materializePackagedOmxPluginCache, packagedOmxPluginVersion, resolvePackagedOmxMarketplace, upsertLocalOmxMarketplaceRegistration, upsertLocalOmxPluginEnablement, } from "./plugin-marketplace.js";
|
|
46
47
|
import { escapeTomlString, readTopLevelTomlString, upsertTopLevelTomlString } from "../utils/toml.js";
|
|
47
48
|
export { readPersistedSetupPreferences, readPersistedSetupScope, resolveCodexConfigPathForLaunch, resolveCodexHomeForLaunch, resolveProjectLocalCodexHomeForLaunch, } from "./codex-home.js";
|
|
48
49
|
import { SKILL_ACTIVE_STATE_MODE, extractSessionIdFromInitializedStatePath, getSkillActiveStatePathsForStateDir, listActiveSkills, readSkillActiveState, syncCanonicalSkillStateForMode, } from "../state/skill-active.js";
|
|
@@ -65,7 +66,7 @@ rememberOmxLaunchContext({ argv1: process.argv[1], cwd: process.cwd(), env: proc
|
|
|
65
66
|
import { classifySpawnError, resolveTmuxBinaryForPlatform, spawnPlatformCommandSync, } from "../utils/platform-command.js";
|
|
66
67
|
import { buildHookEvent } from "../hooks/extensibility/events.js";
|
|
67
68
|
import { dispatchHookEvent } from "../hooks/extensibility/dispatcher.js";
|
|
68
|
-
import { collectInheritableTeamWorkerArgs as collectInheritableTeamWorkerArgsShared, resolveTeamWorkerLaunchArgs, resolveTeamLowComplexityDefaultModel, } from "../team/model-contract.js";
|
|
69
|
+
import { collectInheritableTeamWorkerArgs as collectInheritableTeamWorkerArgsShared, parseTeamWorkerLaunchArgs, resolveTeamWorkerLaunchArgs, resolveTeamLowComplexityDefaultModel, TEAM_WORKER_INHERITED_MODEL_ENV, } from "../team/model-contract.js";
|
|
69
70
|
import { parseWorktreeMode, planWorktreeTarget, ensureWorktree, } from "../team/worktree.js";
|
|
70
71
|
import { ensureReusableNodeModules } from "../utils/repo-deps.js";
|
|
71
72
|
import { OMX_NOTIFY_TEMP_CONTRACT_ENV, parseNotifyTempContractFromArgs, serializeNotifyTempContract, } from "../notifications/temp-contract.js";
|
|
@@ -667,26 +668,43 @@ async function materializeProjectLaunchRuntimeHistoryEntries(runtimeCodexHome, s
|
|
|
667
668
|
await copyFile(source, destination);
|
|
668
669
|
}
|
|
669
670
|
}
|
|
670
|
-
async function mergeProjectLaunchRuntimeHistoryEntries(runtimeCodexHome, sourceCodexHome) {
|
|
671
|
+
async function mergeProjectLaunchRuntimeHistoryEntries(runtimeCodexHome, sourceCodexHome, mergedHistorySourceRealpaths) {
|
|
671
672
|
for (const entryName of PROJECT_LAUNCH_DURABLE_HISTORY_ENTRY_NAMES) {
|
|
672
673
|
const source = join(sourceCodexHome, entryName);
|
|
673
674
|
if (!existsSync(source))
|
|
674
675
|
continue;
|
|
676
|
+
const sourceRealpath = realpathSync(source);
|
|
677
|
+
if (mergedHistorySourceRealpaths.has(sourceRealpath))
|
|
678
|
+
continue;
|
|
675
679
|
const destination = join(runtimeCodexHome, entryName);
|
|
676
|
-
const sourceStat = await
|
|
680
|
+
const sourceStat = await stat(source);
|
|
677
681
|
if (sourceStat.isDirectory()) {
|
|
678
682
|
await mkdir(destination, { recursive: true });
|
|
679
683
|
await cp(source, destination, { recursive: true, force: true, dereference: true });
|
|
684
|
+
mergedHistorySourceRealpaths.add(sourceRealpath);
|
|
680
685
|
continue;
|
|
681
686
|
}
|
|
687
|
+
if (entryName === "sessions")
|
|
688
|
+
continue;
|
|
689
|
+
if (!sourceStat.isFile())
|
|
690
|
+
continue;
|
|
682
691
|
if (existsSync(destination)) {
|
|
692
|
+
const destinationStat = await stat(destination);
|
|
693
|
+
if (!destinationStat.isFile()) {
|
|
694
|
+
await rm(destination, { recursive: true, force: true });
|
|
695
|
+
await copyFile(source, destination);
|
|
696
|
+
mergedHistorySourceRealpaths.add(sourceRealpath);
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
683
699
|
const existing = await readFile(destination, "utf-8").catch(() => "");
|
|
684
700
|
const addition = await readFile(source, "utf-8");
|
|
685
701
|
const separator = existing === "" || existing.endsWith("\n") || addition === "" ? "" : "\n";
|
|
686
702
|
await writeFile(destination, `${existing}${separator}${addition}`, "utf-8");
|
|
703
|
+
mergedHistorySourceRealpaths.add(sourceRealpath);
|
|
687
704
|
continue;
|
|
688
705
|
}
|
|
689
706
|
await copyFile(source, destination);
|
|
707
|
+
mergedHistorySourceRealpaths.add(sourceRealpath);
|
|
690
708
|
}
|
|
691
709
|
}
|
|
692
710
|
export async function persistProjectLaunchRuntimeAuthState(runtimeCodexHome, projectCodexHome) {
|
|
@@ -730,9 +748,15 @@ export async function prepareRuntimeCodexHomeForProjectLaunch(cwd, sessionId, pr
|
|
|
730
748
|
}
|
|
731
749
|
await ensureProjectLaunchRuntimeHistoryLinks(runtimeCodexHome, projectCodexHome);
|
|
732
750
|
if (options.includeHistoryArtifacts === true && (options.extraHistoryCodexHomes?.length ?? 0) > 0) {
|
|
751
|
+
const mergedHistorySourceRealpaths = new Set();
|
|
752
|
+
for (const entryName of PROJECT_LAUNCH_DURABLE_HISTORY_ENTRY_NAMES) {
|
|
753
|
+
const source = join(projectCodexHome, entryName);
|
|
754
|
+
if (existsSync(source))
|
|
755
|
+
mergedHistorySourceRealpaths.add(realpathSync(source));
|
|
756
|
+
}
|
|
733
757
|
await materializeProjectLaunchRuntimeHistoryEntries(runtimeCodexHome, projectCodexHome);
|
|
734
758
|
for (const extraCodexHome of options.extraHistoryCodexHomes ?? []) {
|
|
735
|
-
await mergeProjectLaunchRuntimeHistoryEntries(runtimeCodexHome, extraCodexHome);
|
|
759
|
+
await mergeProjectLaunchRuntimeHistoryEntries(runtimeCodexHome, extraCodexHome, mergedHistorySourceRealpaths);
|
|
736
760
|
}
|
|
737
761
|
}
|
|
738
762
|
return runtimeCodexHome;
|
|
@@ -793,13 +817,46 @@ export function parseResumeCodexHomeSelection(args) {
|
|
|
793
817
|
projectOnly,
|
|
794
818
|
};
|
|
795
819
|
}
|
|
820
|
+
export async function preflightResumeOmxPluginState(codexHomeDir, pkgRoot = getPackageRoot()) {
|
|
821
|
+
const selectedCodexHomeDir = codexHomeDir && codexHomeDir.trim() !== ""
|
|
822
|
+
? codexHomeDir
|
|
823
|
+
: join(homedir(), ".codex");
|
|
824
|
+
const packagedMarketplace = await resolvePackagedOmxMarketplace(pkgRoot);
|
|
825
|
+
if (!packagedMarketplace) {
|
|
826
|
+
return { status: "unavailable", prunedStaleDirs: [], configUpdated: false };
|
|
827
|
+
}
|
|
828
|
+
const materialized = await materializePackagedOmxPluginCache(selectedCodexHomeDir, packagedMarketplace);
|
|
829
|
+
const version = materialized.version ?? (await packagedOmxPluginVersion(packagedMarketplace)) ?? undefined;
|
|
830
|
+
const currentCacheDir = materialized.cacheDir ?? (version ? join(selectedCodexHomeDir, "plugins", "cache", "oh-my-codex-local", "oh-my-codex", version) : undefined);
|
|
831
|
+
const prunedStaleDirs = [];
|
|
832
|
+
const configPath = join(selectedCodexHomeDir, "config.toml");
|
|
833
|
+
const existingConfig = existsSync(configPath) ? await readFile(configPath, "utf-8") : "";
|
|
834
|
+
const nextConfig = upsertLocalOmxMarketplaceRegistration(upsertLocalOmxPluginEnablement(existingConfig), pkgRoot);
|
|
835
|
+
const configUpdated = nextConfig !== existingConfig;
|
|
836
|
+
if (configUpdated) {
|
|
837
|
+
await mkdir(dirname(configPath), { recursive: true });
|
|
838
|
+
await writeFile(configPath, nextConfig, "utf-8");
|
|
839
|
+
}
|
|
840
|
+
return {
|
|
841
|
+
status: "prepared",
|
|
842
|
+
version,
|
|
843
|
+
cacheDir: currentCacheDir,
|
|
844
|
+
prunedStaleDirs,
|
|
845
|
+
configUpdated,
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
function isResumeCodexLaunch(args) {
|
|
849
|
+
return args.includes("resume");
|
|
850
|
+
}
|
|
796
851
|
async function prepareResumeCodexHomeForLaunch(cwd, sessionId, args, env = process.env) {
|
|
797
852
|
const selection = parseResumeCodexHomeSelection(args);
|
|
798
853
|
if (selection.explicitCodexHome) {
|
|
854
|
+
const codexHomeOverride = resolve(selection.explicitCodexHome);
|
|
855
|
+
await preflightResumeOmxPluginState(codexHomeOverride);
|
|
799
856
|
return {
|
|
800
857
|
args: selection.args,
|
|
801
858
|
prepared: {
|
|
802
|
-
codexHomeOverride
|
|
859
|
+
codexHomeOverride,
|
|
803
860
|
},
|
|
804
861
|
};
|
|
805
862
|
}
|
|
@@ -809,6 +866,7 @@ async function prepareResumeCodexHomeForLaunch(cwd, sessionId, args, env = proce
|
|
|
809
866
|
const emptyRuntimeCodexHome = runtimeCodexHomePath(cwd, sessionId);
|
|
810
867
|
await rm(emptyRuntimeCodexHome, { recursive: true, force: true });
|
|
811
868
|
await mkdir(join(emptyRuntimeCodexHome, "sessions"), { recursive: true });
|
|
869
|
+
await preflightResumeOmxPluginState(emptyRuntimeCodexHome);
|
|
812
870
|
return {
|
|
813
871
|
args: selection.args,
|
|
814
872
|
prepared: {
|
|
@@ -821,6 +879,7 @@ async function prepareResumeCodexHomeForLaunch(cwd, sessionId, args, env = proce
|
|
|
821
879
|
includeHistoryArtifacts: true,
|
|
822
880
|
extraHistoryCodexHomes: projectHomes.slice(1).map((home) => home.path),
|
|
823
881
|
});
|
|
882
|
+
await preflightResumeOmxPluginState(runtimeCodexHome);
|
|
824
883
|
return {
|
|
825
884
|
args: selection.args,
|
|
826
885
|
prepared: {
|
|
@@ -832,6 +891,7 @@ async function prepareResumeCodexHomeForLaunch(cwd, sessionId, args, env = proce
|
|
|
832
891
|
includeHistoryArtifacts: true,
|
|
833
892
|
extraHistoryCodexHomes: projectHomes.map((home) => home.path),
|
|
834
893
|
});
|
|
894
|
+
await preflightResumeOmxPluginState(prepared.codexHomeOverride);
|
|
835
895
|
return { args: selection.args, prepared };
|
|
836
896
|
}
|
|
837
897
|
export async function persistProjectLaunchRuntimeProjectTrustState(runtimeCodexHome, projectCodexHome) {
|
|
@@ -1362,20 +1422,88 @@ export function resolveDisposableWorktreeOmxRootForLaunch(ensuredWorktree, env =
|
|
|
1362
1422
|
return undefined;
|
|
1363
1423
|
return ensuredWorktree.repoRoot;
|
|
1364
1424
|
}
|
|
1425
|
+
function buildMadmaxWorktreeRuntimeEnvOverlay(runtimeContext) {
|
|
1426
|
+
if (!runtimeContext)
|
|
1427
|
+
return {};
|
|
1428
|
+
return {
|
|
1429
|
+
OMX_ROOT: runtimeContext.omxRoot,
|
|
1430
|
+
...(runtimeContext.omxStateRoot ? { OMX_STATE_ROOT: runtimeContext.omxStateRoot } : {}),
|
|
1431
|
+
...(runtimeContext.boxedActive ? { OMXBOX_ACTIVE: "1" } : {}),
|
|
1432
|
+
OMX_SOURCE_CWD: runtimeContext.sourceCwd,
|
|
1433
|
+
...(runtimeContext.madmaxDetachedContext
|
|
1434
|
+
? { [OMX_MADMAX_DETACHED_CONTEXT_ENV]: runtimeContext.madmaxDetachedContext }
|
|
1435
|
+
: {}),
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
export function captureMadmaxWorktreeRuntimeContext(options) {
|
|
1439
|
+
const env = options.env ?? process.env;
|
|
1440
|
+
if (!options.worktreeEnabled)
|
|
1441
|
+
return undefined;
|
|
1442
|
+
if (!launchArgsRequestMadmaxIsolation(options.originalLaunchArgs))
|
|
1443
|
+
return undefined;
|
|
1444
|
+
if (env.OMXBOX_ACTIVE !== "1")
|
|
1445
|
+
return undefined;
|
|
1446
|
+
const inheritedRoot = resolveInheritedMadmaxRoot(env);
|
|
1447
|
+
if (!inheritedRoot)
|
|
1448
|
+
return undefined;
|
|
1449
|
+
const sourceCwd = env.OMX_SOURCE_CWD?.trim() || options.sourceCwd;
|
|
1450
|
+
const worktreeCwd = options.worktreeCwd?.trim();
|
|
1451
|
+
const omxStateRoot = env.OMX_STATE_ROOT?.trim();
|
|
1452
|
+
const madmaxDetachedContext = env[OMX_MADMAX_DETACHED_CONTEXT_ENV]?.trim();
|
|
1453
|
+
return {
|
|
1454
|
+
omxRoot: resolveLaunchPath(options.sourceCwd, inheritedRoot),
|
|
1455
|
+
...(omxStateRoot ? { omxStateRoot: resolveLaunchPath(options.sourceCwd, omxStateRoot) } : {}),
|
|
1456
|
+
sourceCwd,
|
|
1457
|
+
...(worktreeCwd && worktreeCwd !== sourceCwd ? { worktreeCwd } : {}),
|
|
1458
|
+
...(madmaxDetachedContext ? { madmaxDetachedContext } : {}),
|
|
1459
|
+
boxedActive: true,
|
|
1460
|
+
};
|
|
1461
|
+
}
|
|
1365
1462
|
function applyDisposableWorktreeOmxRootForLaunch(ensuredWorktree, env = process.env) {
|
|
1366
1463
|
const omxRootOverride = resolveDisposableWorktreeOmxRootForLaunch(ensuredWorktree, env);
|
|
1367
1464
|
if (!omxRootOverride)
|
|
1368
1465
|
return;
|
|
1369
1466
|
env.OMX_ROOT = omxRootOverride;
|
|
1370
1467
|
}
|
|
1371
|
-
|
|
1468
|
+
function launchArgRequestsDisposableWorktree(arg) {
|
|
1469
|
+
return arg === "--worktree" ||
|
|
1470
|
+
arg === "-w" ||
|
|
1471
|
+
arg.startsWith("--worktree=") ||
|
|
1472
|
+
// Covers both `-w=<name>` and `-w<name>`; an explicit `-w=` check would be a
|
|
1473
|
+
// strict subset of this clause, so it is omitted as redundant.
|
|
1474
|
+
(arg.startsWith("-w") && arg.length > 2);
|
|
1475
|
+
}
|
|
1476
|
+
function launchArgsRequestMadmaxIsolation(launchArgs) {
|
|
1477
|
+
return launchArgs.some((arg) => arg === MADMAX_FLAG || arg === MADMAX_SPARK_FLAG);
|
|
1478
|
+
}
|
|
1479
|
+
function launchArgsRequestDisposableWorktree(launchArgs) {
|
|
1480
|
+
return launchArgs.some((arg) => launchArgRequestsDisposableWorktree(arg));
|
|
1481
|
+
}
|
|
1482
|
+
function clearInheritedMadmaxRootForDisposableWorktreeLaunch(launchArgs, env = process.env) {
|
|
1483
|
+
if (!launchArgsRequestDisposableWorktree(launchArgs))
|
|
1484
|
+
return;
|
|
1485
|
+
if (env.OMXBOX_ACTIVE !== "1")
|
|
1486
|
+
return;
|
|
1487
|
+
delete env.OMX_ROOT;
|
|
1488
|
+
delete env.OMX_STATE_ROOT;
|
|
1489
|
+
delete env.OMXBOX_ACTIVE;
|
|
1490
|
+
delete env.OMX_SOURCE_CWD;
|
|
1491
|
+
delete env[OMX_MADMAX_DETACHED_CONTEXT_ENV];
|
|
1492
|
+
}
|
|
1493
|
+
export function shouldAutoIsolateMadmaxLaunch(command, launchArgs, env = process.env, cwd = process.cwd()) {
|
|
1372
1494
|
if (command !== "launch" && command !== "exec")
|
|
1373
1495
|
return false;
|
|
1374
|
-
if (env.OMX_NO_BOX === "1"
|
|
1496
|
+
if (env.OMX_NO_BOX === "1")
|
|
1375
1497
|
return false;
|
|
1376
|
-
if (
|
|
1498
|
+
if (!launchArgsRequestMadmaxIsolation(launchArgs))
|
|
1377
1499
|
return false;
|
|
1378
|
-
|
|
1500
|
+
const inheritedContext = env[OMX_MADMAX_DETACHED_CONTEXT_ENV]?.trim();
|
|
1501
|
+
if (env.OMXBOX_ACTIVE === "1" && inheritedContext && !resolveInheritedMadmaxRoot(env)) {
|
|
1502
|
+
return false;
|
|
1503
|
+
}
|
|
1504
|
+
if (madmaxInheritedContextMatchesLaunch(cwd, launchArgs, env))
|
|
1505
|
+
return false;
|
|
1506
|
+
return true;
|
|
1379
1507
|
}
|
|
1380
1508
|
function sanitizeRunIdSegment(value) {
|
|
1381
1509
|
return value.replace(/[^a-zA-Z0-9._-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
@@ -1474,6 +1602,7 @@ function readMadmaxDetachedActiveRecord(recordPath) {
|
|
|
1474
1602
|
tmux_session_name: parsed.tmux_session_name,
|
|
1475
1603
|
...(typeof parsed.session_id === "string" ? { session_id: parsed.session_id } : {}),
|
|
1476
1604
|
...(typeof parsed.tmux_pane_id === "string" ? { tmux_pane_id: parsed.tmux_pane_id } : {}),
|
|
1605
|
+
...(typeof parsed.worktree_cwd === "string" ? { worktree_cwd: parsed.worktree_cwd } : {}),
|
|
1477
1606
|
};
|
|
1478
1607
|
}
|
|
1479
1608
|
catch {
|
|
@@ -1607,6 +1736,43 @@ export function withMadmaxDetachedContextLock(runsRoot, contextKey, run, options
|
|
|
1607
1736
|
}
|
|
1608
1737
|
throw new MadmaxDetachedGuardError(`timed out waiting for madmax detached launch context lock: ${lockPath} (${lastDiagnostic})`);
|
|
1609
1738
|
}
|
|
1739
|
+
function readMadmaxRunMetadata(runRoot) {
|
|
1740
|
+
try {
|
|
1741
|
+
const parsed = JSON.parse(readFileSync(join(runRoot, ".omxbox-run.json"), "utf-8"));
|
|
1742
|
+
return {
|
|
1743
|
+
...(typeof parsed.cwd === "string" ? { cwd: parsed.cwd } : {}),
|
|
1744
|
+
...(typeof parsed.detached_launch_context === "string"
|
|
1745
|
+
? { detached_launch_context: parsed.detached_launch_context }
|
|
1746
|
+
: {}),
|
|
1747
|
+
};
|
|
1748
|
+
}
|
|
1749
|
+
catch {
|
|
1750
|
+
return null;
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
function resolveInheritedMadmaxRoot(env) {
|
|
1754
|
+
const root = env.OMX_ROOT?.trim() || env.OMX_STATE_ROOT?.trim();
|
|
1755
|
+
return root || undefined;
|
|
1756
|
+
}
|
|
1757
|
+
function madmaxInheritedContextMatchesLaunch(cwd, launchArgs, env) {
|
|
1758
|
+
if (env.OMXBOX_ACTIVE !== "1")
|
|
1759
|
+
return false;
|
|
1760
|
+
const context = env[OMX_MADMAX_DETACHED_CONTEXT_ENV]?.trim();
|
|
1761
|
+
if (!context)
|
|
1762
|
+
return false;
|
|
1763
|
+
const inheritedRoot = resolveInheritedMadmaxRoot(env);
|
|
1764
|
+
if (!inheritedRoot)
|
|
1765
|
+
return false;
|
|
1766
|
+
const metadata = readMadmaxRunMetadata(inheritedRoot);
|
|
1767
|
+
if (!metadata)
|
|
1768
|
+
return false;
|
|
1769
|
+
if (metadata.cwd && metadata.cwd !== inheritedRoot)
|
|
1770
|
+
return false;
|
|
1771
|
+
if (metadata.detached_launch_context !== context)
|
|
1772
|
+
return false;
|
|
1773
|
+
const expectedContext = buildMadmaxDetachedLaunchContextKey(cwd, [...launchArgs], inheritedRoot);
|
|
1774
|
+
return expectedContext === context;
|
|
1775
|
+
}
|
|
1610
1776
|
function isMadmaxDetachedGuardEnabled(env) {
|
|
1611
1777
|
return env.OMXBOX_ACTIVE === "1" && typeof env[OMX_MADMAX_DETACHED_CONTEXT_ENV] === "string";
|
|
1612
1778
|
}
|
|
@@ -1651,7 +1817,7 @@ export function createMadmaxIsolatedRoot(sourceCwd, argv, env = process.env) {
|
|
|
1651
1817
|
return runDir;
|
|
1652
1818
|
}
|
|
1653
1819
|
function activateMadmaxIsolationIfNeeded(command, launchArgs, cwd, env = process.env) {
|
|
1654
|
-
if (!shouldAutoIsolateMadmaxLaunch(command, launchArgs, env))
|
|
1820
|
+
if (!shouldAutoIsolateMadmaxLaunch(command, launchArgs, env, cwd))
|
|
1655
1821
|
return;
|
|
1656
1822
|
const runDir = createMadmaxIsolatedRoot(cwd, launchArgs, env);
|
|
1657
1823
|
env.OMX_ROOT = runDir;
|
|
@@ -2066,6 +2232,7 @@ export async function launchWithAuthHotswap(args) {
|
|
|
2066
2232
|
}
|
|
2067
2233
|
}
|
|
2068
2234
|
}
|
|
2235
|
+
clearInheritedMadmaxRootForDisposableWorktreeLaunch(parsedWorktree.remainingArgs);
|
|
2069
2236
|
applyDisposableWorktreeOmxRootForLaunch(ensuredLaunchWorktree);
|
|
2070
2237
|
try {
|
|
2071
2238
|
await maybeCheckAndPromptUpdate(cwd);
|
|
@@ -2165,6 +2332,14 @@ export async function launchWithHud(args) {
|
|
|
2165
2332
|
}
|
|
2166
2333
|
}
|
|
2167
2334
|
}
|
|
2335
|
+
const madmaxWorktreeRuntimeContext = captureMadmaxWorktreeRuntimeContext({
|
|
2336
|
+
originalLaunchArgs: args,
|
|
2337
|
+
worktreeEnabled: Boolean(parsedWorktree.mode.enabled && ensuredLaunchWorktree?.enabled),
|
|
2338
|
+
sourceCwd: launchCwd,
|
|
2339
|
+
worktreeCwd: ensuredLaunchWorktree?.enabled ? ensuredLaunchWorktree.worktreePath : undefined,
|
|
2340
|
+
env: process.env,
|
|
2341
|
+
});
|
|
2342
|
+
clearInheritedMadmaxRootForDisposableWorktreeLaunch(parsedWorktree.remainingArgs);
|
|
2168
2343
|
applyDisposableWorktreeOmxRootForLaunch(ensuredLaunchWorktree);
|
|
2169
2344
|
const sessionId = `omx-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
2170
2345
|
try {
|
|
@@ -2195,14 +2370,14 @@ export async function launchWithHud(args) {
|
|
|
2195
2370
|
catch {
|
|
2196
2371
|
// Non-fatal: repair failure must not block launch
|
|
2197
2372
|
}
|
|
2198
|
-
const resumePrepared = normalizedArgs
|
|
2373
|
+
const resumePrepared = isResumeCodexLaunch(normalizedArgs)
|
|
2199
2374
|
? await prepareResumeCodexHomeForLaunch(launchCwd, sessionId, normalizedArgs, process.env)
|
|
2200
2375
|
: null;
|
|
2201
2376
|
if (resumePrepared) {
|
|
2202
2377
|
normalizedArgs = resumePrepared.args;
|
|
2203
2378
|
}
|
|
2204
2379
|
const preparedCodexHome = resumePrepared?.prepared ?? await prepareCodexHomeForLaunch(launchCwd, sessionId, process.env, {
|
|
2205
|
-
includeHistoryArtifacts: normalizedArgs
|
|
2380
|
+
includeHistoryArtifacts: isResumeCodexLaunch(normalizedArgs),
|
|
2206
2381
|
});
|
|
2207
2382
|
const codexHomeOverride = preparedCodexHome.codexHomeOverride;
|
|
2208
2383
|
const sqliteHomeOverride = preparedCodexHome.sqliteHomeOverride;
|
|
@@ -2221,7 +2396,7 @@ export async function launchWithHud(args) {
|
|
|
2221
2396
|
const notifyTempContractRaw = notifyTempResult.contract.active
|
|
2222
2397
|
? serializeNotifyTempContract(notifyTempResult.contract)
|
|
2223
2398
|
: null;
|
|
2224
|
-
const launchResult = runCodex(cwd, normalizedArgs, sessionId, workerSparkModel, codexHomeOverride, sqliteHomeOverride, notifyTempContractRaw, effectiveExplicitLaunchPolicy, projectLocalCodexHomeForCleanup, preparedCodexHome.runtimeCodexHomeForCleanup);
|
|
2399
|
+
const launchResult = runCodex(cwd, normalizedArgs, sessionId, workerSparkModel, codexHomeOverride, sqliteHomeOverride, notifyTempContractRaw, effectiveExplicitLaunchPolicy, projectLocalCodexHomeForCleanup, preparedCodexHome.runtimeCodexHomeForCleanup, madmaxWorktreeRuntimeContext);
|
|
2225
2400
|
postLaunchHandledExternally = launchResult.postLaunchHandledExternally;
|
|
2226
2401
|
}
|
|
2227
2402
|
finally {
|
|
@@ -2264,6 +2439,7 @@ export async function execWithOverlay(args) {
|
|
|
2264
2439
|
}
|
|
2265
2440
|
}
|
|
2266
2441
|
}
|
|
2442
|
+
clearInheritedMadmaxRootForDisposableWorktreeLaunch(parsedWorktree.remainingArgs);
|
|
2267
2443
|
applyDisposableWorktreeOmxRootForLaunch(ensuredLaunchWorktree);
|
|
2268
2444
|
const sessionId = `omx-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
2269
2445
|
try {
|
|
@@ -2982,7 +3158,7 @@ export function withTmuxExtendedKeys(cwd, run, execFileSyncImpl = (file, tmuxArg
|
|
|
2982
3158
|
releaseTmuxExtendedKeysLease(cwd, leaseHandle, execFileSyncImpl);
|
|
2983
3159
|
}
|
|
2984
3160
|
}
|
|
2985
|
-
export function buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw, nativeWindows = false, sessionId, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, omxRootOverride, env = process.env, sqliteHomeOverride, parentEnvFilePath) {
|
|
3161
|
+
export function buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw, nativeWindows = false, sessionId, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, omxRootOverride, env = process.env, sqliteHomeOverride, parentEnvFilePath, inheritedWorkerModel) {
|
|
2986
3162
|
const detachedLeaderCmd = nativeWindows
|
|
2987
3163
|
? "powershell.exe"
|
|
2988
3164
|
: buildDetachedSessionLeaderCommand(cwd, sessionName, codexCmd, sessionId, codexHomeOverride, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, parentEnvFilePath);
|
|
@@ -3013,17 +3189,19 @@ export function buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, h
|
|
|
3013
3189
|
sessionName,
|
|
3014
3190
|
"-c",
|
|
3015
3191
|
cwd,
|
|
3016
|
-
...(workerLaunchArgs
|
|
3017
|
-
? ["-e", `${TEAM_WORKER_LAUNCH_ARGS_ENV}=${workerLaunchArgs}`]
|
|
3018
|
-
: []),
|
|
3192
|
+
...(workerLaunchArgs ? ["-e", `${TEAM_WORKER_LAUNCH_ARGS_ENV}=${workerLaunchArgs}`] : []),
|
|
3019
3193
|
...Object.entries(hudRuntimeEnv).map(([key, value]) => ["-e", `${key}=${value}`]).flat(),
|
|
3020
3194
|
...(codexHomeOverride ? ["-e", `CODEX_HOME=${codexHomeOverride}`] : []),
|
|
3021
3195
|
...(sqliteHomeOverride ? ["-e", `${CODEX_SQLITE_HOME_ENV}=${sqliteHomeOverride}`] : []),
|
|
3022
3196
|
...(env.OMXBOX_ACTIVE ? ["-e", `OMXBOX_ACTIVE=${env.OMXBOX_ACTIVE}`] : []),
|
|
3023
3197
|
...(env.OMX_SOURCE_CWD ? ["-e", `OMX_SOURCE_CWD=${env.OMX_SOURCE_CWD}`] : []),
|
|
3198
|
+
...(env[OMX_MADMAX_DETACHED_CONTEXT_ENV]
|
|
3199
|
+
? ["-e", `${OMX_MADMAX_DETACHED_CONTEXT_ENV}=${env[OMX_MADMAX_DETACHED_CONTEXT_ENV]}`]
|
|
3200
|
+
: []),
|
|
3024
3201
|
...(notifyTempContractRaw
|
|
3025
3202
|
? ["-e", `${OMX_NOTIFY_TEMP_CONTRACT_ENV}=${notifyTempContractRaw}`]
|
|
3026
3203
|
: []),
|
|
3204
|
+
...(inheritedWorkerModel ? ["-e", `${TEAM_WORKER_INHERITED_MODEL_ENV}=${inheritedWorkerModel}`] : []),
|
|
3027
3205
|
detachedLeaderCmd,
|
|
3028
3206
|
];
|
|
3029
3207
|
const splitCaptureArgs = [
|
|
@@ -3606,42 +3784,59 @@ ${launchAppendix}${dirtyWorktreeGuidance}`
|
|
|
3606
3784
|
* runCodex: Launch Codex CLI (blocks until exit).
|
|
3607
3785
|
* All 3 paths (new tmux, existing tmux, no tmux) block via execSync/execFileSync.
|
|
3608
3786
|
*/
|
|
3609
|
-
function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, sqliteHomeOverride, notifyTempContractRaw, explicitLaunchPolicy, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup) {
|
|
3787
|
+
function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, sqliteHomeOverride, notifyTempContractRaw, explicitLaunchPolicy, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, runtimeContext) {
|
|
3610
3788
|
const launchArgs = injectModelInstructionsBypassArgs(cwd, args, process.env, sessionModelInstructionsPath(cwd, sessionId));
|
|
3611
3789
|
const nativeWindows = isNativeWindows();
|
|
3612
3790
|
const omxBin = resolveOmxCliEntryPath({ argv1: process.argv[1], cwd, env: process.env });
|
|
3613
3791
|
if (!omxBin) {
|
|
3614
3792
|
throw new Error("Unable to resolve OMX launcher path for tmux HUD bootstrap");
|
|
3615
3793
|
}
|
|
3616
|
-
const
|
|
3794
|
+
const runtimeEnvOverlay = buildMadmaxWorktreeRuntimeEnvOverlay(runtimeContext);
|
|
3795
|
+
const omxRootOverride = runtimeContext?.omxRoot ?? resolveOmxRootForLaunch(cwd, process.env);
|
|
3617
3796
|
const currentPaneId = process.env.TMUX_PANE;
|
|
3618
|
-
const hudRuntimeRoot =
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
...
|
|
3623
|
-
|
|
3797
|
+
const hudRuntimeRoot = runtimeContext
|
|
3798
|
+
? { omxRoot: runtimeContext.omxRoot, rootSource: 'omx-root-env' }
|
|
3799
|
+
: resolveHudRuntimeRootForLaunch(cwd, process.env);
|
|
3800
|
+
const hudRuntimeEnv = {
|
|
3801
|
+
...buildHudRuntimeEnv({
|
|
3802
|
+
sessionId,
|
|
3803
|
+
leaderPaneId: currentPaneId,
|
|
3804
|
+
...hudRuntimeRoot,
|
|
3805
|
+
}).env,
|
|
3806
|
+
...runtimeEnvOverlay,
|
|
3807
|
+
};
|
|
3808
|
+
const hudEnvArgs = Object.entries(hudRuntimeEnv).map(([key, value]) => `${key}=${value}`);
|
|
3624
3809
|
const hudCmd = nativeWindows
|
|
3625
3810
|
? buildWindowsPromptCommand("node", [omxBin, "hud", "--watch"])
|
|
3626
3811
|
: buildTmuxPaneCommand("env", [...hudEnvArgs, "node", omxBin, "hud", "--watch"]);
|
|
3627
3812
|
const inheritLeaderFlags = process.env[TEAM_INHERIT_LEADER_FLAGS_ENV] !== "0";
|
|
3813
|
+
const inheritedWorkerLaunchArgs = inheritLeaderFlags
|
|
3814
|
+
? collectInheritableTeamWorkerArgsShared(launchArgs)
|
|
3815
|
+
: [];
|
|
3816
|
+
const inheritedWorkerModel = parseTeamWorkerLaunchArgs(inheritedWorkerLaunchArgs).modelOverride ?? undefined;
|
|
3628
3817
|
const workerLaunchArgs = resolveTeamWorkerLaunchArgsEnv(process.env[TEAM_WORKER_LAUNCH_ARGS_ENV], launchArgs, inheritLeaderFlags, workerDefaultModel);
|
|
3629
3818
|
const codexBaseEnv = prependOmxRuntimeCommandShimToEnv(cwd, {
|
|
3630
3819
|
...stripHermesMcpBridgeEnv(process.env),
|
|
3631
3820
|
...(codexHomeOverride ? { CODEX_HOME: codexHomeOverride } : {}),
|
|
3632
3821
|
...(sqliteHomeOverride ? { [CODEX_SQLITE_HOME_ENV]: sqliteHomeOverride } : {}),
|
|
3633
3822
|
...(omxRootOverride ? { OMX_ROOT: omxRootOverride } : {}),
|
|
3823
|
+
...runtimeEnvOverlay,
|
|
3634
3824
|
}, omxBin);
|
|
3635
3825
|
const codexEnvWithSession = {
|
|
3636
3826
|
...codexBaseEnv,
|
|
3637
3827
|
...buildHudRuntimeEnv({ sessionId }).env,
|
|
3638
3828
|
};
|
|
3639
3829
|
const codexEnv = workerLaunchArgs
|
|
3640
|
-
? {
|
|
3830
|
+
? {
|
|
3831
|
+
...codexEnvWithSession,
|
|
3832
|
+
[TEAM_WORKER_LAUNCH_ARGS_ENV]: workerLaunchArgs,
|
|
3833
|
+
...(inheritedWorkerModel ? { [TEAM_WORKER_INHERITED_MODEL_ENV]: inheritedWorkerModel } : {}),
|
|
3834
|
+
}
|
|
3641
3835
|
: codexEnvWithSession;
|
|
3642
3836
|
const codexEnvWithNotify = notifyTempContractRaw
|
|
3643
3837
|
? { ...codexEnv, [OMX_NOTIFY_TEMP_CONTRACT_ENV]: notifyTempContractRaw }
|
|
3644
3838
|
: codexEnv;
|
|
3839
|
+
const runtimeHookEnv = { ...process.env, ...runtimeEnvOverlay };
|
|
3645
3840
|
const { launchPolicy } = resolveTmuxAwareLaunchPolicy(explicitLaunchPolicy, nativeWindows);
|
|
3646
3841
|
if (isCodexVersionRequest(launchArgs)) {
|
|
3647
3842
|
runCodexBlocking(cwd, launchArgs, codexEnvWithNotify);
|
|
@@ -3679,6 +3874,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, s
|
|
|
3679
3874
|
cwd,
|
|
3680
3875
|
sessionId,
|
|
3681
3876
|
omxRootOverride,
|
|
3877
|
+
baseEnv: runtimeHookEnv,
|
|
3682
3878
|
});
|
|
3683
3879
|
}
|
|
3684
3880
|
catch (err) {
|
|
@@ -3705,6 +3901,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, s
|
|
|
3705
3901
|
cwd,
|
|
3706
3902
|
sessionId,
|
|
3707
3903
|
omxRootOverride,
|
|
3904
|
+
baseEnv: runtimeHookEnv,
|
|
3708
3905
|
});
|
|
3709
3906
|
}
|
|
3710
3907
|
catch (err) {
|
|
@@ -3771,7 +3968,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, s
|
|
|
3771
3968
|
: null;
|
|
3772
3969
|
const sessionName = buildDetachedTmuxSessionName(cwd, sessionId);
|
|
3773
3970
|
const launchDetachedSession = () => {
|
|
3774
|
-
const contextKey = process.env[OMX_MADMAX_DETACHED_CONTEXT_ENV]?.trim();
|
|
3971
|
+
const contextKey = runtimeContext?.madmaxDetachedContext ?? process.env[OMX_MADMAX_DETACHED_CONTEXT_ENV]?.trim();
|
|
3775
3972
|
const runsRoot = resolveMadmaxRunsRoot(process.env);
|
|
3776
3973
|
const activeRecordPath = contextKey
|
|
3777
3974
|
? madmaxDetachedActiveRecordPath(runsRoot, contextKey)
|
|
@@ -3836,7 +4033,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, s
|
|
|
3836
4033
|
if (!nativeWindows) {
|
|
3837
4034
|
detachedParentEnvFilePath = writeDetachedSessionParentEnvFile(cwd, sessionId, codexEnvWithNotify);
|
|
3838
4035
|
}
|
|
3839
|
-
const bootstrapSteps = buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw, nativeWindows, sessionId, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, omxRootOverride,
|
|
4036
|
+
const bootstrapSteps = buildDetachedSessionBootstrapSteps(sessionName, cwd, codexCmd, hudCmd, workerLaunchArgs, codexHomeOverride, notifyTempContractRaw, nativeWindows, sessionId, projectLocalCodexHomeForCleanup, runtimeCodexHomeForCleanup, omxRootOverride, runtimeHookEnv, sqliteHomeOverride, detachedParentEnvFilePath, inheritedWorkerModel);
|
|
3840
4037
|
for (const step of bootstrapSteps) {
|
|
3841
4038
|
const output = execTmuxFileSync(step.args, {
|
|
3842
4039
|
stdio: "pipe",
|
|
@@ -3853,9 +4050,10 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, s
|
|
|
3853
4050
|
version: 1,
|
|
3854
4051
|
context_key: contextKey,
|
|
3855
4052
|
created_at: new Date().toISOString(),
|
|
3856
|
-
source_cwd: process.env.OMX_SOURCE_CWD
|
|
4053
|
+
source_cwd: runtimeContext?.sourceCwd ?? process.env.OMX_SOURCE_CWD ?? cwd,
|
|
4054
|
+
...(runtimeContext?.worktreeCwd ? { worktree_cwd: runtimeContext.worktreeCwd } : {}),
|
|
3857
4055
|
argv: args,
|
|
3858
|
-
run_dir: process.env.OMX_ROOT
|
|
4056
|
+
run_dir: runtimeContext?.omxRoot ?? process.env.OMX_ROOT ?? cwd,
|
|
3859
4057
|
tmux_session_name: sessionName,
|
|
3860
4058
|
session_id: sessionId,
|
|
3861
4059
|
tmux_pane_id: leaderPaneId,
|
|
@@ -3924,6 +4122,7 @@ function runCodex(cwd, args, sessionId, workerDefaultModel, codexHomeOverride, s
|
|
|
3924
4122
|
sessionId,
|
|
3925
4123
|
omxBin,
|
|
3926
4124
|
omxRootOverride,
|
|
4125
|
+
baseEnv: runtimeHookEnv,
|
|
3927
4126
|
});
|
|
3928
4127
|
}
|
|
3929
4128
|
}
|
|
@@ -4663,6 +4862,7 @@ async function listHookVisibleRunDirStateRefs(cwd) {
|
|
|
4663
4862
|
return;
|
|
4664
4863
|
const record = raw;
|
|
4665
4864
|
const sourceCwd = typeof record.source_cwd === "string" ? record.source_cwd.trim() : "";
|
|
4865
|
+
const worktreeCwd = typeof record.worktree_cwd === "string" ? record.worktree_cwd.trim() : "";
|
|
4666
4866
|
const runDir = typeof record.run_dir === "string"
|
|
4667
4867
|
? record.run_dir.trim()
|
|
4668
4868
|
: typeof record.cwd === "string"
|
|
@@ -4671,7 +4871,8 @@ async function listHookVisibleRunDirStateRefs(cwd) {
|
|
|
4671
4871
|
if (!sourceCwd || !runDir)
|
|
4672
4872
|
return;
|
|
4673
4873
|
try {
|
|
4674
|
-
if (canonicalizePathForRunDirMatch(sourceCwd) !== canonicalCwd
|
|
4874
|
+
if (canonicalizePathForRunDirMatch(sourceCwd) !== canonicalCwd &&
|
|
4875
|
+
(!worktreeCwd || canonicalizePathForRunDirMatch(worktreeCwd) !== canonicalCwd))
|
|
4675
4876
|
return;
|
|
4676
4877
|
const resolvedRunDir = resolve(runDir);
|
|
4677
4878
|
if (resolvedRunDir !== canonicalRunsRoot
|