fix(service): forward PATH into the ccam systemd --user unit
systemd --user units start with systemd's own minimal PATH, not the installer's shell PATH, so the dashboard couldn't find claude/codex (e.g. installed under ~/.local/bin) when spawning a lane from a service-managed server. Forward process.env.PATH into the unit's environment from both ccam service install and the plugin bootstrap's auto-install path.
This commit is contained in:
+11
-2
@@ -1454,7 +1454,10 @@ async function cmdService(sub, flags) {
|
|||||||
console.error(c.red("✖ client/dist is missing — build it first: npm run build"));
|
console.error(c.red("✖ client/dist is missing — build it first: npm run build"));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
const env = { NODE_ENV: "production" };
|
// systemd --user units get systemd's own minimal PATH, not the shell's —
|
||||||
|
// without forwarding it, the server can't find `claude`/`codex` when
|
||||||
|
// spawning lanes even though they're on the installer's PATH.
|
||||||
|
const env = { NODE_ENV: "production", PATH: process.env.PATH || "" };
|
||||||
if (flags.port) env.DASHBOARD_PORT = String(flags.port);
|
if (flags.port) env.DASHBOARD_PORT = String(flags.port);
|
||||||
const result = svc.installUserService({
|
const result = svc.installUserService({
|
||||||
name,
|
name,
|
||||||
@@ -1834,12 +1837,18 @@ async function cmdLanesLifecycle(action, args) {
|
|||||||
* ALIAS — which is most of them, ship-feature's skill says `tests`, `booting`,
|
* ALIAS — which is most of them, ship-feature's skill says `tests`, `booting`,
|
||||||
* `ship`, `gate-blocked` — is not a node id, so indexOf answers -1 and every
|
* `ship`, `gate-blocked` — is not a node id, so indexOf answers -1 and every
|
||||||
* detection, however far behind, reads as leading.
|
* detection, however far behind, reads as leading.
|
||||||
|
*
|
||||||
|
* `>=`, not `>`: a lane that has never declared anything is RENDERED at its
|
||||||
|
* detected node by the server (`inferredDisplayStage`), so detection and the
|
||||||
|
* `current` node are the same one — and for that lane this badge is the only
|
||||||
|
* readout of what it is doing. A declared lane can never tie, because
|
||||||
|
* recordDetection refuses a detection that isn't strictly ahead of it.
|
||||||
*/
|
*/
|
||||||
function detectionLeadsDeclaration(l) {
|
function detectionLeadsDeclaration(l) {
|
||||||
if (!l.detected_stage) return false;
|
if (!l.detected_stage) return false;
|
||||||
const nodes = l.pipeline_nodes || [];
|
const nodes = l.pipeline_nodes || [];
|
||||||
return (
|
return (
|
||||||
nodes.findIndex((n) => n.id === l.detected_stage) >
|
nodes.findIndex((n) => n.id === l.detected_stage) >=
|
||||||
nodes.findIndex((n) => n.state === "current")
|
nodes.findIndex((n) => n.state === "current")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -480,6 +480,9 @@ function bootstrap(rt = runtimeDir(), { force = false } = {}) {
|
|||||||
NODE_ENV: "production",
|
NODE_ENV: "production",
|
||||||
NODE_PATH: path.join(rt, "node_modules"),
|
NODE_PATH: path.join(rt, "node_modules"),
|
||||||
DASHBOARD_CLIENT_DIST: path.join(rt, "client-dist"),
|
DASHBOARD_CLIENT_DIST: path.join(rt, "client-dist"),
|
||||||
|
// systemd --user units get systemd's own minimal PATH, not the
|
||||||
|
// shell's — forward it so the server can find `claude`/`codex`.
|
||||||
|
PATH: process.env.PATH || "",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
: "unavailable";
|
: "unavailable";
|
||||||
|
|||||||
Reference in New Issue
Block a user