@virtengine/openfleet 0.25.0 → 0.26.2

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/.env.example CHANGED
@@ -109,7 +109,7 @@ TELEGRAM_MINIAPP_ENABLED=false
109
109
  # Keep Telegram command availability even when openfleet is down.
110
110
  # Sentinel can auto-restart monitor, detect crash loops, and run repair-agent.
111
111
  # Auto-start sentinel whenever openfleet starts (default: disabled)
112
- # CODEX_MONITOR_SENTINEL_AUTO_START=true
112
+ # OPENFLEET_SENTINEL_AUTO_START=true
113
113
  # Auto-restart monitor when sentinel detects monitor down/crash (default: 1)
114
114
  # SENTINEL_AUTO_RESTART_MONITOR=true
115
115
  # Crash-loop threshold within rolling window (default: 3)
@@ -322,9 +322,9 @@ TELEGRAM_MINIAPP_ENABLED=false
322
322
  # Auto-assign task creator/login when creating issues (default: true)
323
323
  # GITHUB_AUTO_ASSIGN_CREATOR=true
324
324
  # Codex task scoping label policy (only matching labels are picked by openfleet)
325
- # CODEX_MONITOR_TASK_LABEL=openfleet
326
- # CODEX_MONITOR_TASK_LABELS=openfleet,codex-mointor
327
- # CODEX_MONITOR_ENFORCE_TASK_LABEL=true
325
+ # OPENFLEET_TASK_LABEL=openfleet
326
+ # OPENFLEET_TASK_LABELS=openfleet,codex-mointor
327
+ # OPENFLEET_ENFORCE_TASK_LABEL=true
328
328
  # Optional issue fetch cap per sync/poll cycle (default: 1000)
329
329
  # GITHUB_ISSUES_LIST_LIMIT=1000
330
330
 
@@ -427,12 +427,12 @@ TELEGRAM_MINIAPP_ENABLED=false
427
427
  # PID file: .cache/openfleet.pid
428
428
  # Logs: logs/daemon.log
429
429
  # Daemon crash supervision (monitor child):
430
- # CODEX_MONITOR_DAEMON_RESTART_DELAY_MS=5000
431
- # CODEX_MONITOR_DAEMON_MAX_RESTARTS=0 # 0 = unlimited
430
+ # OPENFLEET_DAEMON_RESTART_DELAY_MS=5000
431
+ # OPENFLEET_DAEMON_MAX_RESTARTS=0 # 0 = unlimited
432
432
  # Consider any crash within this window as an instant startup failure (default: 15000)
433
- # CODEX_MONITOR_DAEMON_INSTANT_CRASH_WINDOW_MS=15000
433
+ # OPENFLEET_DAEMON_INSTANT_CRASH_WINDOW_MS=15000
434
434
  # Stop auto-restarts after this many instant failures in a row (default: 3)
435
- # CODEX_MONITOR_DAEMON_MAX_INSTANT_RESTARTS=3
435
+ # OPENFLEET_DAEMON_MAX_INSTANT_RESTARTS=3
436
436
 
437
437
  # ─── Vibe-Kanban ──────────────────────────────────────────────────────────────
438
438
  # Base URL for the Vibe-Kanban API (default: http://127.0.0.1:54089)
@@ -492,7 +492,7 @@ VK_RECOVERY_PORT=54089
492
492
  # Target branch for PR checks/merge (default: origin/main)
493
493
  # VK_TARGET_BRANCH=origin/main
494
494
  # Default upstream/base branch for openfleet tasks (overrides VK_TARGET_BRANCH)
495
- # CODEX_MONITOR_TASK_UPSTREAM=origin/ve/openfleet-generic
495
+ # OPENFLEET_TASK_UPSTREAM=origin/ve/openfleet-generic
496
496
 
497
497
  # ─── Codex / AI Provider ─────────────────────────────────────────────────────
498
498
  # The Codex SDK uses OpenAI-compatible configuration that has been setup in ~/.codex/config.toml -
@@ -544,39 +544,39 @@ VK_RECOVERY_PORT=54089
544
544
  #
545
545
  # Hook profile for setup/non-interactive runs:
546
546
  # strict | balanced | lightweight | none
547
- # CODEX_MONITOR_HOOK_PROFILE=strict
547
+ # OPENFLEET_HOOK_PROFILE=strict
548
548
  #
549
549
  # Which agents should receive generated hook files (comma-separated):
550
550
  # codex,claude,copilot
551
- # CODEX_MONITOR_HOOK_TARGETS=codex,claude,copilot
551
+ # OPENFLEET_HOOK_TARGETS=codex,claude,copilot
552
552
  #
553
553
  # Set to false to skip hook scaffolding during setup.
554
- # CODEX_MONITOR_HOOKS_ENABLED=true
554
+ # OPENFLEET_HOOKS_ENABLED=true
555
555
  # Set to true to overwrite existing generated hook files.
556
- # CODEX_MONITOR_HOOKS_OVERWRITE=false
556
+ # OPENFLEET_HOOKS_OVERWRITE=false
557
557
  # Optional overrides for generated bridge command tokens.
558
558
  # Defaults are portable across workstations:
559
559
  # node scripts/openfleet/agent-hook-bridge.mjs
560
- # CODEX_MONITOR_HOOK_NODE_BIN=node
561
- # CODEX_MONITOR_HOOK_BRIDGE_PATH=scripts/openfleet/agent-hook-bridge.mjs
560
+ # OPENFLEET_HOOK_NODE_BIN=node
561
+ # OPENFLEET_HOOK_BRIDGE_PATH=scripts/openfleet/agent-hook-bridge.mjs
562
562
  #
563
563
  # Optional per-event command overrides (separate multiple commands with ';;').
564
564
  # Use value 'none' to disable that event in generated .codex/hooks.json.
565
- # CODEX_MONITOR_HOOK_PREPUSH=go vet ./...;;go build ./...
566
- # CODEX_MONITOR_HOOK_PRECOMMIT=gofmt -l .
567
- # CODEX_MONITOR_HOOK_TASK_COMPLETE=echo \"task completed\"
568
- # CODEX_MONITOR_HOOK_SESSION_START=echo \"session start\"
569
- # CODEX_MONITOR_HOOK_SESSION_STOP=echo \"session stop\"
565
+ # OPENFLEET_HOOK_PREPUSH=go vet ./...;;go build ./...
566
+ # OPENFLEET_HOOK_PRECOMMIT=gofmt -l .
567
+ # OPENFLEET_HOOK_TASK_COMPLETE=echo \"task completed\"
568
+ # OPENFLEET_HOOK_SESSION_START=echo \"session start\"
569
+ # OPENFLEET_HOOK_SESSION_STOP=echo \"session stop\"
570
570
  #
571
571
  # Built-in hook behavior inside openfleet runtime:
572
572
  # force (default), auto, off
573
- # CODEX_MONITOR_HOOKS_BUILTINS_MODE=force
574
- # CODEX_MONITOR_HOOKS_DISABLE_PREPUSH=false
575
- # CODEX_MONITOR_HOOKS_DISABLE_TASK_COMPLETE=false
576
- # CODEX_MONITOR_HOOKS_DISABLE_HEALTH_CHECK=false
573
+ # OPENFLEET_HOOKS_BUILTINS_MODE=force
574
+ # OPENFLEET_HOOKS_DISABLE_PREPUSH=false
575
+ # OPENFLEET_HOOKS_DISABLE_TASK_COMPLETE=false
576
+ # OPENFLEET_HOOKS_DISABLE_HEALTH_CHECK=false
577
577
 
578
578
  # Force hooks to fire even for non-managed sessions (debug only):
579
- # CODEX_MONITOR_HOOKS_FORCE=false
579
+ # OPENFLEET_HOOKS_FORCE=false
580
580
 
581
581
  # VE_MANAGED is auto-set by openfleet at startup. Agent hook bridge
582
582
  # scripts check for this and exit silently if not present, preventing
@@ -735,11 +735,15 @@ COMPLEXITY_ROUTING_ENABLED=true
735
735
  # COMPLEXITY_ROUTING_CODEX_LOW_REASONING=low
736
736
  # COMPLEXITY_ROUTING_CODEX_MEDIUM_MODEL=gpt-5.2-codex
737
737
  # COMPLEXITY_ROUTING_CODEX_MEDIUM_VARIANT=DEFAULT
738
+ # COMPLEXITY_ROUTING_CODEX_MEDIUM_REASONING=medium
738
739
  # COMPLEXITY_ROUTING_CODEX_HIGH_MODEL=gpt-5.1-codex-max
739
740
  # COMPLEXITY_ROUTING_CODEX_HIGH_VARIANT=GPT51_CODEX_MAX
740
- # COMPLEXITY_ROUTING_COPILOT_LOW_MODEL=haiku-4.5
741
- # COMPLEXITY_ROUTING_COPILOT_MEDIUM_MODEL=sonnet-4.5
742
- # COMPLEXITY_ROUTING_COPILOT_HIGH_MODEL=opus-4.6
741
+ # COMPLEXITY_ROUTING_CODEX_HIGH_REASONING=high
742
+ # COMPLEXITY_ROUTING_COPILOT_LOW_MODEL=claude-haiku-4.5
743
+ # COMPLEXITY_ROUTING_COPILOT_MEDIUM_MODEL=claude-sonnet-4.5
744
+ # COMPLEXITY_ROUTING_COPILOT_MEDIUM_REASONING=medium
745
+ # COMPLEXITY_ROUTING_COPILOT_HIGH_MODEL=claude-opus-4.6
746
+ # COMPLEXITY_ROUTING_COPILOT_HIGH_REASONING=high
743
747
 
744
748
  # ─── Shared Cloud Workspaces ────────────────────────────────────────────────
745
749
  # Registry file for shared workspace leasing (default: .cache/openfleet/shared-workspaces.json)
@@ -812,11 +816,11 @@ COPILOT_CLOUD_DISABLED=true
812
816
  # .openfleet/agents/*.md
813
817
  # Files in that folder are loaded automatically and are intended for per-project customization.
814
818
  # You can also override any prompt path explicitly with env vars:
815
- # CODEX_MONITOR_PROMPT_PLANNER=.openfleet/agents/task-planner.md
816
- # CODEX_MONITOR_PROMPT_MONITOR_MONITOR=.openfleet/agents/monitor-monitor.md
817
- # CODEX_MONITOR_PROMPT_TASK_EXECUTOR=.openfleet/agents/task-executor.md
818
- # CODEX_MONITOR_PROMPT_REVIEWER=.openfleet/agents/reviewer.md
819
- # CODEX_MONITOR_PROMPT_SDK_CONFLICT_RESOLVER=.openfleet/agents/sdk-conflict-resolver.md
819
+ # OPENFLEET_PROMPT_PLANNER=.openfleet/agents/task-planner.md
820
+ # OPENFLEET_PROMPT_MONITOR_MONITOR=.openfleet/agents/monitor-monitor.md
821
+ # OPENFLEET_PROMPT_TASK_EXECUTOR=.openfleet/agents/task-executor.md
822
+ # OPENFLEET_PROMPT_REVIEWER=.openfleet/agents/reviewer.md
823
+ # OPENFLEET_PROMPT_SDK_CONFLICT_RESOLVER=.openfleet/agents/sdk-conflict-resolver.md
820
824
 
821
825
  # ─── Dependabot / Bot PR Auto-Merge ───────────────────────────────────────────
822
826
  # Auto-merge Dependabot (and other bot) PRs after all CI checks pass.
@@ -860,7 +864,7 @@ COPILOT_CLOUD_DISABLED=true
860
864
 
861
865
  # ─── Advanced ─────────────────────────────────────────────────────────────────
862
866
  # Override openfleet config directory (where .env and config live)
863
- # CODEX_MONITOR_DIR=/path/to/scripts/openfleet
867
+ # OPENFLEET_DIR=/path/to/scripts/openfleet
864
868
  # Max orchestrator restarts (0 = unlimited)
865
869
  # MAX_RESTARTS=0
866
870
  # Restart delay in milliseconds
@@ -166,7 +166,7 @@ async function run() {
166
166
  // openfleet sets VE_MANAGED=1 in all spawned agent environments.
167
167
  // If this env var is missing, we're running inside a standalone agent session
168
168
  // that just happens to have the hook files in its config — exit silently.
169
- if (!process.env.VE_MANAGED && !process.env.CODEX_MONITOR_HOOKS_FORCE) {
169
+ if (!process.env.VE_MANAGED && !process.env.OPENFLEET_HOOKS_FORCE) {
170
170
  process.exit(0);
171
171
  }
172
172
 
package/agent-hooks.mjs CHANGED
@@ -617,7 +617,7 @@ export async function executeBlockingHooks(event, context = {}) {
617
617
  export function registerBuiltinHooks(options = {}) {
618
618
  const modeRaw =
619
619
  options.mode ??
620
- process.env.CODEX_MONITOR_HOOKS_BUILTINS_MODE ??
620
+ process.env.OPENFLEET_HOOKS_BUILTINS_MODE ??
621
621
  process.env.VE_HOOK_BUILTINS_MODE ??
622
622
  "force";
623
623
  const mode = String(modeRaw).trim().toLowerCase();
@@ -633,12 +633,12 @@ export function registerBuiltinHooks(options = {}) {
633
633
  (hook) => !hook.builtin,
634
634
  );
635
635
  const skipPrePush =
636
- envFlag("CODEX_MONITOR_HOOKS_DISABLE_PREPUSH", false) ||
636
+ envFlag("OPENFLEET_HOOKS_DISABLE_PREPUSH", false) ||
637
637
  envFlag("VE_HOOK_DISABLE_PREPUSH", false) ||
638
638
  (mode === "auto" && hasCustomPrePush);
639
639
  const skipTaskComplete =
640
- envFlag("CODEX_MONITOR_HOOKS_DISABLE_TASK_COMPLETE", false) ||
641
- envFlag("CODEX_MONITOR_HOOKS_DISABLE_VALIDATION", false) ||
640
+ envFlag("OPENFLEET_HOOKS_DISABLE_TASK_COMPLETE", false) ||
641
+ envFlag("OPENFLEET_HOOKS_DISABLE_VALIDATION", false) ||
642
642
  envFlag("VE_HOOK_DISABLE_TASK_COMPLETE", false) ||
643
643
  (mode === "auto" && hasCustomTaskComplete);
644
644
 
@@ -680,7 +680,7 @@ export function registerBuiltinHooks(options = {}) {
680
680
  // ── SessionStart: worktree health check ──
681
681
  // Verifies the worktree directory exists, is a valid git repo,
682
682
  // and the expected branch is checked out. Retryable for transient git issues.
683
- const skipHealthCheck = envFlag("CODEX_MONITOR_HOOKS_DISABLE_HEALTH_CHECK", false);
683
+ const skipHealthCheck = envFlag("OPENFLEET_HOOKS_DISABLE_HEALTH_CHECK", false);
684
684
  if (!skipHealthCheck) {
685
685
  const healthCmd = IS_WINDOWS
686
686
  ? 'powershell -NoProfile -Command "if (-not (Test-Path .git)) { if (-not (git rev-parse --git-dir 2>$null)) { Write-Error \'Not a git repository\'; exit 1 } }; git status --porcelain 2>&1 | Out-Null; if ($LASTEXITCODE -ne 0) { Write-Error \'git status failed\'; exit 1 }; Write-Host \'OK: worktree healthy\'"'
package/agent-prompts.mjs CHANGED
@@ -119,7 +119,7 @@ export const AGENT_PROMPT_DEFINITIONS = Object.freeze(
119
119
  PROMPT_DEFS.map((item) =>
120
120
  Object.freeze({
121
121
  ...item,
122
- envVar: `CODEX_MONITOR_PROMPT_${toEnvSuffix(item.key)}`,
122
+ envVar: `OPENFLEET_PROMPT_${toEnvSuffix(item.key)}`,
123
123
  defaultRelativePath: `${PROMPT_WORKSPACE_DIR}/${item.filename}`,
124
124
  }),
125
125
  ),
@@ -562,7 +562,7 @@ export function getAgentPromptDefinitions() {
562
562
 
563
563
  export function getDefaultPromptWorkspace(repoRoot) {
564
564
  const override = String(
565
- process.env.CODEX_MONITOR_PROMPT_WORKSPACE || "",
565
+ process.env.OPENFLEET_PROMPT_WORKSPACE || "",
566
566
  ).trim();
567
567
  if (override) {
568
568
  return isAbsolute(override)
@@ -607,13 +607,13 @@ export function ensureAgentPromptWorkspace(repoRoot) {
607
607
  mkdirSync(workspaceDir, { recursive: true });
608
608
  } catch (err) {
609
609
  const fallbackRoot = resolve(
610
- process.env.CODEX_MONITOR_HOME ||
610
+ process.env.OPENFLEET_HOME ||
611
611
  process.env.HOME ||
612
612
  process.env.USERPROFILE ||
613
613
  homedir(),
614
614
  );
615
615
  const fallbackDir = resolve(fallbackRoot, PROMPT_WORKSPACE_DIR);
616
- process.env.CODEX_MONITOR_PROMPT_WORKSPACE = fallbackDir;
616
+ process.env.OPENFLEET_PROMPT_WORKSPACE = fallbackDir;
617
617
  workspaceDir = fallbackDir;
618
618
  mkdirSync(workspaceDir, { recursive: true });
619
619
  console.warn(
package/cli.mjs CHANGED
@@ -140,9 +140,9 @@ function showHelp() {
140
140
  5. Built-in defaults
141
141
 
142
142
  Auto-update environment variables:
143
- CODEX_MONITOR_SKIP_UPDATE_CHECK=1 Disable startup version check
144
- CODEX_MONITOR_SKIP_AUTO_UPDATE=1 Disable background polling
145
- CODEX_MONITOR_UPDATE_INTERVAL_MS=N Override poll interval (default: 600000)
143
+ OPENFLEET_SKIP_UPDATE_CHECK=1 Disable startup version check
144
+ OPENFLEET_SKIP_AUTO_UPDATE=1 Disable background polling
145
+ OPENFLEET_UPDATE_INTERVAL_MS=N Override poll interval (default: 600000)
146
146
 
147
147
  See .env.example for all environment variables.
148
148
 
@@ -199,23 +199,23 @@ const SENTINEL_SCRIPT_PATH = fileURLToPath(
199
199
  new URL("./telegram-sentinel.mjs", import.meta.url),
200
200
  );
201
201
  const IS_DAEMON_CHILD =
202
- args.includes("--daemon-child") || process.env.CODEX_MONITOR_DAEMON === "1";
202
+ args.includes("--daemon-child") || process.env.OPENFLEET_DAEMON === "1";
203
203
  const DAEMON_RESTART_DELAY_MS = Math.max(
204
204
  1000,
205
- Number(process.env.CODEX_MONITOR_DAEMON_RESTART_DELAY_MS || 5000) || 5000,
205
+ Number(process.env.OPENFLEET_DAEMON_RESTART_DELAY_MS || 5000) || 5000,
206
206
  );
207
207
  const DAEMON_MAX_RESTARTS = Math.max(
208
208
  0,
209
- Number(process.env.CODEX_MONITOR_DAEMON_MAX_RESTARTS || 0) || 0,
209
+ Number(process.env.OPENFLEET_DAEMON_MAX_RESTARTS || 0) || 0,
210
210
  );
211
211
  const DAEMON_INSTANT_CRASH_WINDOW_MS = Math.max(
212
212
  1000,
213
- Number(process.env.CODEX_MONITOR_DAEMON_INSTANT_CRASH_WINDOW_MS || 15000) ||
213
+ Number(process.env.OPENFLEET_DAEMON_INSTANT_CRASH_WINDOW_MS || 15000) ||
214
214
  15000,
215
215
  );
216
216
  const DAEMON_MAX_INSTANT_RESTARTS = Math.max(
217
217
  1,
218
- Number(process.env.CODEX_MONITOR_DAEMON_MAX_INSTANT_RESTARTS || 3) || 3,
218
+ Number(process.env.OPENFLEET_DAEMON_MAX_INSTANT_RESTARTS || 3) || 3,
219
219
  );
220
220
  let daemonRestartCount = 0;
221
221
  const daemonCrashTracker = createDaemonCrashTracker({
@@ -283,7 +283,7 @@ async function ensureSentinelRunning(options = {}) {
283
283
  windowsHide: process.platform === "win32",
284
284
  env: {
285
285
  ...process.env,
286
- CODEX_MONITOR_SENTINEL_COMPANION: "1",
286
+ OPENFLEET_SENTINEL_COMPANION: "1",
287
287
  },
288
288
  cwd: process.cwd(),
289
289
  });
@@ -380,7 +380,7 @@ function startDaemon() {
380
380
  detached: true,
381
381
  stdio: "ignore",
382
382
  windowsHide: process.platform === "win32",
383
- env: { ...process.env, CODEX_MONITOR_DAEMON: "1" },
383
+ env: { ...process.env, OPENFLEET_DAEMON: "1" },
384
384
  cwd: process.cwd(),
385
385
  },
386
386
  );
@@ -510,7 +510,7 @@ async function main() {
510
510
  // Write PID file if running as daemon child
511
511
  if (
512
512
  args.includes("--daemon-child") ||
513
- process.env.CODEX_MONITOR_DAEMON === "1"
513
+ process.env.OPENFLEET_DAEMON === "1"
514
514
  ) {
515
515
  writePidFile(process.pid);
516
516
  // Redirect console to log file on daemon child
@@ -556,15 +556,15 @@ async function main() {
556
556
 
557
557
  const sentinelRequested =
558
558
  args.includes("--sentinel") ||
559
- parseBoolEnv(process.env.CODEX_MONITOR_SENTINEL_AUTO_START, false);
559
+ parseBoolEnv(process.env.OPENFLEET_SENTINEL_AUTO_START, false);
560
560
  if (sentinelRequested) {
561
561
  const sentinel = await ensureSentinelRunning({ quiet: false });
562
562
  if (!sentinel.ok) {
563
563
  const mode = args.includes("--sentinel")
564
564
  ? "requested by --sentinel"
565
- : "requested by CODEX_MONITOR_SENTINEL_AUTO_START";
565
+ : "requested by OPENFLEET_SENTINEL_AUTO_START";
566
566
  const strictSentinel = parseBoolEnv(
567
- process.env.CODEX_MONITOR_SENTINEL_STRICT,
567
+ process.env.OPENFLEET_SENTINEL_STRICT,
568
568
  false,
569
569
  );
570
570
  const prefix = strictSentinel ? "✖" : "⚠";
@@ -649,7 +649,7 @@ async function main() {
649
649
 
650
650
  // Propagate --no-auto-update to env for monitor.mjs to pick up
651
651
  if (args.includes("--no-auto-update")) {
652
- process.env.CODEX_MONITOR_SKIP_AUTO_UPDATE = "1";
652
+ process.env.OPENFLEET_SKIP_AUTO_UPDATE = "1";
653
653
  }
654
654
 
655
655
  // Mark all child processes as openfleet managed.
@@ -661,7 +661,7 @@ async function main() {
661
661
  if (args.includes("--setup") || args.includes("setup")) {
662
662
  const configDirArg = getArgValue("--config-dir");
663
663
  if (configDirArg) {
664
- process.env.CODEX_MONITOR_DIR = configDirArg;
664
+ process.env.OPENFLEET_DIR = configDirArg;
665
665
  }
666
666
  const { runSetup } = await import("./setup.mjs");
667
667
  await runSetup();
@@ -682,13 +682,75 @@ async function main() {
682
682
  console.log("\n 🚀 First run detected — launching setup wizard...\n");
683
683
  const configDirArg = getArgValue("--config-dir");
684
684
  if (configDirArg) {
685
- process.env.CODEX_MONITOR_DIR = configDirArg;
685
+ process.env.OPENFLEET_DIR = configDirArg;
686
686
  }
687
687
  const { runSetup } = await import("./setup.mjs");
688
688
  await runSetup();
689
689
  console.log("\n Setup complete! Starting openfleet...\n");
690
690
  }
691
691
 
692
+ // ── Handle --echo-logs: tail the active monitor's log instead of spawning a new instance ──
693
+ if (args.includes("--echo-logs")) {
694
+ // Search for the monitor PID file in common cache locations
695
+ const candidatePidFiles = [
696
+ process.env.OPENFLEET_DIR
697
+ ? resolve(process.env.OPENFLEET_DIR, ".cache", "openfleet.pid")
698
+ : null,
699
+ resolve(__dirname, "..", ".cache", "openfleet.pid"),
700
+ resolve(process.cwd(), ".cache", "openfleet.pid"),
701
+ ].filter(Boolean);
702
+
703
+ let activePidFile = null;
704
+ for (const f of candidatePidFiles) {
705
+ if (existsSync(f)) {
706
+ activePidFile = f;
707
+ break;
708
+ }
709
+ }
710
+
711
+ if (activePidFile) {
712
+ try {
713
+ const pidData = JSON.parse(readFileSync(activePidFile, "utf8"));
714
+ const monitorPid = Number(pidData.pid);
715
+ const monitorPath = (pidData.argv || [])[1] || "";
716
+
717
+ let isAlive = false;
718
+ try {
719
+ process.kill(monitorPid, 0);
720
+ isAlive = true;
721
+ } catch {}
722
+
723
+ if (isAlive && monitorPath) {
724
+ const logDir = resolve(dirname(monitorPath), "logs");
725
+ const daemonLog = resolve(logDir, "daemon.log");
726
+ const monitorLog = resolve(logDir, "monitor.log");
727
+ const logFile = existsSync(daemonLog) ? daemonLog : monitorLog;
728
+
729
+ if (existsSync(logFile)) {
730
+ console.log(
731
+ `\n Tailing logs for active openfleet (PID ${monitorPid}):\n ${logFile}\n`,
732
+ );
733
+ await new Promise((res) => {
734
+ const tail = spawn("tail", ["-f", "-n", "200", logFile], {
735
+ stdio: "inherit",
736
+ });
737
+ tail.on("exit", res);
738
+ process.on("SIGINT", () => {
739
+ tail.kill();
740
+ res();
741
+ });
742
+ });
743
+ process.exit(0);
744
+ }
745
+ }
746
+ } catch {
747
+ // best-effort — fall through to normal start
748
+ }
749
+ }
750
+
751
+ // No active monitor found — start normally; echoLogs will be picked up by config.mjs
752
+ }
753
+
692
754
  // Fork monitor as a child process — enables self-restart on source changes.
693
755
  // When monitor exits with code 75, cli re-forks with a fresh ESM module cache.
694
756
  await runMonitor();
package/config-doctor.mjs CHANGED
@@ -82,7 +82,7 @@ function isWslInteropRuntime() {
82
82
  }
83
83
 
84
84
  function resolveConfigDir(repoRoot) {
85
- const explicit = process.env.CODEX_MONITOR_DIR;
85
+ const explicit = process.env.OPENFLEET_DIR;
86
86
  if (explicit) return resolve(explicit);
87
87
 
88
88
  const repoPath = resolve(repoRoot || process.cwd());
package/config.mjs CHANGED
@@ -726,7 +726,7 @@ export function loadConfig(argv = process.argv, options = {}) {
726
726
  // Determine config directory (where openfleet stores its config)
727
727
  const configDir =
728
728
  cli["config-dir"] ||
729
- process.env.CODEX_MONITOR_DIR ||
729
+ process.env.OPENFLEET_DIR ||
730
730
  resolveConfigDir(repoRootForConfig);
731
731
 
732
732
  const configFile = loadConfigFile(configDir);
@@ -740,8 +740,8 @@ export function loadConfig(argv = process.argv, options = {}) {
740
740
  const repoSelection =
741
741
  cli["repo-name"] ||
742
742
  cli.repository ||
743
- process.env.CODEX_MONITOR_REPO ||
744
- process.env.CODEX_MONITOR_REPO_NAME ||
743
+ process.env.OPENFLEET_REPO ||
744
+ process.env.OPENFLEET_REPO_NAME ||
745
745
  process.env.REPO_NAME ||
746
746
  configData.defaultRepository ||
747
747
  configData.defaultRepo ||
@@ -774,8 +774,8 @@ export function loadConfig(argv = process.argv, options = {}) {
774
774
  (profiles.default ? "default" : "");
775
775
  const profileName =
776
776
  cli.profile ||
777
- process.env.CODEX_MONITOR_PROFILE ||
778
- process.env.CODEX_MONITOR_ENV_PROFILE ||
777
+ process.env.OPENFLEET_PROFILE ||
778
+ process.env.OPENFLEET_ENV_PROFILE ||
779
779
  selectedRepository?.profile ||
780
780
  selectedRepository?.envProfile ||
781
781
  defaultProfile ||
@@ -838,7 +838,7 @@ export function loadConfig(argv = process.argv, options = {}) {
838
838
  const mode =
839
839
  (
840
840
  cli.mode ||
841
- process.env.CODEX_MONITOR_MODE ||
841
+ process.env.OPENFLEET_MODE ||
842
842
  configData.mode ||
843
843
  selectedRepository?.mode ||
844
844
  ""
@@ -943,20 +943,20 @@ export function loadConfig(argv = process.argv, options = {}) {
943
943
  const interactiveShellEnabled =
944
944
  flags.has("shell") ||
945
945
  flags.has("interactive") ||
946
- isEnvEnabled(process.env.CODEX_MONITOR_SHELL, false) ||
947
- isEnvEnabled(process.env.CODEX_MONITOR_INTERACTIVE, false) ||
946
+ isEnvEnabled(process.env.OPENFLEET_SHELL, false) ||
947
+ isEnvEnabled(process.env.OPENFLEET_INTERACTIVE, false) ||
948
948
  configData.interactiveShellEnabled === true ||
949
949
  configData.shellEnabled === true;
950
950
  const preflightEnabled = flags.has("no-preflight")
951
951
  ? false
952
952
  : configData.preflightEnabled !== undefined
953
953
  ? configData.preflightEnabled
954
- : isEnvEnabled(process.env.CODEX_MONITOR_PREFLIGHT_DISABLED, false)
954
+ : isEnvEnabled(process.env.OPENFLEET_PREFLIGHT_DISABLED, false)
955
955
  ? false
956
956
  : true;
957
957
  const preflightRetryMs = Number(
958
958
  cli["preflight-retry"] ||
959
- process.env.CODEX_MONITOR_PREFLIGHT_RETRY_MS ||
959
+ process.env.OPENFLEET_PREFLIGHT_RETRY_MS ||
960
960
  configData.preflightRetryMs ||
961
961
  "300000",
962
962
  );
@@ -1656,7 +1656,7 @@ function detectProjectName(configDir, repoRoot) {
1656
1656
  }
1657
1657
 
1658
1658
  function findOrchestratorScript(configDir, repoRoot) {
1659
- const shellModeEnv = String(process.env.CODEX_MONITOR_SHELL_MODE || "")
1659
+ const shellModeEnv = String(process.env.OPENFLEET_SHELL_MODE || "")
1660
1660
  .trim()
1661
1661
  .toLowerCase();
1662
1662
  const shellModeRequested = ["1", "true", "yes", "on"].includes(shellModeEnv);
package/hook-profiles.mjs CHANGED
@@ -11,13 +11,13 @@ const LEGACY_BRIDGE_SNIPPET = "scripts/openfleet/agent-hook-bridge.mjs";
11
11
  const DEFAULT_BRIDGE_SCRIPT_PATH = resolve(__dirname, "agent-hook-bridge.mjs");
12
12
 
13
13
  function getHookNodeBinary() {
14
- const configured = String(process.env.CODEX_MONITOR_HOOK_NODE_BIN || "").trim();
14
+ const configured = String(process.env.OPENFLEET_HOOK_NODE_BIN || "").trim();
15
15
  return configured || "node";
16
16
  }
17
17
 
18
18
  function getHookBridgeScriptPath() {
19
19
  const configured = String(
20
- process.env.CODEX_MONITOR_HOOK_BRIDGE_PATH || "",
20
+ process.env.OPENFLEET_HOOK_BRIDGE_PATH || "",
21
21
  ).trim();
22
22
  return configured || DEFAULT_BRIDGE_SCRIPT_PATH;
23
23
  }
@@ -242,23 +242,23 @@ export function normalizeHookTargets(value) {
242
242
  }
243
243
 
244
244
  export function buildHookScaffoldOptionsFromEnv(env = process.env) {
245
- const profile = normalizeProfile(env.CODEX_MONITOR_HOOK_PROFILE);
245
+ const profile = normalizeProfile(env.OPENFLEET_HOOK_PROFILE);
246
246
  return {
247
- enabled: parseBoolean(env.CODEX_MONITOR_HOOKS_ENABLED, true),
247
+ enabled: parseBoolean(env.OPENFLEET_HOOKS_ENABLED, true),
248
248
  profile,
249
- targets: normalizeHookTargets(env.CODEX_MONITOR_HOOK_TARGETS),
250
- overwriteExisting: parseBoolean(env.CODEX_MONITOR_HOOKS_OVERWRITE, false),
249
+ targets: normalizeHookTargets(env.OPENFLEET_HOOK_TARGETS),
250
+ overwriteExisting: parseBoolean(env.OPENFLEET_HOOKS_OVERWRITE, false),
251
251
  commands: {
252
252
  SessionStart: normalizeOverrideCommands(
253
- env.CODEX_MONITOR_HOOK_SESSION_START,
253
+ env.OPENFLEET_HOOK_SESSION_START,
254
254
  ),
255
255
  SessionStop: normalizeOverrideCommands(
256
- env.CODEX_MONITOR_HOOK_SESSION_STOP,
256
+ env.OPENFLEET_HOOK_SESSION_STOP,
257
257
  ),
258
- PrePush: normalizeOverrideCommands(env.CODEX_MONITOR_HOOK_PREPUSH),
259
- PreCommit: normalizeOverrideCommands(env.CODEX_MONITOR_HOOK_PRECOMMIT),
258
+ PrePush: normalizeOverrideCommands(env.OPENFLEET_HOOK_PREPUSH),
259
+ PreCommit: normalizeOverrideCommands(env.OPENFLEET_HOOK_PRECOMMIT),
260
260
  TaskComplete: normalizeOverrideCommands(
261
- env.CODEX_MONITOR_HOOK_TASK_COMPLETE,
261
+ env.OPENFLEET_HOOK_TASK_COMPLETE,
262
262
  ),
263
263
  },
264
264
  };
@@ -545,10 +545,10 @@ function buildDisableEnv(hookConfig) {
545
545
  const hasTaskComplete = Array.isArray(hookConfig.hooks?.TaskComplete);
546
546
 
547
547
  return {
548
- CODEX_MONITOR_HOOKS_BUILTINS_MODE:
548
+ OPENFLEET_HOOKS_BUILTINS_MODE:
549
549
  hasPrePush || hasTaskComplete ? "auto" : "off",
550
- CODEX_MONITOR_HOOKS_DISABLE_PREPUSH: hasPrePush ? "0" : "1",
551
- CODEX_MONITOR_HOOKS_DISABLE_TASK_COMPLETE: hasTaskComplete ? "0" : "1",
550
+ OPENFLEET_HOOKS_DISABLE_PREPUSH: hasPrePush ? "0" : "1",
551
+ OPENFLEET_HOOKS_DISABLE_TASK_COMPLETE: hasTaskComplete ? "0" : "1",
552
552
  };
553
553
  }
554
554
 
@@ -571,9 +571,9 @@ export function scaffoldAgentHookFiles(repoRoot, options = {}) {
571
571
 
572
572
  if (!enabled) {
573
573
  result.env = {
574
- CODEX_MONITOR_HOOKS_BUILTINS_MODE: "off",
575
- CODEX_MONITOR_HOOKS_DISABLE_PREPUSH: "1",
576
- CODEX_MONITOR_HOOKS_DISABLE_TASK_COMPLETE: "1",
574
+ OPENFLEET_HOOKS_BUILTINS_MODE: "off",
575
+ OPENFLEET_HOOKS_DISABLE_PREPUSH: "1",
576
+ OPENFLEET_HOOKS_DISABLE_TASK_COMPLETE: "1",
577
577
  };
578
578
  return result;
579
579
  }
@@ -862,13 +862,13 @@ class GitHubIssuesAdapter {
862
862
  };
863
863
 
864
864
  this._canonicalTaskLabel =
865
- process.env.CODEX_MONITOR_TASK_LABEL || "openfleet";
865
+ process.env.OPENFLEET_TASK_LABEL || "openfleet";
866
866
  this._taskScopeLabels = normalizeLabels(
867
- process.env.CODEX_MONITOR_TASK_LABELS ||
867
+ process.env.OPENFLEET_TASK_LABELS ||
868
868
  `${this._canonicalTaskLabel},codex-mointor`,
869
869
  );
870
870
  this._enforceTaskLabel = parseBooleanEnv(
871
- process.env.CODEX_MONITOR_ENFORCE_TASK_LABEL,
871
+ process.env.OPENFLEET_ENFORCE_TASK_LABEL,
872
872
  true,
873
873
  );
874
874
 
@@ -3010,17 +3010,17 @@ class JiraAdapter {
3010
3010
  process.env.JIRA_SUBTASK_PARENT_KEY || "",
3011
3011
  ).trim();
3012
3012
  this._canonicalTaskLabel = String(
3013
- process.env.CODEX_MONITOR_TASK_LABEL || "openfleet",
3013
+ process.env.OPENFLEET_TASK_LABEL || "openfleet",
3014
3014
  )
3015
3015
  .trim()
3016
3016
  .toLowerCase();
3017
3017
  this._taskScopeLabels = normalizeLabels(
3018
3018
  process.env.JIRA_TASK_LABELS ||
3019
- process.env.CODEX_MONITOR_TASK_LABELS ||
3019
+ process.env.OPENFLEET_TASK_LABELS ||
3020
3020
  `${this._canonicalTaskLabel},openfleet`,
3021
3021
  ).map((label) => this._sanitizeJiraLabel(label));
3022
3022
  this._enforceTaskLabel = parseBooleanEnv(
3023
- process.env.JIRA_ENFORCE_TASK_LABEL ?? process.env.CODEX_MONITOR_ENFORCE_TASK_LABEL,
3023
+ process.env.JIRA_ENFORCE_TASK_LABEL ?? process.env.OPENFLEET_ENFORCE_TASK_LABEL,
3024
3024
  true,
3025
3025
  );
3026
3026
  this._codexLabels = {
package/monitor.mjs CHANGED
@@ -6109,9 +6109,9 @@ async function actOnAssessment(ctx, decision) {
6109
6109
  // Use config-driven branch routing instead of hardcoded defaults
6110
6110
  const DEFAULT_TARGET_BRANCH =
6111
6111
  branchRouting?.defaultBranch || process.env.VK_TARGET_BRANCH || "origin/main";
6112
- const DEFAULT_CODEX_MONITOR_UPSTREAM =
6112
+ const DEFAULT_OPENFLEET_UPSTREAM =
6113
6113
  branchRouting?.scopeMap?.["openfleet"] ||
6114
- process.env.CODEX_MONITOR_TASK_UPSTREAM ||
6114
+ process.env.OPENFLEET_TASK_UPSTREAM ||
6115
6115
  "origin/ve/openfleet-generic";
6116
6116
 
6117
6117
  /**
@@ -6303,7 +6303,7 @@ function resolveUpstreamFromTask(task) {
6303
6303
  text.includes("@virtengine/openfleet") ||
6304
6304
  text.includes("scripts/openfleet")
6305
6305
  ) {
6306
- return DEFAULT_CODEX_MONITOR_UPSTREAM;
6306
+ return DEFAULT_OPENFLEET_UPSTREAM;
6307
6307
  }
6308
6308
 
6309
6309
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@virtengine/openfleet",
3
- "version": "0.25.0",
3
+ "version": "0.26.2",
4
4
  "description": "AI-powered orchestrator supervisor — manages AI agent executors with failover, auto-restarts on failure, analyzes crashes with Codex SDK, creates PRs via Vibe-Kanban API, and sends Telegram notifications. Supports N executors with weighted distribution, multi-repo projects, and auto-setup.",
5
5
  "type": "module",
6
6
  "license": "Apache 2.0",
@@ -92,7 +92,11 @@
92
92
  "prepush:check": "npm run syntax:check && npm test",
93
93
  "prepublishOnly": "node prepublish-check.mjs",
94
94
  "publish:env": "node publish.mjs",
95
- "publish:dry-run": "node publish.mjs --dry-run"
95
+ "publish:dry-run": "node publish.mjs --dry-run",
96
+ "publish:minor": "node publish.mjs --bump minor",
97
+ "publish:major": "node publish.mjs --bump major",
98
+ "publish:minor:dry": "node publish.mjs --bump minor --dry-run",
99
+ "publish:major:dry": "node publish.mjs --bump major --dry-run"
96
100
  },
97
101
  "files": [
98
102
  ".env.example",
package/postinstall.mjs CHANGED
@@ -103,7 +103,7 @@ const RECOMMENDED = [
103
103
 
104
104
  function main() {
105
105
  // Skip in CI environments
106
- if (process.env.CI || process.env.CODEX_MONITOR_SKIP_POSTINSTALL) {
106
+ if (process.env.CI || process.env.OPENFLEET_SKIP_POSTINSTALL) {
107
107
  return;
108
108
  }
109
109
 
package/preflight.mjs CHANGED
@@ -3,7 +3,7 @@ import { resolve } from "node:path";
3
3
  import os from "node:os";
4
4
 
5
5
  const isWindows = process.platform === "win32";
6
- const MIN_FREE_GB = Number(process.env.CODEX_MONITOR_MIN_FREE_GB || "10");
6
+ const MIN_FREE_GB = Number(process.env.OPENFLEET_MIN_FREE_GB || "10");
7
7
  const MIN_FREE_BYTES = MIN_FREE_GB * 1024 * 1024 * 1024;
8
8
 
9
9
  function runCommand(command, args, options = {}) {
@@ -167,7 +167,7 @@ function isShellModeRequested() {
167
167
  .toLowerCase();
168
168
  if (script.endsWith(".sh")) return true;
169
169
  if (script.endsWith(".ps1")) return false;
170
- if (parseEnvBool(process.env.CODEX_MONITOR_SHELL_MODE, false)) return true;
170
+ if (parseEnvBool(process.env.OPENFLEET_SHELL_MODE, false)) return true;
171
171
  return !isWindows;
172
172
  }
173
173
 
package/publish.mjs CHANGED
@@ -1,7 +1,22 @@
1
1
  #!/usr/bin/env node
2
+ //
3
+ // Usage:
4
+ // node publish.mjs # publish at current version (prompts login if no token)
5
+ // node publish.mjs --bump minor # 0.25.0 → 0.25.1 (patch digit)
6
+ // node publish.mjs --bump major # 0.25.0 → 0.26.0 (minor digit)
7
+ // node publish.mjs --bump minor --dry-run
8
+ //
9
+ // To set an automation token (Linux/macOS bash — NOT setx/PowerShell):
10
+ // export NPM_ACCESS_TOKEN=npm_xxxx && node publish.mjs --bump minor
11
+ // # or inline:
12
+ // NPM_ACCESS_TOKEN=npm_xxxx npm run publish:minor
13
+ //
14
+ // Terminology matches the openfleet convention (not semver):
15
+ // minor = last digit (semver patch)
16
+ // major = middle digit (semver minor)
2
17
 
3
18
  import { spawnSync } from "node:child_process";
4
- import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
19
+ import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
5
20
  import { tmpdir } from "node:os";
6
21
  import { join, resolve } from "node:path";
7
22
  import { fileURLToPath } from "node:url";
@@ -64,8 +79,82 @@ function runCheck(label, command, args, env) {
64
79
 
65
80
  const NPM_BIN = "npm";
66
81
 
82
+ /**
83
+ * Bump the version in package.json and sync package-lock.json.
84
+ * type: "minor" → patch digit (0.25.0 → 0.25.1)
85
+ * "major" → middle digit (0.25.0 → 0.26.0)
86
+ * Returns the new version string.
87
+ */
88
+ function bumpVersion(type, dryRun) {
89
+ const pkgPath = resolve(SCRIPT_DIR, "package.json");
90
+ const lockPath = resolve(SCRIPT_DIR, "package-lock.json");
91
+
92
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
93
+ const [maj, mid, pat] = pkg.version.split(".").map(Number);
94
+
95
+ let newVersion;
96
+ if (type === "minor") {
97
+ // minor = patch digit (last number)
98
+ newVersion = `${maj}.${mid}.${pat + 1}`;
99
+ } else if (type === "major") {
100
+ // major = middle digit, reset patch
101
+ newVersion = `${maj}.${mid + 1}.0`;
102
+ } else {
103
+ console.error(
104
+ `[publish] Unknown bump type "${type}". Use "minor" (0.25.0→0.25.1) or "major" (0.25.0→0.26.0).`,
105
+ );
106
+ process.exit(1);
107
+ }
108
+
109
+ console.log(`[publish] Bumping version: ${pkg.version} → ${newVersion}`);
110
+
111
+ if (!dryRun) {
112
+ pkg.version = newVersion;
113
+ writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
114
+
115
+ // Update package-lock.json in-place
116
+ try {
117
+ const lock = JSON.parse(readFileSync(lockPath, "utf8"));
118
+ lock.version = newVersion;
119
+ if (lock.packages?.[""] != null) {
120
+ lock.packages[""].version = newVersion;
121
+ }
122
+ writeFileSync(lockPath, JSON.stringify(lock, null, 2) + "\n", "utf8");
123
+ console.log(
124
+ `[publish] package.json + package-lock.json updated to ${newVersion}`,
125
+ );
126
+ } catch {
127
+ console.warn(
128
+ "[publish] Could not update package-lock.json — regenerating...",
129
+ );
130
+ spawnSync(NPM_BIN, ["install", "--package-lock-only", "--ignore-scripts"], {
131
+ stdio: "inherit",
132
+ cwd: SCRIPT_DIR,
133
+ shell: true,
134
+ });
135
+ }
136
+ } else {
137
+ console.log(
138
+ `[publish] dry-run: would write version ${newVersion} to package.json & package-lock.json`,
139
+ );
140
+ }
141
+
142
+ return newVersion;
143
+ }
144
+
145
+ function getBumpArg() {
146
+ const idx = process.argv.indexOf("--bump");
147
+ if (idx !== -1 && process.argv[idx + 1]) return process.argv[idx + 1];
148
+ const flag = process.argv.find((a) => a.startsWith("--bump="));
149
+ if (flag) return flag.slice(7);
150
+ return null;
151
+ }
152
+
67
153
  function main() {
154
+ const bumpType = getBumpArg();
68
155
  const dryRun = hasArg("--dry-run");
156
+ if (bumpType) bumpVersion(bumpType, dryRun);
157
+
69
158
  const tag = process.env.NPM_PUBLISH_TAG || "latest";
70
159
  const otp = process.env.NPM_OTP || "";
71
160
  const access = process.env.NPM_PUBLISH_ACCESS || "public";
@@ -73,10 +162,11 @@ function main() {
73
162
  const token = process.env.NPM_ACCESS_TOKEN || process.env.NODE_AUTH_TOKEN || "";
74
163
 
75
164
  if (!dryRun && !token) {
76
- console.error(
77
- "[publish] Missing token. Set NPM_ACCESS_TOKEN (or NODE_AUTH_TOKEN) in environment. - use a 2FA Permissionless token",
165
+ console.log(
166
+ "[publish] No NPM_ACCESS_TOKEN found npm will prompt for login.",
78
167
  );
79
- process.exit(1);
168
+ } else if (!dryRun && token) {
169
+ console.log("[publish] Token found — using NPM_ACCESS_TOKEN for auth.");
80
170
  }
81
171
 
82
172
  console.log(
@@ -105,7 +195,7 @@ function main() {
105
195
  let tempConfig = null;
106
196
  try {
107
197
  const env = { ...process.env };
108
- if (!dryRun) {
198
+ if (!dryRun && token) {
109
199
  tempConfig = createEphemeralNpmrc(registry, token);
110
200
  env.NPM_CONFIG_USERCONFIG = tempConfig.npmrcPath;
111
201
  env.NODE_AUTH_TOKEN = token;
package/setup.mjs CHANGED
@@ -97,7 +97,7 @@ function isPathInside(parent, child) {
97
97
  }
98
98
 
99
99
  function resolveConfigDir(repoRoot) {
100
- const explicit = process.env.CODEX_MONITOR_DIR;
100
+ const explicit = process.env.OPENFLEET_DIR;
101
101
  if (explicit) return resolve(explicit);
102
102
  const repoPath = resolve(repoRoot || process.cwd());
103
103
  const packageDir = resolve(__dirname);
@@ -2488,7 +2488,7 @@ async function main() {
2488
2488
 
2489
2489
  const canonicalLabel = "openfleet";
2490
2490
  const existingScopeLabels = String(
2491
- process.env.CODEX_MONITOR_TASK_LABELS || "",
2491
+ process.env.OPENFLEET_TASK_LABELS || "",
2492
2492
  )
2493
2493
  .split(",")
2494
2494
  .map((entry) => entry.trim().toLowerCase())
@@ -2499,9 +2499,9 @@ async function main() {
2499
2499
  if (!existingScopeLabels.includes("codex-mointor")) {
2500
2500
  existingScopeLabels.push("codex-mointor");
2501
2501
  }
2502
- env.CODEX_MONITOR_TASK_LABEL = canonicalLabel;
2503
- env.CODEX_MONITOR_TASK_LABELS = existingScopeLabels.join(",");
2504
- env.CODEX_MONITOR_ENFORCE_TASK_LABEL = "true";
2502
+ env.OPENFLEET_TASK_LABEL = canonicalLabel;
2503
+ env.OPENFLEET_TASK_LABELS = existingScopeLabels.join(",");
2504
+ env.OPENFLEET_ENFORCE_TASK_LABEL = "true";
2505
2505
 
2506
2506
  if (githubTaskMode === "kanban") {
2507
2507
  env.GITHUB_PROJECT_OWNER =
@@ -2546,7 +2546,7 @@ async function main() {
2546
2546
  projectTitle: env.GITHUB_PROJECT_TITLE || "OpenFleet",
2547
2547
  projectOwner: env.GITHUB_PROJECT_OWNER || env.GITHUB_REPO_OWNER || "",
2548
2548
  projectNumber: env.GITHUB_PROJECT_NUMBER || "",
2549
- taskLabel: env.CODEX_MONITOR_TASK_LABEL || "openfleet",
2549
+ taskLabel: env.OPENFLEET_TASK_LABEL || "openfleet",
2550
2550
  },
2551
2551
  };
2552
2552
  info(
@@ -2789,7 +2789,7 @@ async function main() {
2789
2789
  const canonicalLabel = "openfleet";
2790
2790
  const jiraScopeLabels = String(
2791
2791
  process.env.JIRA_TASK_LABELS ||
2792
- process.env.CODEX_MONITOR_TASK_LABELS ||
2792
+ process.env.OPENFLEET_TASK_LABELS ||
2793
2793
  "",
2794
2794
  )
2795
2795
  .split(",")
@@ -2801,10 +2801,10 @@ async function main() {
2801
2801
  if (!jiraScopeLabels.includes("codex-mointor")) {
2802
2802
  jiraScopeLabels.push("codex-mointor");
2803
2803
  }
2804
- env.CODEX_MONITOR_TASK_LABEL = canonicalLabel;
2805
- env.CODEX_MONITOR_TASK_LABELS = jiraScopeLabels.join(",");
2806
- env.CODEX_MONITOR_ENFORCE_TASK_LABEL = "true";
2807
- env.JIRA_TASK_LABELS = env.CODEX_MONITOR_TASK_LABELS;
2804
+ env.OPENFLEET_TASK_LABEL = canonicalLabel;
2805
+ env.OPENFLEET_TASK_LABELS = jiraScopeLabels.join(",");
2806
+ env.OPENFLEET_ENFORCE_TASK_LABEL = "true";
2807
+ env.JIRA_TASK_LABELS = env.OPENFLEET_TASK_LABELS;
2808
2808
  env.JIRA_ENFORCE_TASK_LABEL = "true";
2809
2809
 
2810
2810
  if (hasJiraCreds) {
@@ -3244,9 +3244,9 @@ async function main() {
3244
3244
  const profileMap = ["strict", "balanced", "lightweight", "none"];
3245
3245
  let profile = "balanced";
3246
3246
  let targets = ["codex", "claude", "copilot"];
3247
- let prePushRaw = process.env.CODEX_MONITOR_HOOK_PREPUSH || "";
3248
- let preCommitRaw = process.env.CODEX_MONITOR_HOOK_PRECOMMIT || "";
3249
- let taskCompleteRaw = process.env.CODEX_MONITOR_HOOK_TASK_COMPLETE || "";
3247
+ let prePushRaw = process.env.OPENFLEET_HOOK_PREPUSH || "";
3248
+ let preCommitRaw = process.env.OPENFLEET_HOOK_PRECOMMIT || "";
3249
+ let taskCompleteRaw = process.env.OPENFLEET_HOOK_TASK_COMPLETE || "";
3250
3250
  let overwriteHooks = false;
3251
3251
 
3252
3252
  if (isAdvancedSetup) {
@@ -3294,15 +3294,15 @@ async function main() {
3294
3294
 
3295
3295
  prePushRaw = await prompt.ask(
3296
3296
  "Pre-push command override",
3297
- process.env.CODEX_MONITOR_HOOK_PREPUSH || "",
3297
+ process.env.OPENFLEET_HOOK_PREPUSH || "",
3298
3298
  );
3299
3299
  preCommitRaw = await prompt.ask(
3300
3300
  "Pre-commit command override",
3301
- process.env.CODEX_MONITOR_HOOK_PRECOMMIT || "",
3301
+ process.env.OPENFLEET_HOOK_PRECOMMIT || "",
3302
3302
  );
3303
3303
  taskCompleteRaw = await prompt.ask(
3304
3304
  "Task-complete command override",
3305
- process.env.CODEX_MONITOR_HOOK_TASK_COMPLETE || "",
3305
+ process.env.OPENFLEET_HOOK_TASK_COMPLETE || "",
3306
3306
  );
3307
3307
 
3308
3308
  overwriteHooks = await prompt.confirm(
package/task-executor.mjs CHANGED
@@ -97,7 +97,7 @@ const NO_COMMIT_MAX_COOLDOWN_MS = 2 * 60 * 60 * 1000;
97
97
  const CLAIM_CONFLICT_COMMENT_COOLDOWN_MS = 30 * 60 * 1000; // 30 minutes
98
98
  const CODEX_TASK_LABELS = (() => {
99
99
  const raw = String(
100
- process.env.CODEX_MONITOR_TASK_LABELS || "openfleet,codex-mointor",
100
+ process.env.OPENFLEET_TASK_LABELS || "openfleet,codex-mointor",
101
101
  );
102
102
  const labels = raw
103
103
  .split(",")
@@ -1010,11 +1010,11 @@ class TaskExecutor {
1010
1010
  this._claimConflictNotifiedAt = new Map();
1011
1011
  this._instanceIdExplicit =
1012
1012
  String(process.env.VE_INSTANCE_ID || "").trim() !== "" ||
1013
- String(process.env.CODEX_MONITOR_INSTANCE_ID || "").trim() !== "";
1013
+ String(process.env.OPENFLEET_INSTANCE_ID || "").trim() !== "";
1014
1014
  this._instanceId =
1015
1015
  String(
1016
1016
  process.env.VE_INSTANCE_ID ||
1017
- process.env.CODEX_MONITOR_INSTANCE_ID ||
1017
+ process.env.OPENFLEET_INSTANCE_ID ||
1018
1018
  `${os.hostname() || "host"}-${process.pid}`,
1019
1019
  ).trim() || `executor-${process.pid}`;
1020
1020
  this.taskClaimOwnerStaleTtlMs = Math.max(
package/telegram-bot.mjs CHANGED
@@ -2614,7 +2614,7 @@ async function clearWebAppMenuButton() {
2614
2614
  }
2615
2615
  }
2616
2616
 
2617
- const MENU_BUTTON_REFRESH_MS = 5 * 60 * 1000; // 5 minutes
2617
+ const MENU_BUTTON_REFRESH_MS = 60 * 1000; // 1 minute — re-sync after tunnel URL rotates
2618
2618
 
2619
2619
  async function refreshMenuButton() {
2620
2620
  const { uiUrl: currentUiUrl, webAppUrl: currentUrl } = syncUiUrlsFromServer();
@@ -1365,7 +1365,7 @@ async function startAndWaitForMonitor(reason) {
1365
1365
  {
1366
1366
  detached: true,
1367
1367
  stdio: "ignore",
1368
- env: { ...process.env, CODEX_MONITOR_DAEMON: "1" },
1368
+ env: { ...process.env, OPENFLEET_DAEMON: "1" },
1369
1369
  cwd: repoRoot,
1370
1370
  },
1371
1371
  );
@@ -104,12 +104,12 @@ export const SETTINGS_SCHEMA = [
104
104
  // ── Kanban / Tasks ─────────────────────────────────────────
105
105
  { key: "KANBAN_BACKEND", label: "Kanban Backend", category: "kanban", type: "select", defaultVal: "internal", options: ["internal", "vk", "github", "jira"], description: "Task management backend. 'internal' uses built-in store, 'github' syncs with GitHub Issues/Projects." },
106
106
  { key: "KANBAN_SYNC_POLICY", label: "Sync Policy", category: "kanban", type: "select", defaultVal: "internal-primary", options: ["internal-primary", "bidirectional"], description: "How tasks sync between internal store and external backend." },
107
- { key: "CODEX_MONITOR_TASK_LABEL", label: "Task Label", category: "kanban", type: "string", defaultVal: "openfleet", description: "GitHub label used to scope which issues are managed by Codex Monitor." },
108
- { key: "CODEX_MONITOR_ENFORCE_TASK_LABEL", label: "Enforce Task Label", category: "kanban", type: "boolean", defaultVal: true, description: "Only pick up issues that have the task label. Prevents processing unrelated issues." },
107
+ { key: "OPENFLEET_TASK_LABEL", label: "Task Label", category: "kanban", type: "string", defaultVal: "openfleet", description: "GitHub label used to scope which issues are managed by Codex Monitor." },
108
+ { key: "OPENFLEET_ENFORCE_TASK_LABEL", label: "Enforce Task Label", category: "kanban", type: "boolean", defaultVal: true, description: "Only pick up issues that have the task label. Prevents processing unrelated issues." },
109
109
  { key: "STALE_TASK_AGE_HOURS", label: "Stale Task Age", category: "kanban", type: "number", defaultVal: 3, min: 1, max: 168, unit: "hours", description: "Hours before an in-progress task with no activity is considered stale and eligible for recovery." },
110
110
  { key: "TASK_PLANNER_MODE", label: "Task Planner Mode", category: "kanban", type: "select", defaultVal: "kanban", options: ["kanban", "codex-sdk", "disabled"], description: "How the autonomous task planner operates. 'disabled' turns off automatic task generation." },
111
111
  { key: "TASK_PLANNER_DEDUP_HOURS", label: "Planner Dedup Window", category: "kanban", type: "number", defaultVal: 6, min: 1, max: 72, unit: "hours", description: "Hours to look back for duplicate task detection.", advanced: true },
112
- { key: "CODEX_MONITOR_PROMPT_PLANNER", label: "Planner Prompt Path", category: "advanced", type: "string", description: "Override the task planner prompt file path.", advanced: true },
112
+ { key: "OPENFLEET_PROMPT_PLANNER", label: "Planner Prompt Path", category: "advanced", type: "string", description: "Override the task planner prompt file path.", advanced: true },
113
113
 
114
114
  // ── GitHub / Git ─────────────────────────────────────────
115
115
  { key: "GITHUB_TOKEN", label: "GitHub Token", category: "github", type: "secret", sensitive: true, description: "Personal access token or fine-grained token for GitHub API. Required for GitHub kanban backend." },
@@ -157,7 +157,7 @@ export const SETTINGS_SCHEMA = [
157
157
  { key: "CONTAINER_CPU_LIMIT", label: "CPU Limit", category: "security", type: "string", description: "Container CPU limit (e.g., '2', '1.5'). Leave empty for no limit.", validate: "^\\d+\\.?\\d*$" },
158
158
 
159
159
  // ── Sentinel / Reliability ─────────────────────────────────
160
- { key: "CODEX_MONITOR_SENTINEL_AUTO_START", label: "Auto-Start Sentinel", category: "sentinel", type: "boolean", defaultVal: false, description: "Automatically start the sentinel watchdog on boot." },
160
+ { key: "OPENFLEET_SENTINEL_AUTO_START", label: "Auto-Start Sentinel", category: "sentinel", type: "boolean", defaultVal: false, description: "Automatically start the sentinel watchdog on boot." },
161
161
  { key: "SENTINEL_AUTO_RESTART_MONITOR", label: "Auto-Restart on Crash", category: "sentinel", type: "boolean", defaultVal: true, description: "Automatically restart the monitor process if it crashes." },
162
162
  { key: "SENTINEL_CRASH_LOOP_THRESHOLD", label: "Crash Loop Threshold", category: "sentinel", type: "number", defaultVal: 3, min: 2, max: 20, description: "Number of crashes within the window before declaring a crash loop." },
163
163
  { key: "SENTINEL_CRASH_LOOP_WINDOW_MIN", label: "Crash Loop Window", category: "sentinel", type: "number", defaultVal: 10, min: 2, max: 60, unit: "min", description: "Rolling time window for crash loop detection." },
@@ -165,11 +165,11 @@ export const SETTINGS_SCHEMA = [
165
165
  { key: "SENTINEL_REPAIR_TIMEOUT_MIN", label: "Repair Timeout", category: "sentinel", type: "number", defaultVal: 20, min: 5, max: 120, unit: "min", description: "Maximum time the repair agent can run." },
166
166
 
167
167
  // ── Agent Hooks ────────────────────────────────────────────
168
- { key: "CODEX_MONITOR_HOOK_PROFILE", label: "Hook Profile", category: "hooks", type: "select", defaultVal: "strict", options: ["strict", "balanced", "lightweight", "none"], description: "Pre-configured hook intensity. 'strict' runs all checks, 'none' disables hooks." },
169
- { key: "CODEX_MONITOR_HOOK_TARGETS", label: "Hook Targets", category: "hooks", type: "string", defaultVal: "codex,claude,copilot", description: "Comma-separated list of agent SDKs to install hooks for.", validate: "^[a-z,]+$" },
170
- { key: "CODEX_MONITOR_HOOKS_ENABLED", label: "Enable Hooks", category: "hooks", type: "boolean", defaultVal: true, description: "Enable agent lifecycle hook scaffolding." },
171
- { key: "CODEX_MONITOR_HOOKS_OVERWRITE", label: "Overwrite Existing", category: "hooks", type: "boolean", defaultVal: false, description: "Overwrite existing hook files when installing. Use with caution." },
172
- { key: "CODEX_MONITOR_HOOKS_BUILTINS_MODE", label: "Built-ins Mode", category: "hooks", type: "select", defaultVal: "force", options: ["force", "auto", "off"], description: "How built-in hooks are managed. 'force' always installs, 'auto' only if missing." },
168
+ { key: "OPENFLEET_HOOK_PROFILE", label: "Hook Profile", category: "hooks", type: "select", defaultVal: "strict", options: ["strict", "balanced", "lightweight", "none"], description: "Pre-configured hook intensity. 'strict' runs all checks, 'none' disables hooks." },
169
+ { key: "OPENFLEET_HOOK_TARGETS", label: "Hook Targets", category: "hooks", type: "string", defaultVal: "codex,claude,copilot", description: "Comma-separated list of agent SDKs to install hooks for.", validate: "^[a-z,]+$" },
170
+ { key: "OPENFLEET_HOOKS_ENABLED", label: "Enable Hooks", category: "hooks", type: "boolean", defaultVal: true, description: "Enable agent lifecycle hook scaffolding." },
171
+ { key: "OPENFLEET_HOOKS_OVERWRITE", label: "Overwrite Existing", category: "hooks", type: "boolean", defaultVal: false, description: "Overwrite existing hook files when installing. Use with caution." },
172
+ { key: "OPENFLEET_HOOKS_BUILTINS_MODE", label: "Built-ins Mode", category: "hooks", type: "select", defaultVal: "force", options: ["force", "auto", "off"], description: "How built-in hooks are managed. 'force' always installs, 'auto' only if missing." },
173
173
 
174
174
  // ── Logging / Monitoring ────────────────────────────────────
175
175
  { key: "AGENT_WORK_LOGGING_ENABLED", label: "Work Logging", category: "logging", type: "boolean", defaultVal: true, description: "Enable structured agent work logging with transcripts." },
@@ -213,7 +213,7 @@ export function getGroupedSettings(includeAdvanced = false) {
213
213
  */
214
214
  export function validateSetting(def, value) {
215
215
  if (value === "" || value == null) return { valid: true };
216
- if (def.key === "CODEX_MONITOR_HOOK_TARGETS") {
216
+ if (def.key === "OPENFLEET_HOOK_TARGETS") {
217
217
  const targets = String(value || "")
218
218
  .split(",")
219
219
  .map((entry) => entry.trim().toLowerCase())
package/ui-server.mjs CHANGED
@@ -75,8 +75,8 @@ let _configSchema = null;
75
75
  let _configValidator = null;
76
76
 
77
77
  function resolveConfigPath() {
78
- return process.env.CODEX_MONITOR_CONFIG_PATH
79
- ? resolve(process.env.CODEX_MONITOR_CONFIG_PATH)
78
+ return process.env.OPENFLEET_CONFIG_PATH
79
+ ? resolve(process.env.OPENFLEET_CONFIG_PATH)
80
80
  : resolve(__dirname, "openfleet.config.json");
81
81
  }
82
82
 
@@ -165,7 +165,7 @@ function coerceSettingValue(def, value, propSchema) {
165
165
  .split(",")
166
166
  .map((part) => part.trim())
167
167
  .filter(Boolean);
168
- if (def?.key === "CODEX_MONITOR_HOOK_TARGETS") {
168
+ if (def?.key === "OPENFLEET_HOOK_TARGETS") {
169
169
  parts = parts.map((part) => part.toLowerCase());
170
170
  if (parts.includes("all")) {
171
171
  const allowed = Array.isArray(propSchema?.items?.enum)
@@ -213,7 +213,7 @@ function getSchemaProperty(schema, pathParts) {
213
213
 
214
214
  const ROOT_SKIP_ENV_KEYS = new Set([]);
215
215
  const ROOT_OVERRIDE_MAP = {
216
- CODEX_MONITOR_MODE: "mode",
216
+ OPENFLEET_MODE: "mode",
217
217
  TASK_PLANNER_MODE: "plannerMode",
218
218
  EXECUTOR_DISTRIBUTION: "distribution",
219
219
  };
@@ -274,8 +274,8 @@ function mapEnvKeyToConfigPath(key, schema) {
274
274
  const sub = toCamelCaseFromEnv(rest);
275
275
  if (schema.properties.failover.properties[sub]) return buildConfigPath(["failover", sub]);
276
276
  }
277
- if (envKey.startsWith("CODEX_MONITOR_PROMPT_") && schema.properties.agentPrompts?.properties) {
278
- const rest = envKey.slice("CODEX_MONITOR_PROMPT_".length);
277
+ if (envKey.startsWith("OPENFLEET_PROMPT_") && schema.properties.agentPrompts?.properties) {
278
+ const rest = envKey.slice("OPENFLEET_PROMPT_".length);
279
279
  const sub = toCamelCaseFromEnv(rest);
280
280
  if (schema.properties.agentPrompts.properties[sub]) {
281
281
  return buildConfigPath(["agentPrompts", sub]);
@@ -293,10 +293,10 @@ function mapEnvKeyToConfigPath(key, schema) {
293
293
  }
294
294
  }
295
295
  const hookProfileMap = {
296
- CODEX_MONITOR_HOOK_PROFILE: ["hookProfiles", "profile"],
297
- CODEX_MONITOR_HOOK_TARGETS: ["hookProfiles", "targets"],
298
- CODEX_MONITOR_HOOKS_ENABLED: ["hookProfiles", "enabled"],
299
- CODEX_MONITOR_HOOKS_OVERWRITE: ["hookProfiles", "overwriteExisting"],
296
+ OPENFLEET_HOOK_PROFILE: ["hookProfiles", "profile"],
297
+ OPENFLEET_HOOK_TARGETS: ["hookProfiles", "targets"],
298
+ OPENFLEET_HOOKS_ENABLED: ["hookProfiles", "enabled"],
299
+ OPENFLEET_HOOKS_OVERWRITE: ["hookProfiles", "overwriteExisting"],
300
300
  };
301
301
  if (hookProfileMap[envKey]) {
302
302
  const pathParts = hookProfileMap[envKey];
@@ -470,10 +470,10 @@ const SETTINGS_KNOWN_KEYS = [
470
470
  "CODEX_MODEL_PROFILE_M_PROVIDER", "CODEX_MODEL_PROFILE_M_MODEL", "CODEX_MODEL_PROFILE_M_BASE_URL", "CODEX_MODEL_PROFILE_M_API_KEY",
471
471
  "CODEX_SUBAGENT_MODEL", "ANTHROPIC_API_KEY", "CLAUDE_MODEL",
472
472
  "COPILOT_MODEL", "COPILOT_CLI_TOKEN",
473
- "KANBAN_BACKEND", "KANBAN_SYNC_POLICY", "CODEX_MONITOR_TASK_LABEL",
474
- "CODEX_MONITOR_ENFORCE_TASK_LABEL", "STALE_TASK_AGE_HOURS",
473
+ "KANBAN_BACKEND", "KANBAN_SYNC_POLICY", "OPENFLEET_TASK_LABEL",
474
+ "OPENFLEET_ENFORCE_TASK_LABEL", "STALE_TASK_AGE_HOURS",
475
475
  "TASK_PLANNER_MODE", "TASK_PLANNER_DEDUP_HOURS",
476
- "CODEX_MONITOR_PROMPT_PLANNER",
476
+ "OPENFLEET_PROMPT_PLANNER",
477
477
  "GITHUB_TOKEN", "GITHUB_REPOSITORY", "GITHUB_PROJECT_MODE",
478
478
  "GITHUB_PROJECT_NUMBER", "GITHUB_DEFAULT_ASSIGNEE", "GITHUB_AUTO_ASSIGN_CREATOR",
479
479
  "GITHUB_PROJECT_WEBHOOK_PATH", "GITHUB_PROJECT_WEBHOOK_SECRET", "GITHUB_PROJECT_WEBHOOK_REQUIRE_SIGNATURE",
@@ -488,12 +488,12 @@ const SETTINGS_KNOWN_KEYS = [
488
488
  "CODEX_SANDBOX", "CODEX_FEATURES_BWRAP", "CODEX_SANDBOX_PERMISSIONS", "CODEX_SANDBOX_WRITABLE_ROOTS",
489
489
  "CONTAINER_ENABLED", "CONTAINER_RUNTIME", "CONTAINER_IMAGE",
490
490
  "CONTAINER_TIMEOUT_MS", "MAX_CONCURRENT_CONTAINERS", "CONTAINER_MEMORY_LIMIT", "CONTAINER_CPU_LIMIT",
491
- "CODEX_MONITOR_SENTINEL_AUTO_START", "SENTINEL_AUTO_RESTART_MONITOR",
491
+ "OPENFLEET_SENTINEL_AUTO_START", "SENTINEL_AUTO_RESTART_MONITOR",
492
492
  "SENTINEL_CRASH_LOOP_THRESHOLD", "SENTINEL_CRASH_LOOP_WINDOW_MIN",
493
493
  "SENTINEL_REPAIR_AGENT_ENABLED", "SENTINEL_REPAIR_TIMEOUT_MIN",
494
- "CODEX_MONITOR_HOOK_PROFILE", "CODEX_MONITOR_HOOK_TARGETS",
495
- "CODEX_MONITOR_HOOKS_ENABLED", "CODEX_MONITOR_HOOKS_OVERWRITE",
496
- "CODEX_MONITOR_HOOKS_BUILTINS_MODE",
494
+ "OPENFLEET_HOOK_PROFILE", "OPENFLEET_HOOK_TARGETS",
495
+ "OPENFLEET_HOOKS_ENABLED", "OPENFLEET_HOOKS_OVERWRITE",
496
+ "OPENFLEET_HOOKS_BUILTINS_MODE",
497
497
  "AGENT_WORK_LOGGING_ENABLED", "AGENT_WORK_ANALYZER_ENABLED",
498
498
  "AGENT_SESSION_LOG_RETENTION", "AGENT_ERROR_LOOP_THRESHOLD",
499
499
  "AGENT_STUCK_THRESHOLD_MS", "LOG_MAX_SIZE_MB",
package/update-check.mjs CHANGED
@@ -8,9 +8,9 @@
8
8
  * auto-installs updates and restarts the process. Zero user interaction.
9
9
  *
10
10
  * Respects:
11
- * - CODEX_MONITOR_SKIP_UPDATE_CHECK=1 — disable startup check
12
- * - CODEX_MONITOR_SKIP_AUTO_UPDATE=1 — disable polling auto-update
13
- * - CODEX_MONITOR_UPDATE_INTERVAL_MS — override poll interval (default 10 min)
11
+ * - OPENFLEET_SKIP_UPDATE_CHECK=1 — disable startup check
12
+ * - OPENFLEET_SKIP_AUTO_UPDATE=1 — disable polling auto-update
13
+ * - OPENFLEET_UPDATE_INTERVAL_MS — override poll interval (default 10 min)
14
14
  * - Caches the last check timestamp so we don't query npm too aggressively
15
15
  */
16
16
 
@@ -124,7 +124,7 @@ async function fetchLatestVersion() {
124
124
  * Called on startup — must never throw or delay the main process.
125
125
  */
126
126
  export async function checkForUpdate(currentVersion) {
127
- if (process.env.CODEX_MONITOR_SKIP_UPDATE_CHECK) return;
127
+ if (process.env.OPENFLEET_SKIP_UPDATE_CHECK) return;
128
128
 
129
129
  try {
130
130
  // Rate-limit: at most once per hour
@@ -240,13 +240,13 @@ let cleanupHandlersRegistered = false;
240
240
  * @param {number} [opts.parentPid] - Parent process PID to monitor (default: process.ppid)
241
241
  */
242
242
  export function startAutoUpdateLoop(opts = {}) {
243
- if (process.env.CODEX_MONITOR_SKIP_AUTO_UPDATE === "1") {
244
- console.log("[auto-update] Disabled via CODEX_MONITOR_SKIP_AUTO_UPDATE=1");
243
+ if (process.env.OPENFLEET_SKIP_AUTO_UPDATE === "1") {
244
+ console.log("[auto-update] Disabled via OPENFLEET_SKIP_AUTO_UPDATE=1");
245
245
  return;
246
246
  }
247
247
 
248
248
  const intervalMs =
249
- Number(process.env.CODEX_MONITOR_UPDATE_INTERVAL_MS) ||
249
+ Number(process.env.OPENFLEET_UPDATE_INTERVAL_MS) ||
250
250
  opts.intervalMs ||
251
251
  AUTO_UPDATE_INTERVAL_MS;
252
252
  const onRestart = opts.onRestart || (() => process.exit(0));
@@ -969,7 +969,7 @@ function Initialize-CISweepConfig {
969
969
  $script:CopilotCloudDisableOnRateLimit = Get-EnvBool -Name "COPILOT_CLOUD_DISABLE_ON_RATE_LIMIT" -Default $true
970
970
  $envCopilotLocalResolution = Get-EnvFallback -Name "COPILOT_LOCAL_RESOLUTION"
971
971
  $script:CopilotLocalResolution = if ($envCopilotLocalResolution) { $envCopilotLocalResolution } else { "agent" }
972
- $script:CodexMonitorTaskUpstream = Get-EnvString -Name "CODEX_MONITOR_TASK_UPSTREAM" -Default "origin/ve/openfleet-generic"
972
+ $script:CodexMonitorTaskUpstream = Get-EnvString -Name "OPENFLEET_TASK_UPSTREAM" -Default "origin/ve/openfleet-generic"
973
973
 
974
974
  # Branch routing scope map (v0.8) — maps conventional commit scopes to upstream branches
975
975
  $script:BranchRoutingScopeMap = @{}
@@ -177,7 +177,7 @@ function detectGitTopLevel(candidatePath) {
177
177
  * Resolve the best repository root for singleton initialization.
178
178
  * Priority:
179
179
  * 1) explicit repoRoot arg
180
- * 2) VE_REPO_ROOT / CODEX_MONITOR_REPO_ROOT env
180
+ * 2) VE_REPO_ROOT / OPENFLEET_REPO_ROOT env
181
181
  * 3) current working directory's git top-level
182
182
  * 4) module-relative git top-level (useful for local dev)
183
183
  * 5) process.cwd() fallback
@@ -189,7 +189,7 @@ function resolveDefaultRepoRoot(repoRoot) {
189
189
  if (repoRoot) return resolve(repoRoot);
190
190
 
191
191
  const envRoot =
192
- process.env.VE_REPO_ROOT || process.env.CODEX_MONITOR_REPO_ROOT || "";
192
+ process.env.VE_REPO_ROOT || process.env.OPENFLEET_REPO_ROOT || "";
193
193
  const fromEnv = detectGitTopLevel(envRoot) || (envRoot ? resolve(envRoot) : null);
194
194
  if (fromEnv) return fromEnv;
195
195