kandev 0.50.0 → 0.51.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.
@@ -1,11 +1,41 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.MANAGED_MARKER_TEXT = void 0;
4
7
  exports.looksLikeManagedUnit = looksLikeManagedUnit;
5
8
  exports.renderSystemdUnit = renderSystemdUnit;
6
9
  exports.renderLaunchdPlist = renderLaunchdPlist;
7
- const SYSTEMD_PATH = "/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin:/home/linuxbrew/.linuxbrew/bin";
8
- const LAUNCHD_PATH = "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin";
10
+ const node_os_1 = __importDefault(require("node:os"));
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ // User-mode PATH includes ~/.local/bin so user-installed agent CLIs (npm user
13
+ // prefix, pipx, fnm, etc.) are discoverable.
14
+ const SYSTEMD_SYSTEM_PATH = "/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin:/home/linuxbrew/.linuxbrew/bin";
15
+ const SYSTEMD_USER_PATH = `%h/.local/bin:${SYSTEMD_SYSTEM_PATH}`;
16
+ const LAUNCHD_SYSTEM_PATH = "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin";
17
+ const launchdUserPath = () => `${node_os_1.default.homedir()}/.local/bin:${LAUNCHD_SYSTEM_PATH}`;
18
+ // Prepend the launcher node's bin dir so `npm`/`npx` resolve under per-user
19
+ // node managers (fnm, nvm, asdf, volta, mise), where node lives in a versioned
20
+ // subdirectory not covered by the system PATH. ExecStart already points at this
21
+ // node, so its parent dir is exactly where the matching npm/npx live — without
22
+ // this, npx-based ACP agents (claude, codex, opencode) fail to spawn.
23
+ //
24
+ // The isAbsolute guard exists because `path.dirname` on POSIX returns `'.'`
25
+ // for a path with no `/` separator (e.g. a Windows-style `C:\…\node.exe`
26
+ // passed through). Prepending `.` would put CWD ahead of system dirs in the
27
+ // daemon's PATH — a privilege-escalation footgun. Production callers always
28
+ // pass `process.execPath` (absolute on Linux/macOS), so the guard only kicks
29
+ // in for non-POSIX or relative inputs from future callers / tests.
30
+ function pathWithNodeBinDir(basePath, nodePath) {
31
+ const nodeBinDir = node_path_1.default.dirname(nodePath);
32
+ if (!node_path_1.default.isAbsolute(nodeBinDir))
33
+ return basePath;
34
+ const parts = basePath.split(":");
35
+ if (parts.includes(nodeBinDir))
36
+ return basePath;
37
+ return `${nodeBinDir}:${basePath}`;
38
+ }
9
39
  /**
10
40
  * Marker substring baked into every unit/plist kandev writes. Used to safely
11
41
  * detect "this file is ours, overwriting is fine" vs "user has put something
@@ -26,10 +56,11 @@ function looksLikeManagedUnit(content) {
26
56
  * `npm i -g` installs don't get spurious env vars.
27
57
  */
28
58
  function renderSystemdUnit(input) {
59
+ const basePath = input.mode === "system" ? SYSTEMD_SYSTEM_PATH : SYSTEMD_USER_PATH;
29
60
  const env = [
30
61
  envLine("KANDEV_HOME_DIR", input.homeDir),
31
62
  envLine("KANDEV_LOG_LEVEL", "info"),
32
- envLine("PATH", SYSTEMD_PATH),
63
+ envLine("PATH", pathWithNodeBinDir(basePath, input.launcher.nodePath)),
33
64
  ];
34
65
  if (input.port !== undefined) {
35
66
  env.push(envLine("KANDEV_SERVER_PORT", String(input.port)));
@@ -71,10 +102,11 @@ WantedBy=${wantedBy}
71
102
  * get a LaunchDaemon that runs at boot regardless of login.
72
103
  */
73
104
  function renderLaunchdPlist(input) {
105
+ const basePath = input.mode === "system" ? LAUNCHD_SYSTEM_PATH : launchdUserPath();
74
106
  const envEntries = [
75
107
  ["KANDEV_HOME_DIR", input.homeDir],
76
108
  ["KANDEV_LOG_LEVEL", "info"],
77
- ["PATH", LAUNCHD_PATH],
109
+ ["PATH", pathWithNodeBinDir(basePath, input.launcher.nodePath)],
78
110
  ];
79
111
  if (input.port !== undefined) {
80
112
  envEntries.push(["KANDEV_SERVER_PORT", String(input.port)]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kandev",
3
- "version": "0.50.0",
3
+ "version": "0.51.0",
4
4
  "private": false,
5
5
  "description": "Launcher for Kandev — manage tasks, orchestrate agents, review changes, and ship value",
6
6
  "license": "AGPL-3.0-only",
@@ -22,11 +22,11 @@
22
22
  "npm": ">=7"
23
23
  },
24
24
  "optionalDependencies": {
25
- "@kdlbs/runtime-linux-x64": "0.50.0",
26
- "@kdlbs/runtime-linux-arm64": "0.50.0",
27
- "@kdlbs/runtime-darwin-x64": "0.50.0",
28
- "@kdlbs/runtime-darwin-arm64": "0.50.0",
29
- "@kdlbs/runtime-win32-x64": "0.50.0"
25
+ "@kdlbs/runtime-linux-x64": "0.51.0",
26
+ "@kdlbs/runtime-linux-arm64": "0.51.0",
27
+ "@kdlbs/runtime-darwin-x64": "0.51.0",
28
+ "@kdlbs/runtime-darwin-arm64": "0.51.0",
29
+ "@kdlbs/runtime-win32-x64": "0.51.0"
30
30
  },
31
31
  "dependencies": {
32
32
  "tar": "^7.5.11",