@virtengine/openfleet 0.26.1 → 0.26.3

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.
@@ -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 OpenFleet." },
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())
@@ -1,5 +1,5 @@
1
1
  /* ─── VirtEngine Control Center — CSS Custom Properties ─── */
2
- /* Tuned for a CodexMonitor-style desktop + responsive UI */
2
+ /* Tuned for a OpenFleet-style desktop + responsive UI */
3
3
 
4
4
  :root {
5
5
  /* Typography */
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",
@@ -3807,8 +3807,9 @@ async function handleStatic(req, res, url) {
3807
3807
  export async function startTelegramUiServer(options = {}) {
3808
3808
  if (uiServer) return uiServer;
3809
3809
 
3810
- const port = Number(options.port || getDefaultPort());
3811
- if (!port) return null;
3810
+ const rawPort = options.port ?? getDefaultPort();
3811
+ const port = Number(rawPort);
3812
+ if (!Number.isFinite(port) || port < 0) return null;
3812
3813
 
3813
3814
  injectUiDependencies(options.dependencies || {});
3814
3815
 
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
 
@@ -20,6 +20,7 @@ import { readFileSync, existsSync } from "node:fs";
20
20
  import { resolve, dirname, join } from "node:path";
21
21
  import { fileURLToPath } from "node:url";
22
22
  import { createInterface } from "node:readline";
23
+ import os from "node:os";
23
24
 
24
25
  const __dirname = dirname(fileURLToPath(import.meta.url));
25
26
  const PKG_NAME = "@virtengine/openfleet";
@@ -28,9 +29,14 @@ const STARTUP_CHECK_INTERVAL_MS = 60 * 60 * 1000; // 1 hour (startup notice)
28
29
  const AUTO_UPDATE_INTERVAL_MS = 10 * 60 * 1000; // 10 minutes (polling loop)
29
30
 
30
31
  function runNpmCommand(args, options = {}) {
32
+ // Default cwd to the user home directory so that npm never inherits a
33
+ // deleted working directory (e.g. a stale git worktree), which would cause
34
+ // Node's uv_cwd to throw ENOENT before npm even parses its arguments.
35
+ const safeOptions = { cwd: os.homedir(), ...options };
36
+
31
37
  const npmExecPath = process.env.npm_execpath;
32
38
  if (npmExecPath && existsSync(npmExecPath)) {
33
- return execFileSync(process.execPath, [npmExecPath, ...args], options);
39
+ return execFileSync(process.execPath, [npmExecPath, ...args], safeOptions);
34
40
  }
35
41
 
36
42
  const nodeBinDir = dirname(process.execPath);
@@ -45,12 +51,12 @@ function runNpmCommand(args, options = {}) {
45
51
 
46
52
  for (const candidate of candidates) {
47
53
  if (existsSync(candidate)) {
48
- return execFileSync(candidate, args, options);
54
+ return execFileSync(candidate, args, safeOptions);
49
55
  }
50
56
  }
51
57
 
52
58
  const fallback = process.platform === "win32" ? "npm.cmd" : "npm";
53
- return execFileSync(fallback, args, options);
59
+ return execFileSync(fallback, args, safeOptions);
54
60
  }
55
61
 
56
62
  // ── Semver comparison ────────────────────────────────────────────────────────
@@ -124,7 +130,7 @@ async function fetchLatestVersion() {
124
130
  * Called on startup — must never throw or delay the main process.
125
131
  */
126
132
  export async function checkForUpdate(currentVersion) {
127
- if (process.env.CODEX_MONITOR_SKIP_UPDATE_CHECK) return;
133
+ if (process.env.OPENFLEET_SKIP_UPDATE_CHECK) return;
128
134
 
129
135
  try {
130
136
  // Rate-limit: at most once per hour
@@ -240,13 +246,13 @@ let cleanupHandlersRegistered = false;
240
246
  * @param {number} [opts.parentPid] - Parent process PID to monitor (default: process.ppid)
241
247
  */
242
248
  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");
249
+ if (process.env.OPENFLEET_SKIP_AUTO_UPDATE === "1") {
250
+ console.log("[auto-update] Disabled via OPENFLEET_SKIP_AUTO_UPDATE=1");
245
251
  return;
246
252
  }
247
253
 
248
254
  const intervalMs =
249
- Number(process.env.CODEX_MONITOR_UPDATE_INTERVAL_MS) ||
255
+ Number(process.env.OPENFLEET_UPDATE_INTERVAL_MS) ||
250
256
  opts.intervalMs ||
251
257
  AUTO_UPDATE_INTERVAL_MS;
252
258
  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:OpenFleetTaskUpstream = 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 = @{}
@@ -1530,10 +1530,10 @@ function Extract-UpstreamFromText {
1530
1530
  return Normalize-BranchName -Branch $match.Groups[1].Value
1531
1531
  }
1532
1532
 
1533
- function Test-IsCodexMonitorTask {
1533
+ function Test-IsOpenFleetTask {
1534
1534
  param([Parameter(Mandatory)][object]$Task)
1535
1535
  $text = (Get-TaskTextBlob -Task $Task).ToLowerInvariant()
1536
- if ($text -match "openfleet|codex monitor|@virtengine/openfleet|scripts/openfleet") { return $true }
1536
+ if ($text -match "openfleet|OpenFleet|@virtengine/openfleet|scripts/openfleet") { return $true }
1537
1537
  return $false
1538
1538
  }
1539
1539
 
@@ -1637,8 +1637,8 @@ function Get-TaskUpstreamBranch {
1637
1637
  $fromScope = Resolve-BranchFromScopeMap -Task $Task
1638
1638
  if ($fromScope) { return $fromScope }
1639
1639
 
1640
- if (Test-IsCodexMonitorTask -Task $Task) {
1641
- return $script:CodexMonitorTaskUpstream
1640
+ if (Test-IsOpenFleetTask -Task $Task) {
1641
+ return $script:OpenFleetTaskUpstream
1642
1642
  }
1643
1643
 
1644
1644
  return $script:VK_TARGET_BRANCH
@@ -5926,7 +5926,7 @@ function Test-DirtyPRFileOverlap {
5926
5926
  'ci' = @('.github/', 'Makefile', 'make/')
5927
5927
  'ml' = @('ml/')
5928
5928
  'deps' = @('go.mod', 'go.sum', 'vendor/')
5929
- 'codexmonitor' = @('scripts/openfleet/')
5929
+ 'OpenFleet' = @('scripts/openfleet/')
5930
5930
  }
5931
5931
 
5932
5932
  $titleLower = $TaskTitle.ToLower()
@@ -33,7 +33,7 @@ const whatsappChatId = process.env.WHATSAPP_CHAT_ID || "";
33
33
  const assistantName =
34
34
  process.env.WHATSAPP_ASSISTANT_NAME ||
35
35
  process.env.PROJECT_NAME ||
36
- "Codex Monitor";
36
+ "OpenFleet";
37
37
  const storeDir = resolve(
38
38
  process.env.WHATSAPP_STORE_DIR ||
39
39
  resolve(repoRoot, ".cache", "whatsapp-store"),
@@ -229,7 +229,7 @@ async function connectInternal(onFirstOpen) {
229
229
  },
230
230
  printQRInTerminal: false,
231
231
  logger: silentLogger,
232
- browser: b.Browsers?.macOS?.("Chrome") || ["Codex Monitor", "Chrome", "1.0"],
232
+ browser: b.Browsers?.macOS?.("Chrome") || ["OpenFleet", "Chrome", "1.0"],
233
233
  });
234
234
 
235
235
  sock.ev.on("connection.update", (update) => {
@@ -452,7 +452,7 @@ export async function runWhatsAppAuth(mode = "qr") {
452
452
  },
453
453
  printQRInTerminal: false,
454
454
  logger: silentLogger,
455
- browser: b.Browsers?.macOS?.("Chrome") || ["Codex Monitor", "Chrome", "1.0"],
455
+ browser: b.Browsers?.macOS?.("Chrome") || ["OpenFleet", "Chrome", "1.0"],
456
456
  });
457
457
 
458
458
  let pairingRequested = false;
@@ -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