overlord-cli 0.2608231148.0 → 0.2608241435.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +122 -13
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7375,6 +7375,9 @@ function hasControlCharacters(value) {
|
|
|
7375
7375
|
function hasUnsafePathCharacters(value) {
|
|
7376
7376
|
return hasControlCharacters(value) || value.includes("\\");
|
|
7377
7377
|
}
|
|
7378
|
+
function isOverlordManagedEvidencePath(filePath) {
|
|
7379
|
+
return filePath === ".overlord" || filePath.startsWith(".overlord/");
|
|
7380
|
+
}
|
|
7378
7381
|
function isExactEvidencePath(value) {
|
|
7379
7382
|
if (typeof value !== "string")
|
|
7380
7383
|
return false;
|
|
@@ -19247,6 +19250,7 @@ function normalizeWorkspacePath({
|
|
|
19247
19250
|
}
|
|
19248
19251
|
if (relative.length > MAX_EVIDENCE_PATH_LENGTH) return { reason: "path_too_long" };
|
|
19249
19252
|
if (!isExactEvidencePath(relative)) return { reason: "invalid_path" };
|
|
19253
|
+
if (isOverlordManagedEvidencePath(relative)) return { reason: "ignored_path" };
|
|
19250
19254
|
if (isIgnoredPath(ignoreRules, relative)) return { reason: "ignored_path" };
|
|
19251
19255
|
return { filePath: relative };
|
|
19252
19256
|
}
|
|
@@ -20809,6 +20813,9 @@ var init_pre_launch = __esm({
|
|
|
20809
20813
|
});
|
|
20810
20814
|
|
|
20811
20815
|
// src/terminal-launcher.ts
|
|
20816
|
+
function terminalOpenSpawnTimeoutMs(execution) {
|
|
20817
|
+
return execution.terminal ? TERMINAL_OPEN_SPAWN_TIMEOUT_MS : void 0;
|
|
20818
|
+
}
|
|
20812
20819
|
function shellQuote2(value) {
|
|
20813
20820
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
20814
20821
|
}
|
|
@@ -21126,11 +21133,14 @@ function resolveLaunchExecution({
|
|
|
21126
21133
|
});
|
|
21127
21134
|
return { command: full, args: [], useShell: true, terminal: launcher, display: full };
|
|
21128
21135
|
}
|
|
21136
|
+
var TERMINAL_OPEN_SPAWN_TIMEOUT_MS, TERMINAL_OPEN_SPAWN_KILL_SIGNAL;
|
|
21129
21137
|
var init_terminal_launcher = __esm({
|
|
21130
21138
|
"src/terminal-launcher.ts"() {
|
|
21131
21139
|
"use strict";
|
|
21132
21140
|
init_project_tmp();
|
|
21133
21141
|
init_terminal_launch_chord();
|
|
21142
|
+
TERMINAL_OPEN_SPAWN_TIMEOUT_MS = 45e3;
|
|
21143
|
+
TERMINAL_OPEN_SPAWN_KILL_SIGNAL = "SIGKILL";
|
|
21134
21144
|
}
|
|
21135
21145
|
});
|
|
21136
21146
|
|
|
@@ -21142,6 +21152,40 @@ function interactiveLoginShellInvocation(command, configuredShell = process.env.
|
|
|
21142
21152
|
const shell = configuredShell?.trim() || "/bin/bash";
|
|
21143
21153
|
return { command: shell, args: ["-ilc", command] };
|
|
21144
21154
|
}
|
|
21155
|
+
function spawnSyncOptionsForLaunch({
|
|
21156
|
+
cwd,
|
|
21157
|
+
env,
|
|
21158
|
+
timeoutMs
|
|
21159
|
+
}) {
|
|
21160
|
+
return {
|
|
21161
|
+
cwd,
|
|
21162
|
+
env,
|
|
21163
|
+
stdio: "inherit",
|
|
21164
|
+
...timeoutMs === void 0 ? {} : { timeout: timeoutMs, killSignal: TERMINAL_OPEN_SPAWN_KILL_SIGNAL }
|
|
21165
|
+
};
|
|
21166
|
+
}
|
|
21167
|
+
function isSpawnSyncTimedOut(result) {
|
|
21168
|
+
return result.error?.code === "ETIMEDOUT";
|
|
21169
|
+
}
|
|
21170
|
+
function terminalOpenTimeoutMessage({
|
|
21171
|
+
terminal,
|
|
21172
|
+
timeoutMs
|
|
21173
|
+
}) {
|
|
21174
|
+
const seconds = Math.round(timeoutMs / 1e3);
|
|
21175
|
+
return `osascript/Apple Event timed out after ${seconds}s while opening ${terminal}. The execution request failed so the runner can keep claiming. ${terminal} may still open after this timeout (orphan window).`;
|
|
21176
|
+
}
|
|
21177
|
+
function throwIfTerminalOpenTimedOut({
|
|
21178
|
+
result,
|
|
21179
|
+
execution
|
|
21180
|
+
}) {
|
|
21181
|
+
if (!execution.terminal || !isSpawnSyncTimedOut(result)) return;
|
|
21182
|
+
throw new Error(
|
|
21183
|
+
terminalOpenTimeoutMessage({
|
|
21184
|
+
terminal: execution.terminal,
|
|
21185
|
+
timeoutMs: TERMINAL_OPEN_SPAWN_TIMEOUT_MS
|
|
21186
|
+
})
|
|
21187
|
+
);
|
|
21188
|
+
}
|
|
21145
21189
|
function overlordLaunchEnv({
|
|
21146
21190
|
backendUrl,
|
|
21147
21191
|
missionId,
|
|
@@ -21573,16 +21617,15 @@ async function launchAgent({
|
|
|
21573
21617
|
};
|
|
21574
21618
|
}
|
|
21575
21619
|
const { execution } = plan;
|
|
21576
|
-
const
|
|
21577
|
-
const
|
|
21578
|
-
cwd: options.workingDirectory,
|
|
21579
|
-
env,
|
|
21580
|
-
stdio: "inherit"
|
|
21581
|
-
}) : spawnSync3(execution.command, execution.args, {
|
|
21620
|
+
const timeoutMs = terminalOpenSpawnTimeoutMs(execution);
|
|
21621
|
+
const spawnOptions = spawnSyncOptionsForLaunch({
|
|
21582
21622
|
cwd: options.workingDirectory,
|
|
21583
21623
|
env,
|
|
21584
|
-
|
|
21624
|
+
timeoutMs
|
|
21585
21625
|
});
|
|
21626
|
+
const shellInvocation = execution.useShell ? interactiveLoginShellInvocation(execution.command) : null;
|
|
21627
|
+
const result = shellInvocation ? spawnSync3(shellInvocation.command, shellInvocation.args, spawnOptions) : spawnSync3(execution.command, execution.args, spawnOptions);
|
|
21628
|
+
throwIfTerminalOpenTimedOut({ result, execution });
|
|
21586
21629
|
return {
|
|
21587
21630
|
plan,
|
|
21588
21631
|
status: result.status,
|
|
@@ -22795,13 +22838,66 @@ function resolveOvldInvocation(argv = process.argv, execPath = process.execPath)
|
|
|
22795
22838
|
}
|
|
22796
22839
|
return { program: execPath, args: ["runner", "supervise"] };
|
|
22797
22840
|
}
|
|
22841
|
+
function composeRunnerServicePath({
|
|
22842
|
+
homeDir = os5.homedir()
|
|
22843
|
+
} = {}) {
|
|
22844
|
+
const localBin = path33.join(homeDir, ".local", "bin");
|
|
22845
|
+
const dirs = [...RUNNER_SERVICE_PATH_PREFIX_DIRS, localBin, ...RUNNER_SERVICE_SYSTEM_PATH_DIRS];
|
|
22846
|
+
return [...new Set(dirs)].join(":");
|
|
22847
|
+
}
|
|
22848
|
+
function parseLaunchdProcessType(plist) {
|
|
22849
|
+
const match = /<key>ProcessType<\/key>\s*<string>([^<]*)<\/string>/.exec(plist);
|
|
22850
|
+
return match?.[1] ?? null;
|
|
22851
|
+
}
|
|
22852
|
+
function parseLaunchdEnvPath(plist) {
|
|
22853
|
+
const match = /<key>PATH<\/key>\s*<string>([^<]*)<\/string>/.exec(plist);
|
|
22854
|
+
return match?.[1] ?? null;
|
|
22855
|
+
}
|
|
22856
|
+
function inspectInstalledLaunchdPlist(plistPath) {
|
|
22857
|
+
if (!existsSync28(plistPath)) return { processType: null, path: null };
|
|
22858
|
+
try {
|
|
22859
|
+
const plist = readFileSync19(plistPath, "utf8");
|
|
22860
|
+
return {
|
|
22861
|
+
processType: parseLaunchdProcessType(plist),
|
|
22862
|
+
path: parseLaunchdEnvPath(plist)
|
|
22863
|
+
};
|
|
22864
|
+
} catch {
|
|
22865
|
+
return { processType: null, path: null };
|
|
22866
|
+
}
|
|
22867
|
+
}
|
|
22868
|
+
function runnerServiceReinstallHint({
|
|
22869
|
+
installed,
|
|
22870
|
+
publisher,
|
|
22871
|
+
processType,
|
|
22872
|
+
path: path36
|
|
22873
|
+
}) {
|
|
22874
|
+
if (!installed) return null;
|
|
22875
|
+
const hints = [];
|
|
22876
|
+
if (publisher === "node") {
|
|
22877
|
+
hints.push(
|
|
22878
|
+
'This service is registered under "Node.js Foundation" because it runs the plain node binary. Reinstall it from the Overlord desktop app (or with the desktop app present) to re-register it under "Overlord".'
|
|
22879
|
+
);
|
|
22880
|
+
}
|
|
22881
|
+
if (processType && processType !== LAUNCHD_PROCESS_TYPE) {
|
|
22882
|
+
hints.push(
|
|
22883
|
+
`This LaunchAgent is ProcessType=${processType}. App auto-update respawns the supervisor but does not rewrite ProcessType, so Apple Events to Terminal/iTerm stay App-Napped. Reinstall with \`ovld runner service install\` (or Desktop \u2192 Reinstall service) to switch to ${LAUNCHD_PROCESS_TYPE}.`
|
|
22884
|
+
);
|
|
22885
|
+
}
|
|
22886
|
+
if (path36 !== void 0 && path36 !== composeRunnerServicePath()) {
|
|
22887
|
+
hints.push(
|
|
22888
|
+
"This LaunchAgent PATH is not the deterministic prefix (`/opt/homebrew/bin:/usr/local/bin:$HOME/.local/bin` plus system dirs). App auto-update respawns the supervisor but does not rewrite PATH, so Latch/`open`/agent binaries spawned by the service may be missing. Reinstall with `ovld runner service install` (or Desktop \u2192 Reinstall service) to apply it."
|
|
22889
|
+
);
|
|
22890
|
+
}
|
|
22891
|
+
return hints.length > 0 ? hints.join(" ") : null;
|
|
22892
|
+
}
|
|
22798
22893
|
function buildRunnerServiceEnv({
|
|
22799
22894
|
backendUrl,
|
|
22800
22895
|
overlordHome,
|
|
22801
|
-
runAsElectronNode
|
|
22896
|
+
runAsElectronNode,
|
|
22897
|
+
homeDir
|
|
22802
22898
|
}) {
|
|
22803
22899
|
const env = {
|
|
22804
|
-
PATH:
|
|
22900
|
+
PATH: composeRunnerServicePath({ homeDir })
|
|
22805
22901
|
};
|
|
22806
22902
|
if (!isLoopbackBackendUrl(backendUrl)) env.OVERLORD_BACKEND_URL = backendUrl;
|
|
22807
22903
|
const home = overlordHome?.trim() || process.env.OVLD_HOME?.trim();
|
|
@@ -22848,7 +22944,7 @@ ${envEntries}
|
|
|
22848
22944
|
<key>StandardErrorPath</key>
|
|
22849
22945
|
<string>${xmlEscape(path33.join(logDir, "runner-service.err.log"))}</string>
|
|
22850
22946
|
<key>ProcessType</key>
|
|
22851
|
-
<string
|
|
22947
|
+
<string>${LAUNCHD_PROCESS_TYPE}</string>
|
|
22852
22948
|
</dict>
|
|
22853
22949
|
</plist>
|
|
22854
22950
|
`;
|
|
@@ -22913,7 +23009,7 @@ function resolveServiceManager(platform2 = process.platform) {
|
|
|
22913
23009
|
if (platform2 === "linux") return new SystemdUserManager();
|
|
22914
23010
|
return null;
|
|
22915
23011
|
}
|
|
22916
|
-
var execFileAsync, RUNNER_SERVICE_STATE_FILENAME, LAUNCHD_LABEL, SYSTEMD_UNIT_NAME, FALLBACK_POLL_INTERVAL_MS, LaunchdManager, SystemdUserManager;
|
|
23012
|
+
var execFileAsync, RUNNER_SERVICE_STATE_FILENAME, LAUNCHD_LABEL, SYSTEMD_UNIT_NAME, FALLBACK_POLL_INTERVAL_MS, LAUNCHD_PROCESS_TYPE, RUNNER_SERVICE_SYSTEM_PATH_DIRS, RUNNER_SERVICE_PATH_PREFIX_DIRS, LaunchdManager, SystemdUserManager;
|
|
22917
23013
|
var init_runner_service = __esm({
|
|
22918
23014
|
"src/runner-service.ts"() {
|
|
22919
23015
|
"use strict";
|
|
@@ -22923,6 +23019,9 @@ var init_runner_service = __esm({
|
|
|
22923
23019
|
LAUNCHD_LABEL = "io.overlord.runner";
|
|
22924
23020
|
SYSTEMD_UNIT_NAME = "overlord-runner";
|
|
22925
23021
|
FALLBACK_POLL_INTERVAL_MS = 5e3;
|
|
23022
|
+
LAUNCHD_PROCESS_TYPE = "Interactive";
|
|
23023
|
+
RUNNER_SERVICE_SYSTEM_PATH_DIRS = ["/usr/bin", "/bin", "/usr/sbin", "/sbin"];
|
|
23024
|
+
RUNNER_SERVICE_PATH_PREFIX_DIRS = ["/opt/homebrew/bin", "/usr/local/bin"];
|
|
22926
23025
|
LaunchdManager = class {
|
|
22927
23026
|
kind = "launchd";
|
|
22928
23027
|
identifier = LAUNCHD_LABEL;
|
|
@@ -24821,7 +24920,14 @@ async function runRunnerServiceCommand({
|
|
|
24821
24920
|
const runState = await manager.status();
|
|
24822
24921
|
const state = readRunnerServiceState();
|
|
24823
24922
|
const publisher = process.platform !== "darwin" || !state.execProgram ? "unknown" : state.execProgram.includes(".app/Contents/MacOS/") ? "overlord" : "node";
|
|
24824
|
-
const
|
|
24923
|
+
const inspected = manager.kind === "launchd" && runState.installed ? inspectInstalledLaunchdPlist(manager.unitPath()) : null;
|
|
24924
|
+
const processType = inspected?.processType ?? null;
|
|
24925
|
+
const reinstallHint = runnerServiceReinstallHint({
|
|
24926
|
+
installed: runState.installed,
|
|
24927
|
+
publisher,
|
|
24928
|
+
processType,
|
|
24929
|
+
...inspected ? { path: inspected.path } : {}
|
|
24930
|
+
});
|
|
24825
24931
|
const payload = {
|
|
24826
24932
|
supported: true,
|
|
24827
24933
|
kind: manager.kind,
|
|
@@ -24837,6 +24943,8 @@ async function runRunnerServiceCommand({
|
|
|
24837
24943
|
lastError: state.lastError,
|
|
24838
24944
|
currentPollIntervalMs: state.currentPollIntervalMs,
|
|
24839
24945
|
publisher,
|
|
24946
|
+
processType,
|
|
24947
|
+
path: inspected?.path ?? null,
|
|
24840
24948
|
reinstallHint
|
|
24841
24949
|
};
|
|
24842
24950
|
if (json) printJson(payload);
|
|
@@ -24846,6 +24954,7 @@ async function runRunnerServiceCommand({
|
|
|
24846
24954
|
Installed: runState.installed ? "yes" : "no",
|
|
24847
24955
|
Running: runState.running,
|
|
24848
24956
|
Publisher: publisher === "unknown" ? "(unknown)" : publisher,
|
|
24957
|
+
...processType ? { "Process type": processType } : {},
|
|
24849
24958
|
Backend: state.backendUrl ?? "(unknown)",
|
|
24850
24959
|
"Last heartbeat": state.lastHeartbeatAt ?? "(never)",
|
|
24851
24960
|
"Last launched": state.lastLaunchedAt ?? "(never)",
|
|
@@ -24881,7 +24990,7 @@ Note: ${reinstallHint}`);
|
|
|
24881
24990
|
if (json) printJson({ started: autoStart, ...runState });
|
|
24882
24991
|
else
|
|
24883
24992
|
console.log(
|
|
24884
|
-
`Persistent runner installed (${manager.kind}) and ${autoStart ? "started" : "not started"}.`
|
|
24993
|
+
`Persistent runner installed (${manager.kind}) and ${autoStart ? "started" : "not started"}.` + (manager.kind === "launchd" ? " Re-running install rewrites the LaunchAgent (ProcessType Interactive and PATH prefix); app auto-update respawns the process but does not rewrite the plist." : "")
|
|
24885
24994
|
);
|
|
24886
24995
|
return;
|
|
24887
24996
|
}
|