@pwrdrvr/agent-acp 0.13.0 → 0.13.1

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 CHANGED
@@ -6,6 +6,10 @@ import {
6
6
  ndJsonStream
7
7
  } from "@agentclientprotocol/sdk";
8
8
  import { noopLogger } from "@pwrdrvr/agent-core";
9
+ import {
10
+ createCommandInvocation,
11
+ prependCommandDirToPath
12
+ } from "@pwrdrvr/agent-transport";
9
13
  var AcpConnection = class {
10
14
  constructor(options) {
11
15
  this.options = options;
@@ -64,9 +68,12 @@ var AcpConnection = class {
64
68
  const { command, args, env } = this.options;
65
69
  const logger = this.logger;
66
70
  return (client) => {
67
- const child = spawn(command, args, {
71
+ const launchEnv = prependCommandDirToPath(command, env ?? process.env);
72
+ const invocation = createCommandInvocation({ command, args, env: launchEnv });
73
+ const child = spawn(invocation.command, invocation.args, {
68
74
  stdio: ["pipe", "pipe", "pipe"],
69
- ...env !== void 0 ? { env } : {}
75
+ env: launchEnv,
76
+ windowsVerbatimArguments: invocation.windowsVerbatimArguments
70
77
  });
71
78
  child.on("error", (error) => {
72
79
  logger.error("acp agent process error", { command, message: error.message });
@@ -2302,7 +2309,10 @@ import { readdirSync, realpathSync, statSync } from "fs";
2302
2309
  import { homedir as homedir4 } from "os";
2303
2310
  import path4 from "path";
2304
2311
  import { promisify } from "util";
2305
- import { prependCommandDirToPath } from "@pwrdrvr/agent-transport";
2312
+ import {
2313
+ createCommandInvocation as createCommandInvocation2,
2314
+ prependCommandDirToPath as prependCommandDirToPath2
2315
+ } from "@pwrdrvr/agent-transport";
2306
2316
  var execFile = promisify(execFileCallback);
2307
2317
  async function discoverLocalAcpAgentInstances(options = {}) {
2308
2318
  const strategies = options.strategies ?? BUILT_IN_ACP_STRATEGIES;
@@ -2403,35 +2413,60 @@ function candidateCommands(strategy, env, listExecutables, override) {
2403
2413
  return out;
2404
2414
  }
2405
2415
  function canonicalize(command) {
2406
- if (!path4.isAbsolute(command)) return command;
2416
+ if (!path4.isAbsolute(command)) {
2417
+ return process.platform === "win32" ? command.toLowerCase() : command;
2418
+ }
2407
2419
  try {
2408
- return realpathSync(command);
2420
+ const canonical = realpathSync(command);
2421
+ return process.platform === "win32" ? canonical.toLowerCase() : canonical;
2409
2422
  } catch {
2410
- return command;
2423
+ return process.platform === "win32" ? command.toLowerCase() : command;
2411
2424
  }
2412
2425
  }
2413
2426
  function defaultListExecutables(command, env) {
2414
- if (process.platform === "win32") return [];
2415
- if (command.includes(path4.sep)) return [];
2427
+ if (command.includes("/") || command.includes("\\")) return [];
2416
2428
  const found = [];
2417
2429
  const seenDir = /* @__PURE__ */ new Set();
2418
2430
  for (const dir of discoveryDirs(env)) {
2419
- if (dir.length === 0 || seenDir.has(dir)) continue;
2420
- seenDir.add(dir);
2421
- const candidate = path4.join(dir, command);
2422
- try {
2423
- const stat = statSync(candidate);
2424
- if (stat.isFile() && (stat.mode & 73) !== 0) {
2425
- found.push(candidate);
2431
+ const normalizedDir = normalizePathEntry(dir);
2432
+ const dirKey = process.platform === "win32" ? normalizedDir.toLowerCase() : normalizedDir;
2433
+ if (normalizedDir.length === 0 || seenDir.has(dirKey)) continue;
2434
+ seenDir.add(dirKey);
2435
+ for (const commandName of executableCommandNames(command, env)) {
2436
+ const candidate = path4.join(normalizedDir, commandName);
2437
+ try {
2438
+ const stat = statSync(candidate);
2439
+ if (stat.isFile() && (process.platform === "win32" || (stat.mode & 73) !== 0)) {
2440
+ found.push(candidate);
2441
+ }
2442
+ } catch {
2426
2443
  }
2427
- } catch {
2428
2444
  }
2429
2445
  }
2430
2446
  return found;
2431
2447
  }
2448
+ function executableCommandNames(command, env) {
2449
+ if (process.platform !== "win32") return [command];
2450
+ const extensions = (readWindowsEnv(env, "PATHEXT")?.trim() || ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean).map((extension) => extension.startsWith(".") ? extension : `.${extension}`);
2451
+ const commandExtension = path4.win32.extname(command);
2452
+ if (commandExtension.length > 0 && extensions.some((extension) => extension.toLowerCase() === commandExtension.toLowerCase())) {
2453
+ return [command];
2454
+ }
2455
+ return extensions.map((extension) => `${command}${extension}`);
2456
+ }
2457
+ function readWindowsEnv(env, name) {
2458
+ const key = Object.keys(env).find((candidate) => candidate.toLowerCase() === name.toLowerCase());
2459
+ return key ? env[key] : void 0;
2460
+ }
2461
+ function normalizePathEntry(entry) {
2462
+ const trimmed = entry.trim();
2463
+ const quoted = trimmed.match(/^"(.*)"$/);
2464
+ return quoted?.[1] ?? trimmed;
2465
+ }
2432
2466
  function discoveryDirs(env) {
2433
- const pathValue = env.PATH ?? env.Path ?? "";
2434
- return [...pathValue.split(path4.delimiter), ...wellKnownAgentBinDirs(homedir4())];
2467
+ const pathValue = process.platform === "win32" ? readWindowsEnv(env, "PATH") ?? "" : env.PATH ?? "";
2468
+ const pathDirs = pathValue.split(path4.delimiter);
2469
+ return process.platform === "win32" ? pathDirs : [...pathDirs, ...wellKnownAgentBinDirs(homedir4())];
2435
2470
  }
2436
2471
  function wellKnownAgentBinDirs(home = homedir4()) {
2437
2472
  return [
@@ -2469,12 +2504,15 @@ function ensureArgs(args, ensure) {
2469
2504
  }
2470
2505
  function makeDefaultProbe(env) {
2471
2506
  return async (command, args) => {
2472
- return await execFile(command, args, {
2507
+ const launchEnv = prependCommandDirToPath2(command, env);
2508
+ const invocation = createCommandInvocation2({ command, args, env: launchEnv });
2509
+ return await execFile(invocation.command, invocation.args, {
2473
2510
  timeout: 5e3,
2474
2511
  maxBuffer: 1024 * 1024,
2475
2512
  // Prepend the candidate's own dir so a node-script CLI (e.g. an nvm-
2476
2513
  // installed `qwen`) finds its sibling `node` during the probe.
2477
- env: prependCommandDirToPath(command, env)
2514
+ env: launchEnv,
2515
+ windowsVerbatimArguments: invocation.windowsVerbatimArguments
2478
2516
  });
2479
2517
  };
2480
2518
  }