@turns/dev 0.0.32 → 0.0.33

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.
@@ -24,6 +24,7 @@
24
24
  import { spawn } from 'node:child_process';
25
25
  import os from 'node:os';
26
26
  import { readCodexAccountStatus } from "./codex-account.js";
27
+ import { executablePath } from "./executable-path.js";
27
28
  import { readVibeAccount, readLocalHarnessAccount, parseNativeHarnessAccount, NATIVE_ACCOUNT_COMMANDS, } from "./harness-account.js";
28
29
  import { ACP_PROFILES, HARNESS_IDS, resolveHarnessCommand } from "./harness-registry.js";
29
30
  /** Harnesses whose account status this module can inspect. Mirrors the shared
@@ -84,12 +85,19 @@ export function parseCodexLoginStatus(output) {
84
85
  return { authenticated: false };
85
86
  return { authenticated: null };
86
87
  }
88
+ /**
89
+ * Match the PATH agent anchors launch with, so a Node-backed CLI found
90
+ * outside the daemon's inherited PATH can still locate its interpreter.
91
+ */
92
+ function harnessEnvironment() {
93
+ return { ...process.env, PATH: executablePath() };
94
+ }
87
95
  /** Both streams interleaved: codex reports status on stderr, claude on stdout. */
88
96
  function runCommand(command, args, timeoutMs) {
89
97
  return new Promise((resolve) => {
90
98
  const child = spawn(command, args, {
91
99
  cwd: os.homedir(),
92
- env: process.env,
100
+ env: harnessEnvironment(),
93
101
  stdio: ['ignore', 'pipe', 'pipe'],
94
102
  });
95
103
  let output = '';
@@ -210,7 +218,7 @@ export function createHarnessAuthManager() {
210
218
  flows.set(harness, flow);
211
219
  const child = spawn(command, args, {
212
220
  cwd: os.homedir(),
213
- env: process.env,
221
+ env: harnessEnvironment(),
214
222
  stdio: ['pipe', 'pipe', 'pipe'],
215
223
  });
216
224
  flow.child = child;
@@ -264,6 +264,9 @@ export const HARNESS_IDS = [
264
264
  function executable(candidate) {
265
265
  try {
266
266
  fs.accessSync(candidate, fs.constants.X_OK);
267
+ // X_OK also passes for directories, which cannot be launched.
268
+ if (!fs.statSync(candidate).isFile())
269
+ return '';
267
270
  return candidate;
268
271
  }
269
272
  catch {
@@ -325,6 +328,15 @@ export function resolveHarnessCommand(harness, profile = {}, dependencies = {})
325
328
  return found;
326
329
  }
327
330
  }
331
+ // Claude Code's older "local" installer puts a wrapper script here and
332
+ // relies on a shell alias rather than PATH, so a daemon (which never reads
333
+ // the user's shell config) would otherwise miss it. Living in the shared
334
+ // resolver covers agent launch, auth status, and login alike.
335
+ if (harness === 'claude') {
336
+ const found = executable(path.join(home, '.claude', 'local', 'claude'));
337
+ if (found)
338
+ return found;
339
+ }
328
340
  throw new Error(`Agent executable not found for harness "${harness}" (${command}).`);
329
341
  }
330
342
  export function processInvocation({ harness, sessionId, transcriptPath, cwd, prompt, createSession, model, thinkingLevel, timeoutMs, }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@turns/dev",
3
- "version": "0.0.32",
3
+ "version": "0.0.33",
4
4
  "description": "Upload local AI agent sessions to turns.dev",
5
5
  "license": "MIT",
6
6
  "type": "module",