@otto-code/cli 0.5.7 → 0.6.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.
@@ -76,6 +76,45 @@ function buildChildEnv(options) {
76
76
  }
77
77
  return childEnv;
78
78
  }
79
+ // A packaged desktop build runs this CLI on the Electron binary
80
+ // (`process.execPath` is e.g. /opt/Otto/Otto). Spawning the daemon through that
81
+ // binary then needs two things the plain-Node path doesn't:
82
+ // 1. ELECTRON_RUN_AS_NODE=1 — otherwise the binary boots as the Otto GUI/CLI
83
+ // (commander) and rejects the daemon entry as an "unknown command".
84
+ // 2. The unpacked node-entrypoint-runner — the supervisor entry resolves to a
85
+ // path inside app.asar, which can't be the direct entry under
86
+ // ELECTRON_RUN_AS_NODE, so it must be loaded via the runner (mirroring the
87
+ // desktop daemon-manager: `<runner> node-script <entry>`).
88
+ // Outside a packaged Electron binary (dev, or a plain-node CLI), neither applies
89
+ // and we spawn the entry directly. Returns null when not applicable.
90
+ function resolvePackagedNodeEntrypointRunner(daemonRunnerEntry) {
91
+ if (!process.versions.electron) {
92
+ return null;
93
+ }
94
+ const marker = `${path.sep}node_modules${path.sep}@otto-code${path.sep}server${path.sep}`;
95
+ const markerIndex = daemonRunnerEntry.lastIndexOf(marker);
96
+ if (markerIndex === -1) {
97
+ return null;
98
+ }
99
+ const appRoot = daemonRunnerEntry.slice(0, markerIndex);
100
+ const runnerPath = path.join(appRoot, "dist", "daemon", "node-entrypoint-runner.js");
101
+ return existsSync(runnerPath) ? runnerPath : null;
102
+ }
103
+ function buildDaemonSpawnInvocation(daemonRunnerEntry, runnerArgs, childEnv) {
104
+ const packagedRunner = resolvePackagedNodeEntrypointRunner(daemonRunnerEntry);
105
+ if (packagedRunner) {
106
+ return {
107
+ command: process.execPath,
108
+ args: [packagedRunner, "node-script", daemonRunnerEntry, ...runnerArgs],
109
+ env: { ...childEnv, ELECTRON_RUN_AS_NODE: "1" },
110
+ };
111
+ }
112
+ return {
113
+ command: process.execPath,
114
+ args: [...process.execArgv, daemonRunnerEntry, ...runnerArgs],
115
+ env: childEnv,
116
+ };
117
+ }
79
118
  function resolveServerRunnerFromDir(currentDir) {
80
119
  const packageJsonPath = path.join(currentDir, "package.json");
81
120
  if (!existsSync(packageJsonPath))
@@ -411,10 +450,11 @@ export async function startLocalDaemonDetached(options, runtime = defaultDaemonL
411
450
  const childEnv = buildChildEnv(options);
412
451
  const ottoHome = runtime.resolveHome(childEnv);
413
452
  const logPath = path.join(ottoHome, DAEMON_LOG_FILENAME);
414
- const child = runtime.spawnDetached(process.execPath, [...process.execArgv, daemonRunnerEntry, ...buildRunnerArgs(options)], {
453
+ const invocation = buildDaemonSpawnInvocation(daemonRunnerEntry, buildRunnerArgs(options), childEnv);
454
+ const child = runtime.spawnDetached(invocation.command, invocation.args, {
415
455
  detached: true,
416
456
  envMode: "internal",
417
- env: childEnv,
457
+ env: invocation.env,
418
458
  stdio: ["ignore", "ignore", "ignore"],
419
459
  });
420
460
  child.unref();
@@ -459,8 +499,9 @@ export function startLocalDaemonForeground(options, runtime = defaultDaemonLaunc
459
499
  }
460
500
  const daemonRunnerEntry = runtime.resolveRunnerEntry();
461
501
  const childEnv = buildChildEnv(options);
462
- const result = runtime.spawnForeground(process.execPath, [...process.execArgv, daemonRunnerEntry, ...buildRunnerArgs(options)], {
463
- env: childEnv,
502
+ const invocation = buildDaemonSpawnInvocation(daemonRunnerEntry, buildRunnerArgs(options), childEnv);
503
+ const result = runtime.spawnForeground(invocation.command, invocation.args, {
504
+ env: invocation.env,
464
505
  stdio: "inherit",
465
506
  });
466
507
  if (result.error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@otto-code/cli",
3
- "version": "0.5.7",
3
+ "version": "0.6.0",
4
4
  "description": "Otto CLI - control your AI coding agents from the command line",
5
5
  "bin": {
6
6
  "otto": "bin/otto"
@@ -27,9 +27,9 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@clack/prompts": "^1.0.0",
30
- "@otto-code/client": "0.5.7",
31
- "@otto-code/protocol": "0.5.7",
32
- "@otto-code/server": "0.5.7",
30
+ "@otto-code/client": "0.6.0",
31
+ "@otto-code/protocol": "0.6.0",
32
+ "@otto-code/server": "0.6.0",
33
33
  "chalk": "^5.3.0",
34
34
  "commander": "^12.0.0",
35
35
  "mime-types": "^2.1.35",