@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.
- package/.env.example +33 -33
- package/agent-hook-bridge.mjs +1 -1
- package/agent-hooks.mjs +5 -5
- package/agent-prompts.mjs +4 -4
- package/cli.mjs +67 -25
- package/compat.mjs +286 -0
- package/config-doctor.mjs +1 -1
- package/config.mjs +15 -11
- package/hook-profiles.mjs +17 -17
- package/kanban-adapter.mjs +11 -11
- package/monitor.mjs +37 -7
- package/package.json +4 -2
- package/postinstall.mjs +1 -1
- package/preflight.mjs +2 -2
- package/presence.mjs +1 -1
- package/publish.mjs +13 -7
- package/setup.mjs +26 -17
- package/shared-state-manager.mjs +1 -1
- package/startup-service.mjs +2 -2
- package/task-executor.mjs +3 -3
- package/telegram-bot.mjs +136 -2
- package/telegram-sentinel.mjs +1 -1
- package/ui/demo.html +640 -0
- package/ui/modules/settings-schema.js +10 -10
- package/ui/styles/variables.css +1 -1
- package/ui-server.mjs +20 -19
- package/update-check.mjs +16 -10
- package/ve-orchestrator.ps1 +6 -6
- package/whatsapp-channel.mjs +3 -3
- package/worktree-manager.mjs +2 -2
|
@@ -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: "
|
|
108
|
-
{ key: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
169
|
-
{ key: "
|
|
170
|
-
{ key: "
|
|
171
|
-
{ key: "
|
|
172
|
-
{ key: "
|
|
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 === "
|
|
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/styles/variables.css
CHANGED
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.
|
|
79
|
-
? resolve(process.env.
|
|
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 === "
|
|
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
|
-
|
|
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("
|
|
278
|
-
const rest = envKey.slice("
|
|
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
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
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", "
|
|
474
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
495
|
-
"
|
|
496
|
-
"
|
|
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
|
|
3811
|
-
|
|
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
|
-
* -
|
|
12
|
-
* -
|
|
13
|
-
* -
|
|
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],
|
|
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,
|
|
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,
|
|
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.
|
|
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.
|
|
244
|
-
console.log("[auto-update] Disabled via
|
|
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.
|
|
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));
|
package/ve-orchestrator.ps1
CHANGED
|
@@ -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:
|
|
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-
|
|
1533
|
+
function Test-IsOpenFleetTask {
|
|
1534
1534
|
param([Parameter(Mandatory)][object]$Task)
|
|
1535
1535
|
$text = (Get-TaskTextBlob -Task $Task).ToLowerInvariant()
|
|
1536
|
-
if ($text -match "openfleet|
|
|
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-
|
|
1641
|
-
return $script:
|
|
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
|
-
'
|
|
5929
|
+
'OpenFleet' = @('scripts/openfleet/')
|
|
5930
5930
|
}
|
|
5931
5931
|
|
|
5932
5932
|
$titleLower = $TaskTitle.ToLower()
|
package/whatsapp-channel.mjs
CHANGED
|
@@ -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
|
-
"
|
|
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") || ["
|
|
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") || ["
|
|
455
|
+
browser: b.Browsers?.macOS?.("Chrome") || ["OpenFleet", "Chrome", "1.0"],
|
|
456
456
|
});
|
|
457
457
|
|
|
458
458
|
let pairingRequested = false;
|
package/worktree-manager.mjs
CHANGED
|
@@ -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 /
|
|
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.
|
|
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
|
|