overlord-cli 0.2608231148.0 → 0.2608240740.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 +118 -13
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20809,6 +20809,9 @@ var init_pre_launch = __esm({
|
|
|
20809
20809
|
});
|
|
20810
20810
|
|
|
20811
20811
|
// src/terminal-launcher.ts
|
|
20812
|
+
function terminalOpenSpawnTimeoutMs(execution) {
|
|
20813
|
+
return execution.terminal ? TERMINAL_OPEN_SPAWN_TIMEOUT_MS : void 0;
|
|
20814
|
+
}
|
|
20812
20815
|
function shellQuote2(value) {
|
|
20813
20816
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
20814
20817
|
}
|
|
@@ -21126,11 +21129,14 @@ function resolveLaunchExecution({
|
|
|
21126
21129
|
});
|
|
21127
21130
|
return { command: full, args: [], useShell: true, terminal: launcher, display: full };
|
|
21128
21131
|
}
|
|
21132
|
+
var TERMINAL_OPEN_SPAWN_TIMEOUT_MS, TERMINAL_OPEN_SPAWN_KILL_SIGNAL;
|
|
21129
21133
|
var init_terminal_launcher = __esm({
|
|
21130
21134
|
"src/terminal-launcher.ts"() {
|
|
21131
21135
|
"use strict";
|
|
21132
21136
|
init_project_tmp();
|
|
21133
21137
|
init_terminal_launch_chord();
|
|
21138
|
+
TERMINAL_OPEN_SPAWN_TIMEOUT_MS = 45e3;
|
|
21139
|
+
TERMINAL_OPEN_SPAWN_KILL_SIGNAL = "SIGKILL";
|
|
21134
21140
|
}
|
|
21135
21141
|
});
|
|
21136
21142
|
|
|
@@ -21142,6 +21148,40 @@ function interactiveLoginShellInvocation(command, configuredShell = process.env.
|
|
|
21142
21148
|
const shell = configuredShell?.trim() || "/bin/bash";
|
|
21143
21149
|
return { command: shell, args: ["-ilc", command] };
|
|
21144
21150
|
}
|
|
21151
|
+
function spawnSyncOptionsForLaunch({
|
|
21152
|
+
cwd,
|
|
21153
|
+
env,
|
|
21154
|
+
timeoutMs
|
|
21155
|
+
}) {
|
|
21156
|
+
return {
|
|
21157
|
+
cwd,
|
|
21158
|
+
env,
|
|
21159
|
+
stdio: "inherit",
|
|
21160
|
+
...timeoutMs === void 0 ? {} : { timeout: timeoutMs, killSignal: TERMINAL_OPEN_SPAWN_KILL_SIGNAL }
|
|
21161
|
+
};
|
|
21162
|
+
}
|
|
21163
|
+
function isSpawnSyncTimedOut(result) {
|
|
21164
|
+
return result.error?.code === "ETIMEDOUT";
|
|
21165
|
+
}
|
|
21166
|
+
function terminalOpenTimeoutMessage({
|
|
21167
|
+
terminal,
|
|
21168
|
+
timeoutMs
|
|
21169
|
+
}) {
|
|
21170
|
+
const seconds = Math.round(timeoutMs / 1e3);
|
|
21171
|
+
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).`;
|
|
21172
|
+
}
|
|
21173
|
+
function throwIfTerminalOpenTimedOut({
|
|
21174
|
+
result,
|
|
21175
|
+
execution
|
|
21176
|
+
}) {
|
|
21177
|
+
if (!execution.terminal || !isSpawnSyncTimedOut(result)) return;
|
|
21178
|
+
throw new Error(
|
|
21179
|
+
terminalOpenTimeoutMessage({
|
|
21180
|
+
terminal: execution.terminal,
|
|
21181
|
+
timeoutMs: TERMINAL_OPEN_SPAWN_TIMEOUT_MS
|
|
21182
|
+
})
|
|
21183
|
+
);
|
|
21184
|
+
}
|
|
21145
21185
|
function overlordLaunchEnv({
|
|
21146
21186
|
backendUrl,
|
|
21147
21187
|
missionId,
|
|
@@ -21573,16 +21613,15 @@ async function launchAgent({
|
|
|
21573
21613
|
};
|
|
21574
21614
|
}
|
|
21575
21615
|
const { execution } = plan;
|
|
21576
|
-
const
|
|
21577
|
-
const
|
|
21578
|
-
cwd: options.workingDirectory,
|
|
21579
|
-
env,
|
|
21580
|
-
stdio: "inherit"
|
|
21581
|
-
}) : spawnSync3(execution.command, execution.args, {
|
|
21616
|
+
const timeoutMs = terminalOpenSpawnTimeoutMs(execution);
|
|
21617
|
+
const spawnOptions = spawnSyncOptionsForLaunch({
|
|
21582
21618
|
cwd: options.workingDirectory,
|
|
21583
21619
|
env,
|
|
21584
|
-
|
|
21620
|
+
timeoutMs
|
|
21585
21621
|
});
|
|
21622
|
+
const shellInvocation = execution.useShell ? interactiveLoginShellInvocation(execution.command) : null;
|
|
21623
|
+
const result = shellInvocation ? spawnSync3(shellInvocation.command, shellInvocation.args, spawnOptions) : spawnSync3(execution.command, execution.args, spawnOptions);
|
|
21624
|
+
throwIfTerminalOpenTimedOut({ result, execution });
|
|
21586
21625
|
return {
|
|
21587
21626
|
plan,
|
|
21588
21627
|
status: result.status,
|
|
@@ -22795,13 +22834,66 @@ function resolveOvldInvocation(argv = process.argv, execPath = process.execPath)
|
|
|
22795
22834
|
}
|
|
22796
22835
|
return { program: execPath, args: ["runner", "supervise"] };
|
|
22797
22836
|
}
|
|
22837
|
+
function composeRunnerServicePath({
|
|
22838
|
+
homeDir = os5.homedir()
|
|
22839
|
+
} = {}) {
|
|
22840
|
+
const localBin = path33.join(homeDir, ".local", "bin");
|
|
22841
|
+
const dirs = [...RUNNER_SERVICE_PATH_PREFIX_DIRS, localBin, ...RUNNER_SERVICE_SYSTEM_PATH_DIRS];
|
|
22842
|
+
return [...new Set(dirs)].join(":");
|
|
22843
|
+
}
|
|
22844
|
+
function parseLaunchdProcessType(plist) {
|
|
22845
|
+
const match = /<key>ProcessType<\/key>\s*<string>([^<]*)<\/string>/.exec(plist);
|
|
22846
|
+
return match?.[1] ?? null;
|
|
22847
|
+
}
|
|
22848
|
+
function parseLaunchdEnvPath(plist) {
|
|
22849
|
+
const match = /<key>PATH<\/key>\s*<string>([^<]*)<\/string>/.exec(plist);
|
|
22850
|
+
return match?.[1] ?? null;
|
|
22851
|
+
}
|
|
22852
|
+
function inspectInstalledLaunchdPlist(plistPath) {
|
|
22853
|
+
if (!existsSync28(plistPath)) return { processType: null, path: null };
|
|
22854
|
+
try {
|
|
22855
|
+
const plist = readFileSync19(plistPath, "utf8");
|
|
22856
|
+
return {
|
|
22857
|
+
processType: parseLaunchdProcessType(plist),
|
|
22858
|
+
path: parseLaunchdEnvPath(plist)
|
|
22859
|
+
};
|
|
22860
|
+
} catch {
|
|
22861
|
+
return { processType: null, path: null };
|
|
22862
|
+
}
|
|
22863
|
+
}
|
|
22864
|
+
function runnerServiceReinstallHint({
|
|
22865
|
+
installed,
|
|
22866
|
+
publisher,
|
|
22867
|
+
processType,
|
|
22868
|
+
path: path36
|
|
22869
|
+
}) {
|
|
22870
|
+
if (!installed) return null;
|
|
22871
|
+
const hints = [];
|
|
22872
|
+
if (publisher === "node") {
|
|
22873
|
+
hints.push(
|
|
22874
|
+
'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".'
|
|
22875
|
+
);
|
|
22876
|
+
}
|
|
22877
|
+
if (processType && processType !== LAUNCHD_PROCESS_TYPE) {
|
|
22878
|
+
hints.push(
|
|
22879
|
+
`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}.`
|
|
22880
|
+
);
|
|
22881
|
+
}
|
|
22882
|
+
if (path36 !== void 0 && path36 !== composeRunnerServicePath()) {
|
|
22883
|
+
hints.push(
|
|
22884
|
+
"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."
|
|
22885
|
+
);
|
|
22886
|
+
}
|
|
22887
|
+
return hints.length > 0 ? hints.join(" ") : null;
|
|
22888
|
+
}
|
|
22798
22889
|
function buildRunnerServiceEnv({
|
|
22799
22890
|
backendUrl,
|
|
22800
22891
|
overlordHome,
|
|
22801
|
-
runAsElectronNode
|
|
22892
|
+
runAsElectronNode,
|
|
22893
|
+
homeDir
|
|
22802
22894
|
}) {
|
|
22803
22895
|
const env = {
|
|
22804
|
-
PATH:
|
|
22896
|
+
PATH: composeRunnerServicePath({ homeDir })
|
|
22805
22897
|
};
|
|
22806
22898
|
if (!isLoopbackBackendUrl(backendUrl)) env.OVERLORD_BACKEND_URL = backendUrl;
|
|
22807
22899
|
const home = overlordHome?.trim() || process.env.OVLD_HOME?.trim();
|
|
@@ -22848,7 +22940,7 @@ ${envEntries}
|
|
|
22848
22940
|
<key>StandardErrorPath</key>
|
|
22849
22941
|
<string>${xmlEscape(path33.join(logDir, "runner-service.err.log"))}</string>
|
|
22850
22942
|
<key>ProcessType</key>
|
|
22851
|
-
<string
|
|
22943
|
+
<string>${LAUNCHD_PROCESS_TYPE}</string>
|
|
22852
22944
|
</dict>
|
|
22853
22945
|
</plist>
|
|
22854
22946
|
`;
|
|
@@ -22913,7 +23005,7 @@ function resolveServiceManager(platform2 = process.platform) {
|
|
|
22913
23005
|
if (platform2 === "linux") return new SystemdUserManager();
|
|
22914
23006
|
return null;
|
|
22915
23007
|
}
|
|
22916
|
-
var execFileAsync, RUNNER_SERVICE_STATE_FILENAME, LAUNCHD_LABEL, SYSTEMD_UNIT_NAME, FALLBACK_POLL_INTERVAL_MS, LaunchdManager, SystemdUserManager;
|
|
23008
|
+
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
23009
|
var init_runner_service = __esm({
|
|
22918
23010
|
"src/runner-service.ts"() {
|
|
22919
23011
|
"use strict";
|
|
@@ -22923,6 +23015,9 @@ var init_runner_service = __esm({
|
|
|
22923
23015
|
LAUNCHD_LABEL = "io.overlord.runner";
|
|
22924
23016
|
SYSTEMD_UNIT_NAME = "overlord-runner";
|
|
22925
23017
|
FALLBACK_POLL_INTERVAL_MS = 5e3;
|
|
23018
|
+
LAUNCHD_PROCESS_TYPE = "Interactive";
|
|
23019
|
+
RUNNER_SERVICE_SYSTEM_PATH_DIRS = ["/usr/bin", "/bin", "/usr/sbin", "/sbin"];
|
|
23020
|
+
RUNNER_SERVICE_PATH_PREFIX_DIRS = ["/opt/homebrew/bin", "/usr/local/bin"];
|
|
22926
23021
|
LaunchdManager = class {
|
|
22927
23022
|
kind = "launchd";
|
|
22928
23023
|
identifier = LAUNCHD_LABEL;
|
|
@@ -24821,7 +24916,14 @@ async function runRunnerServiceCommand({
|
|
|
24821
24916
|
const runState = await manager.status();
|
|
24822
24917
|
const state = readRunnerServiceState();
|
|
24823
24918
|
const publisher = process.platform !== "darwin" || !state.execProgram ? "unknown" : state.execProgram.includes(".app/Contents/MacOS/") ? "overlord" : "node";
|
|
24824
|
-
const
|
|
24919
|
+
const inspected = manager.kind === "launchd" && runState.installed ? inspectInstalledLaunchdPlist(manager.unitPath()) : null;
|
|
24920
|
+
const processType = inspected?.processType ?? null;
|
|
24921
|
+
const reinstallHint = runnerServiceReinstallHint({
|
|
24922
|
+
installed: runState.installed,
|
|
24923
|
+
publisher,
|
|
24924
|
+
processType,
|
|
24925
|
+
...inspected ? { path: inspected.path } : {}
|
|
24926
|
+
});
|
|
24825
24927
|
const payload = {
|
|
24826
24928
|
supported: true,
|
|
24827
24929
|
kind: manager.kind,
|
|
@@ -24837,6 +24939,8 @@ async function runRunnerServiceCommand({
|
|
|
24837
24939
|
lastError: state.lastError,
|
|
24838
24940
|
currentPollIntervalMs: state.currentPollIntervalMs,
|
|
24839
24941
|
publisher,
|
|
24942
|
+
processType,
|
|
24943
|
+
path: inspected?.path ?? null,
|
|
24840
24944
|
reinstallHint
|
|
24841
24945
|
};
|
|
24842
24946
|
if (json) printJson(payload);
|
|
@@ -24846,6 +24950,7 @@ async function runRunnerServiceCommand({
|
|
|
24846
24950
|
Installed: runState.installed ? "yes" : "no",
|
|
24847
24951
|
Running: runState.running,
|
|
24848
24952
|
Publisher: publisher === "unknown" ? "(unknown)" : publisher,
|
|
24953
|
+
...processType ? { "Process type": processType } : {},
|
|
24849
24954
|
Backend: state.backendUrl ?? "(unknown)",
|
|
24850
24955
|
"Last heartbeat": state.lastHeartbeatAt ?? "(never)",
|
|
24851
24956
|
"Last launched": state.lastLaunchedAt ?? "(never)",
|
|
@@ -24881,7 +24986,7 @@ Note: ${reinstallHint}`);
|
|
|
24881
24986
|
if (json) printJson({ started: autoStart, ...runState });
|
|
24882
24987
|
else
|
|
24883
24988
|
console.log(
|
|
24884
|
-
`Persistent runner installed (${manager.kind}) and ${autoStart ? "started" : "not started"}.`
|
|
24989
|
+
`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
24990
|
);
|
|
24886
24991
|
return;
|
|
24887
24992
|
}
|