@swmansion/argent 0.14.1-next.8 → 0.15.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.
package/dist/cli-cmds.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
1
+ import { createRequire as __createRequire } from 'node:module'; import { fileURLToPath as __fileURLToPath } from 'node:url'; import { dirname as __pathDirname } from 'node:path'; const require = __createRequire(import.meta.url); const __filename = __fileURLToPath(import.meta.url); const __dirname = __pathDirname(__filename);
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -162,8 +162,8 @@ var require_src = __commonJS({
162
162
  });
163
163
 
164
164
  // ../argent-cli/src/run.ts
165
- import * as fs7 from "node:fs";
166
- import * as path9 from "node:path";
165
+ import * as fs8 from "node:fs";
166
+ import * as path10 from "node:path";
167
167
 
168
168
  // ../argent-tools-client/src/launcher.ts
169
169
  import * as net from "node:net";
@@ -172,8 +172,8 @@ import * as path from "node:path";
172
172
  import * as readline from "node:readline";
173
173
  import { homedir } from "node:os";
174
174
  import { spawn, execFileSync } from "node:child_process";
175
- import { randomBytes } from "node:crypto";
176
- import { mkdir, writeFile, readFile, unlink, rename, chmod } from "node:fs/promises";
175
+ import { createHash, randomBytes } from "node:crypto";
176
+ import { mkdir, writeFile, readFile, readdir, unlink, rename, chmod } from "node:fs/promises";
177
177
  var STATE_DIR = path.join(homedir(), ".argent");
178
178
  var STATE_FILE = path.join(STATE_DIR, "tool-server.json");
179
179
  var LOG_FILE = path.join(STATE_DIR, "tool-server.log");
@@ -193,6 +193,8 @@ function buildToolsServerEnv(paths, port, baseEnv = process.env, options = {}) {
193
193
  env.ARGENT_IDLE_TIMEOUT_MINUTES = String(options.idleTimeoutMinutes);
194
194
  }
195
195
  if (options.token) env[AUTH_TOKEN_ENV] = options.token;
196
+ if (paths.installKind) env.ARGENT_INSTALL_KIND = paths.installKind;
197
+ if (paths.installProjectRoot) env.ARGENT_PROJECT_ROOT = paths.installProjectRoot;
196
198
  return env;
197
199
  }
198
200
  function generateToken() {
@@ -202,7 +204,7 @@ function generateAuthToken() {
202
204
  return generateToken();
203
205
  }
204
206
  function findFreePort() {
205
- return new Promise((resolve3, reject) => {
207
+ return new Promise((resolve4, reject) => {
206
208
  const srv = net.createServer();
207
209
  srv.listen(0, "127.0.0.1", () => {
208
210
  const addr = srv.address();
@@ -213,12 +215,55 @@ function findFreePort() {
213
215
  const port = addr.port;
214
216
  srv.close((err) => {
215
217
  if (err) reject(err);
216
- else resolve3(port);
218
+ else resolve4(port);
217
219
  });
218
220
  });
219
221
  srv.on("error", reject);
220
222
  });
221
223
  }
224
+ function isVersionNewer(a2, b) {
225
+ const parse = (v) => {
226
+ const [core = "", ...preParts] = v.split("+")[0].split("-");
227
+ const nums = core.split(".").map((n2) => Number.parseInt(n2, 10));
228
+ if (nums.length === 0 || nums.some((n2) => Number.isNaN(n2))) return null;
229
+ return { nums, pre: preParts.length > 0 ? preParts.join("-").split(".") : [] };
230
+ };
231
+ const pa = parse(a2);
232
+ const pb = parse(b);
233
+ if (!pa || !pb) return false;
234
+ for (let i2 = 0; i2 < 3; i2++) {
235
+ const x = pa.nums[i2] ?? 0;
236
+ const y = pb.nums[i2] ?? 0;
237
+ if (x !== y) return x > y;
238
+ }
239
+ if (pa.pre.length === 0 && pb.pre.length === 0) return false;
240
+ if (pa.pre.length === 0) return true;
241
+ if (pb.pre.length === 0) return false;
242
+ for (let i2 = 0; i2 < Math.max(pa.pre.length, pb.pre.length); i2++) {
243
+ const x = pa.pre[i2];
244
+ const y = pb.pre[i2];
245
+ if (x === void 0) return false;
246
+ if (y === void 0) return true;
247
+ if (x === y) continue;
248
+ const xn = /^\d+$/.test(x) ? Number.parseInt(x, 10) : null;
249
+ const yn = /^\d+$/.test(y) ? Number.parseInt(y, 10) : null;
250
+ if (xn !== null && yn !== null) return xn > yn;
251
+ if (xn !== null) return false;
252
+ if (yn !== null) return true;
253
+ return x > y;
254
+ }
255
+ return false;
256
+ }
257
+ function readBundlePackageVersion(bundlePath) {
258
+ try {
259
+ const pkg = JSON.parse(
260
+ fs.readFileSync(path.join(path.dirname(bundlePath), "..", "package.json"), "utf8")
261
+ );
262
+ return typeof pkg.version === "string" ? pkg.version : void 0;
263
+ } catch {
264
+ return void 0;
265
+ }
266
+ }
222
267
  function isProcessAlive(pid) {
223
268
  try {
224
269
  process.kill(pid, 0);
@@ -271,7 +316,7 @@ function killSpawnedChild(child, pid) {
271
316
  }
272
317
  }
273
318
  function spawnToolsServer(paths, port, options = {}) {
274
- return new Promise((resolve3, reject) => {
319
+ return new Promise((resolve4, reject) => {
275
320
  let logFd;
276
321
  try {
277
322
  fs.mkdirSync(STATE_DIR, { recursive: true });
@@ -307,7 +352,8 @@ function spawnToolsServer(paths, port, options = {}) {
307
352
  const actualPort = parseInt(match[1], 10);
308
353
  rl.close();
309
354
  child.stdout?.resume();
310
- settle(() => resolve3({ port: actualPort, pid }));
355
+ child.stdout?.unref?.();
356
+ settle(() => resolve4({ port: actualPort, pid }));
311
357
  }
312
358
  });
313
359
  child.on("error", (err) => {
@@ -325,24 +371,36 @@ function spawnToolsServer(paths, port, options = {}) {
325
371
  rl.on("close", () => clearTimeout(timer));
326
372
  });
327
373
  }
328
- async function readToolsServerState() {
374
+ function stateFileForBundle(bundlePath) {
375
+ const key = createHash("sha256").update(bundlePath).digest("hex").slice(0, 12);
376
+ return path.join(STATE_DIR, `tool-server-${key}.json`);
377
+ }
378
+ async function readStateFile(file) {
329
379
  try {
330
- const raw = await readFile(STATE_FILE, "utf8");
380
+ const raw = await readFile(file, "utf8");
331
381
  return JSON.parse(raw);
332
382
  } catch {
333
383
  return null;
334
384
  }
335
385
  }
386
+ async function readToolsServerState(bundlePath) {
387
+ if (bundlePath === void 0) return readStateFile(STATE_FILE);
388
+ const own = await readStateFile(stateFileForBundle(bundlePath));
389
+ if (own) return own;
390
+ const legacy = await readStateFile(STATE_FILE);
391
+ return legacy && legacy.bundlePath === bundlePath ? legacy : null;
392
+ }
336
393
  async function writeToolsServerState(state2) {
394
+ const target = stateFileForBundle(state2.bundlePath);
337
395
  await mkdir(STATE_DIR, { recursive: true });
338
- const tmp = `${STATE_FILE}.${process.pid}.tmp`;
396
+ const tmp = `${target}.${process.pid}.tmp`;
339
397
  try {
340
398
  await writeFile(tmp, JSON.stringify(state2, null, 2) + "\n", {
341
399
  encoding: "utf8",
342
400
  mode: 384
343
401
  });
344
402
  await chmod(tmp, 384);
345
- await rename(tmp, STATE_FILE);
403
+ await rename(tmp, target);
346
404
  } catch (err) {
347
405
  await unlink(tmp).catch(() => {
348
406
  });
@@ -350,22 +408,55 @@ async function writeToolsServerState(state2) {
350
408
  }
351
409
  }
352
410
  function writeToolsServerStateSync(state2) {
411
+ const target = stateFileForBundle(state2.bundlePath);
353
412
  fs.mkdirSync(STATE_DIR, { recursive: true });
354
- fs.writeFileSync(STATE_FILE, JSON.stringify(state2, null, 2) + "\n", {
413
+ fs.writeFileSync(target, JSON.stringify(state2, null, 2) + "\n", {
355
414
  encoding: "utf8",
356
415
  mode: 384
357
416
  });
358
- fs.chmodSync(STATE_FILE, 384);
417
+ fs.chmodSync(target, 384);
418
+ }
419
+ async function clearToolsServerState(bundlePath) {
420
+ const files = [STATE_FILE];
421
+ if (bundlePath !== void 0) {
422
+ files[0] = stateFileForBundle(bundlePath);
423
+ const legacy = await readStateFile(STATE_FILE);
424
+ if (legacy && legacy.bundlePath === bundlePath) files.push(STATE_FILE);
425
+ }
426
+ for (const file of files) {
427
+ try {
428
+ await unlink(file);
429
+ } catch {
430
+ }
431
+ }
359
432
  }
360
- async function clearToolsServerState() {
433
+ var STATE_FILE_RE = /^tool-server(-[0-9a-f]{12})?\.json$/;
434
+ async function readAllToolsServerStates() {
435
+ let names;
361
436
  try {
362
- await unlink(STATE_FILE);
437
+ names = await readdir(STATE_DIR);
363
438
  } catch {
439
+ return [];
440
+ }
441
+ const out = [];
442
+ for (const name of names) {
443
+ if (!STATE_FILE_RE.test(name)) continue;
444
+ const file = path.join(STATE_DIR, name);
445
+ const state2 = await readStateFile(file);
446
+ if (state2) out.push({ file, state: state2 });
447
+ }
448
+ return out;
449
+ }
450
+ async function sweepDeadStateFiles() {
451
+ for (const { file } of await readAllToolsServerStates()) {
452
+ if (file === STATE_FILE) continue;
453
+ const fresh = await readStateFile(file);
454
+ if (fresh && !isProcessAlive(fresh.pid)) await unlink(file).catch(() => {
455
+ });
364
456
  }
365
457
  }
366
458
  var readState = readToolsServerState;
367
459
  var writeState = writeToolsServerState;
368
- var clearState = clearToolsServerState;
369
460
  var SIGTERM_GRACE_MS = 6e3;
370
461
  var SIGKILL_GRACE_MS = 1e3;
371
462
  var KILL_POLL_MS = 100;
@@ -394,11 +485,11 @@ async function terminatePid(pid, stillOurs) {
394
485
  }
395
486
  await waitForExit(pid, SIGKILL_GRACE_MS);
396
487
  }
397
- async function killToolServer() {
398
- const state2 = await readState();
488
+ async function killToolServer(bundlePath) {
489
+ const state2 = await readState(bundlePath);
399
490
  if (!state2) return;
400
491
  await terminatePid(state2.pid);
401
- await clearState();
492
+ await clearToolsServerState(bundlePath ?? state2.bundlePath);
402
493
  }
403
494
  function processCommandMatches(pid, marker) {
404
495
  if (!marker) return false;
@@ -409,8 +500,8 @@ function processCommandMatches(pid, marker) {
409
500
  stdio: ["ignore", "pipe", "ignore"]
410
501
  }).trim();
411
502
  if (!cmd) return false;
412
- const argv = cmd.split(/\s+/);
413
- return argv.includes(marker) && argv.includes("start");
503
+ const escaped = marker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
504
+ return new RegExp(`(?:^|\\s)${escaped} start(?:\\s|$)`).test(cmd);
414
505
  } catch {
415
506
  return false;
416
507
  }
@@ -474,25 +565,45 @@ async function acquireSpawnLock() {
474
565
  }
475
566
  }
476
567
  }
477
- async function reusableHandle(state2) {
568
+ async function reusableHandle(state2, wantBundlePath, wantVersion) {
478
569
  if (!state2 || !isProcessAlive(state2.pid)) return null;
570
+ if (wantBundlePath !== void 0 && state2.bundlePath !== wantBundlePath) return null;
571
+ if (wantBundlePath !== void 0 && state2.version !== void 0) {
572
+ const diskVersion = readBundlePackageVersion(wantBundlePath);
573
+ if (diskVersion !== void 0) {
574
+ if (diskVersion !== state2.version) return null;
575
+ } else if (wantVersion !== void 0 && state2.version !== wantVersion && isVersionNewer(wantVersion, state2.version)) {
576
+ return null;
577
+ }
578
+ }
479
579
  const host = state2.host ?? "127.0.0.1";
480
580
  const healthy = await isToolsServerHealthy(state2.port, host, 2e3, state2.token);
481
581
  if (!healthy) return null;
482
582
  return { url: formatUrl(healthCheckHost(host), state2.port), token: state2.token ?? "" };
483
583
  }
484
584
  async function ensureToolsServer(paths) {
485
- const fast = await reusableHandle(await readState());
585
+ const fast = await reusableHandle(
586
+ await readState(paths.bundlePath),
587
+ paths.bundlePath,
588
+ paths.version
589
+ );
486
590
  if (fast) return fast;
487
591
  const lock = await acquireSpawnLock();
488
592
  try {
489
- const state2 = await readState();
490
- const reuse = await reusableHandle(state2);
593
+ const state2 = await readState(paths.bundlePath);
594
+ const reuse = await reusableHandle(state2, paths.bundlePath, paths.version);
491
595
  if (reuse) return reuse;
492
- if (state2 && state2.managed === "autospawn" && isProcessAlive(state2.pid) && processCommandMatches(state2.pid, state2.bundlePath)) {
596
+ if (state2 && state2.managed === "autospawn" && state2.bundlePath === paths.bundlePath && isProcessAlive(state2.pid) && processCommandMatches(state2.pid, state2.bundlePath)) {
493
597
  await terminatePid(state2.pid, () => processCommandMatches(state2.pid, state2.bundlePath));
494
598
  }
495
- await clearState();
599
+ await clearToolsServerState(paths.bundlePath);
600
+ await sweepDeadStateFiles();
601
+ if (!fs.existsSync(paths.bundlePath)) {
602
+ throw new Error(
603
+ `The argent install serving this session is gone from disk (${paths.bundlePath}) \u2014 it was likely updated or removed. Restart the editor's MCP connection to reconnect.`
604
+ );
605
+ }
606
+ const diskVersion = readBundlePackageVersion(paths.bundlePath) ?? paths.version;
496
607
  const token = generateToken();
497
608
  const port = await findFreePort();
498
609
  const { port: actualPort, pid } = await spawnToolsServer(paths, port, {
@@ -504,6 +615,7 @@ async function ensureToolsServer(paths) {
504
615
  pid,
505
616
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
506
617
  bundlePath: paths.bundlePath,
618
+ version: diskVersion,
507
619
  host: "127.0.0.1",
508
620
  token,
509
621
  managed: "autospawn"
@@ -617,8 +729,8 @@ function parseLinkTarget(input) {
617
729
  const host = u3.hostname.startsWith("[") ? u3.hostname.slice(1, -1) : u3.hostname;
618
730
  if (!host) throw new Error(`URL "${input}" is missing a host.`);
619
731
  const port = u3.port ? Number(u3.port) : u3.protocol === "https:" ? 443 : 80;
620
- const path12 = u3.pathname === "/" ? "" : u3.pathname.replace(/\/+$/, "");
621
- const url = `${u3.protocol}//${u3.host}${path12}`;
732
+ const path13 = u3.pathname === "/" ? "" : u3.pathname.replace(/\/+$/, "");
733
+ const url = `${u3.protocol}//${u3.host}${path13}`;
622
734
  const token = u3.username ? decodeURIComponent(u3.username) : void 0;
623
735
  return { url, host, port, ...token ? { token } : {} };
624
736
  }
@@ -775,7 +887,7 @@ function createToolsClient(options = {}) {
775
887
  import { mkdir as mkdir4, readFile as readFile4, rm, stat as stat2, writeFile as writeFile4 } from "node:fs/promises";
776
888
  import { tmpdir } from "node:os";
777
889
  import { basename, join as join3 } from "node:path";
778
- import { createHash } from "node:crypto";
890
+ import { createHash as createHash2 } from "node:crypto";
779
891
  import { execFile } from "node:child_process";
780
892
  import { promisify } from "node:util";
781
893
  var execFileAsync = promisify(execFile);
@@ -796,7 +908,7 @@ function sanitizeSegment(segment) {
796
908
  }
797
909
  function projectSlug() {
798
910
  const cwd = process.cwd();
799
- const hash = createHash("sha1").update(cwd).digest("hex").slice(0, 6);
911
+ const hash = createHash2("sha1").update(cwd).digest("hex").slice(0, 6);
800
912
  const name = sanitizeSegment(basename(cwd)) || "root";
801
913
  return `${name}-${hash}`;
802
914
  }
@@ -904,7 +1016,7 @@ function getDeviceIdFromArgs(args) {
904
1016
  }
905
1017
 
906
1018
  // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
907
- import { dirname as dirname2, posix, sep } from "path";
1019
+ import { dirname as dirname3, posix, sep } from "path";
908
1020
  function createModulerModifier() {
909
1021
  const getModuleFromFileName = createGetModuleFromFilename();
910
1022
  return async (frames) => {
@@ -912,7 +1024,7 @@ function createModulerModifier() {
912
1024
  return frames;
913
1025
  };
914
1026
  }
915
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname2(process.argv[1]) : process.cwd(), isWindows = "\\" === sep) {
1027
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname3(process.argv[1]) : process.cwd(), isWindows = "\\" === sep) {
916
1028
  const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
917
1029
  return (filename) => {
918
1030
  if (!filename) return;
@@ -930,8 +1042,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname2(proce
930
1042
  return decodedFile;
931
1043
  };
932
1044
  }
933
- function normalizeWindowsPath(path12) {
934
- return path12.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
1045
+ function normalizeWindowsPath(path13) {
1046
+ return path13.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
935
1047
  }
936
1048
 
937
1049
  // ../../node_modules/@posthog/core/dist/featureFlagUtils.mjs
@@ -3483,15 +3595,15 @@ async function addSourceContext(frames) {
3483
3595
  LRU_FILE_CONTENTS_CACHE.reduce();
3484
3596
  return frames;
3485
3597
  }
3486
- function getContextLinesFromFile(path12, ranges, output) {
3487
- return new Promise((resolve3) => {
3488
- const stream = createReadStream(path12);
3598
+ function getContextLinesFromFile(path13, ranges, output) {
3599
+ return new Promise((resolve4) => {
3600
+ const stream = createReadStream(path13);
3489
3601
  const lineReaded = createInterface2({
3490
3602
  input: stream
3491
3603
  });
3492
3604
  function destroyStreamAndResolve() {
3493
3605
  stream.destroy();
3494
- resolve3();
3606
+ resolve4();
3495
3607
  }
3496
3608
  let lineNumber = 0;
3497
3609
  let currentRangeIndex = 0;
@@ -3500,7 +3612,7 @@ function getContextLinesFromFile(path12, ranges, output) {
3500
3612
  let rangeStart = range[0];
3501
3613
  let rangeEnd = range[1];
3502
3614
  function onStreamError() {
3503
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path12, 1);
3615
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path13, 1);
3504
3616
  lineReaded.close();
3505
3617
  lineReaded.removeAllListeners();
3506
3618
  destroyStreamAndResolve();
@@ -3561,8 +3673,8 @@ function clearLineContext(frame) {
3561
3673
  delete frame.context_line;
3562
3674
  delete frame.post_context;
3563
3675
  }
3564
- function shouldSkipContextLinesForFile(path12) {
3565
- return path12.startsWith("node:") || path12.endsWith(".min.js") || path12.endsWith(".min.cjs") || path12.endsWith(".min.mjs") || path12.startsWith("data:");
3676
+ function shouldSkipContextLinesForFile(path13) {
3677
+ return path13.startsWith("node:") || path13.endsWith(".min.js") || path13.endsWith(".min.cjs") || path13.endsWith(".min.mjs") || path13.startsWith("data:");
3566
3678
  }
3567
3679
  function shouldSkipContextLinesForFrame(frame) {
3568
3680
  if (void 0 !== frame.lineno && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
@@ -3635,14 +3747,14 @@ function snipLine(line, colno) {
3635
3747
  }
3636
3748
 
3637
3749
  // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs
3638
- import { isAbsolute as isAbsolute2, relative, sep as sep2 } from "path";
3750
+ import { isAbsolute as isAbsolute3, relative as relative2, sep as sep2 } from "path";
3639
3751
  function createRelativePathModifier(basePath = process.cwd()) {
3640
3752
  const isWindows = "\\" === sep2;
3641
3753
  const toUnix = (p) => isWindows ? p.replace(/\\/g, "/") : p;
3642
3754
  const normalizedBase = toUnix(basePath);
3643
3755
  return async (frames) => {
3644
3756
  for (const frame of frames) if (!(!frame.filename || frame.filename.startsWith("node:") || frame.filename.startsWith("data:"))) {
3645
- if (isAbsolute2(frame.filename)) frame.filename = toUnix(relative(normalizedBase, toUnix(frame.filename)));
3757
+ if (isAbsolute3(frame.filename)) frame.filename = toUnix(relative2(normalizedBase, toUnix(frame.filename)));
3646
3758
  }
3647
3759
  return frames;
3648
3760
  };
@@ -4788,9 +4900,9 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4788
4900
  if (!waitUntil) return;
4789
4901
  if (this.disabled || this.optedOut) return;
4790
4902
  if (!this._waitUntilCycle) {
4791
- let resolve3;
4903
+ let resolve4;
4792
4904
  const promise = new Promise((r2) => {
4793
- resolve3 = r2;
4905
+ resolve4 = r2;
4794
4906
  });
4795
4907
  try {
4796
4908
  waitUntil(promise);
@@ -4798,7 +4910,7 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4798
4910
  return;
4799
4911
  }
4800
4912
  this._waitUntilCycle = {
4801
- resolve: resolve3,
4913
+ resolve: resolve4,
4802
4914
  startedAt: Date.now(),
4803
4915
  timer: void 0
4804
4916
  };
@@ -4822,12 +4934,12 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4822
4934
  return cycle?.resolve;
4823
4935
  }
4824
4936
  async resolveWaitUntilFlush() {
4825
- const resolve3 = this._consumeWaitUntilCycle();
4937
+ const resolve4 = this._consumeWaitUntilCycle();
4826
4938
  try {
4827
4939
  await super.flush();
4828
4940
  } catch {
4829
4941
  } finally {
4830
- resolve3?.();
4942
+ resolve4?.();
4831
4943
  }
4832
4944
  }
4833
4945
  getPersistedProperty(key) {
@@ -4948,15 +5060,15 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
4948
5060
  async waitForLocalEvaluationReady(timeoutMs = THIRTY_SECONDS) {
4949
5061
  if (this.isLocalEvaluationReady()) return true;
4950
5062
  if (void 0 === this.featureFlagsPoller) return false;
4951
- return new Promise((resolve3) => {
5063
+ return new Promise((resolve4) => {
4952
5064
  const timeout = setTimeout(() => {
4953
5065
  cleanup();
4954
- resolve3(false);
5066
+ resolve4(false);
4955
5067
  }, timeoutMs);
4956
5068
  const cleanup = this._events.on("localEvaluationFlagsLoaded", (count) => {
4957
5069
  clearTimeout(timeout);
4958
5070
  cleanup();
4959
- resolve3(count > 0);
5071
+ resolve4(count > 0);
4960
5072
  });
4961
5073
  });
4962
5074
  }
@@ -5411,14 +5523,14 @@ var PostHogBackendClient = class extends PostHogCoreStateless {
5411
5523
  this.context?.enter(data, options);
5412
5524
  }
5413
5525
  async _shutdown(shutdownTimeoutMs) {
5414
- const resolve3 = this._consumeWaitUntilCycle();
5526
+ const resolve4 = this._consumeWaitUntilCycle();
5415
5527
  await this.featureFlagsPoller?.stopPoller(shutdownTimeoutMs);
5416
5528
  this.errorTracking.shutdown();
5417
5529
  try {
5418
5530
  return await super._shutdown(shutdownTimeoutMs);
5419
5531
  } finally {
5420
5532
  this.distinctIdHasSentFlagCalls = {};
5421
- resolve3?.();
5533
+ resolve4?.();
5422
5534
  }
5423
5535
  }
5424
5536
  async _requestRemoteConfigPayload(flagKey) {
@@ -5824,6 +5936,9 @@ var FAILURE_CODES = {
5824
5936
  TOOLSERVER_UNHANDLED_REJECTION: "TOOLSERVER_UNHANDLED_REJECTION",
5825
5937
  TOOLSERVER_UNCAUGHT_EXCEPTION: "TOOLSERVER_UNCAUGHT_EXCEPTION",
5826
5938
  INSTALL_GLOBAL_PACKAGE_FAILED: "INSTALL_GLOBAL_PACKAGE_FAILED",
5939
+ INSTALL_LOCAL_PACKAGE_FAILED: "INSTALL_LOCAL_PACKAGE_FAILED",
5940
+ INSTALL_LOCAL_PRECONDITION_FAILED: "INSTALL_LOCAL_PRECONDITION_FAILED",
5941
+ INSTALL_MODE_FLAG_CONFLICT: "INSTALL_MODE_FLAG_CONFLICT",
5827
5942
  INSTALL_FROM_TAR_PACKAGE_FAILED: "INSTALL_FROM_TAR_PACKAGE_FAILED",
5828
5943
  INSTALL_INIT_TRIGGERED_UPDATE_FAILED: "INSTALL_INIT_TRIGGERED_UPDATE_FAILED",
5829
5944
  INSTALL_SKILLS_REFRESH_FAILED: "INSTALL_SKILLS_REFRESH_FAILED",
@@ -5839,6 +5954,14 @@ var FAILURE_CODES = {
5839
5954
  UNINSTALL_UNCLASSIFIED_FAILED: "UNINSTALL_UNCLASSIFIED_FAILED",
5840
5955
  VEGA_CLI_COMMAND_FAILED: "VEGA_CLI_COMMAND_FAILED",
5841
5956
  VEGA_INPUT_UNAVAILABLE: "VEGA_INPUT_UNAVAILABLE",
5957
+ VEGA_DEVICE_NOT_FOUND: "VEGA_DEVICE_NOT_FOUND",
5958
+ VEGA_DEVICE_NOT_REGISTERED: "VEGA_DEVICE_NOT_REGISTERED",
5959
+ VEGA_MULTIPLE_DEVICES: "VEGA_MULTIPLE_DEVICES",
5960
+ VEGA_BOOT_TIMEOUT: "VEGA_BOOT_TIMEOUT",
5961
+ VEGA_IMAGE_NOT_FOUND: "VEGA_IMAGE_NOT_FOUND",
5962
+ VEGA_ALREADY_RUNNING: "VEGA_ALREADY_RUNNING",
5963
+ VEGA_SCREENSHOT_FAILED: "VEGA_SCREENSHOT_FAILED",
5964
+ VEGA_TEXT_INVALID: "VEGA_TEXT_INVALID",
5842
5965
  ANDROID_ADB_NOT_FOUND: "ANDROID_ADB_NOT_FOUND",
5843
5966
  ANDROID_EMULATOR_NOT_FOUND: "ANDROID_EMULATOR_NOT_FOUND",
5844
5967
  ANDROID_ADB_COMMAND_FAILED: "ANDROID_ADB_COMMAND_FAILED",
@@ -5851,6 +5974,7 @@ var FAILURE_CODES = {
5851
5974
  SIMULATOR_NON_JSON_RESPONSE: "SIMULATOR_NON_JSON_RESPONSE",
5852
5975
  SIMULATOR_HTTP_ERROR_RESPONSE: "SIMULATOR_HTTP_ERROR_RESPONSE",
5853
5976
  SIMULATOR_MISSING_RESPONSE_FIELDS: "SIMULATOR_MISSING_RESPONSE_FIELDS",
5977
+ SIMULATOR_SCREENSHOT_FAILED: "SIMULATOR_SCREENSHOT_FAILED",
5854
5978
  SIMULATOR_SERVER_FACTORY_OPTIONS_MISSING: "SIMULATOR_SERVER_FACTORY_OPTIONS_MISSING",
5855
5979
  SIMULATOR_SERVER_DEVICE_ID_INVALID: "SIMULATOR_SERVER_DEVICE_ID_INVALID",
5856
5980
  SIMULATOR_SERVER_READY_EXITED: "SIMULATOR_SERVER_READY_EXITED",
@@ -5904,6 +6028,7 @@ var FAILURE_CODES = {
5904
6028
  ANDROID_SCREEN_SIZE_PARSE_FAILED: "ANDROID_SCREEN_SIZE_PARSE_FAILED",
5905
6029
  ANDROID_SCREEN_SIZE_NON_POSITIVE: "ANDROID_SCREEN_SIZE_NON_POSITIVE",
5906
6030
  ANDROID_UIAUTOMATOR_PARSE_FAILED: "ANDROID_UIAUTOMATOR_PARSE_FAILED",
6031
+ ANDROID_UIAUTOMATOR_CAPTURE_FAILED: "ANDROID_UIAUTOMATOR_CAPTURE_FAILED",
5907
6032
  DEBUGGER_METRO_NOT_RUNNING: "DEBUGGER_METRO_NOT_RUNNING",
5908
6033
  DEBUGGER_METRO_PROJECT_ROOT_MISSING: "DEBUGGER_METRO_PROJECT_ROOT_MISSING",
5909
6034
  DEBUGGER_METRO_NO_TARGETS: "DEBUGGER_METRO_NO_TARGETS",
@@ -5948,8 +6073,19 @@ var FAILURE_CODES = {
5948
6073
  NATIVE_PROFILER_XCTRACE_READY_EXITED: "NATIVE_PROFILER_XCTRACE_READY_EXITED",
5949
6074
  NATIVE_PROFILER_XCTRACE_PROCESS_ERROR: "NATIVE_PROFILER_XCTRACE_PROCESS_ERROR",
5950
6075
  NATIVE_PROFILER_XCTRACE_READY_TIMEOUT: "NATIVE_PROFILER_XCTRACE_READY_TIMEOUT",
6076
+ NATIVE_PROFILER_TRACE_TEMPLATE_MISSING: "NATIVE_PROFILER_TRACE_TEMPLATE_MISSING",
5951
6077
  NATIVE_PROFILER_NO_ACTIVE_SESSION: "NATIVE_PROFILER_NO_ACTIVE_SESSION",
6078
+ NATIVE_PROFILER_APP_PROCESS_NOT_FOUND: "NATIVE_PROFILER_APP_PROCESS_NOT_FOUND",
6079
+ NATIVE_PROFILER_NO_EXPORTED_TRACE: "NATIVE_PROFILER_NO_EXPORTED_TRACE",
6080
+ // Android perfetto start-failure modes — mirror the iOS xctrace set so a
6081
+ // failed recording start is classified rather than falling through to the
6082
+ // generic tool-execution bucket.
6083
+ NATIVE_PROFILER_PERFETTO_PROCESS_ERROR: "NATIVE_PROFILER_PERFETTO_PROCESS_ERROR",
6084
+ NATIVE_PROFILER_PERFETTO_READY_TIMEOUT: "NATIVE_PROFILER_PERFETTO_READY_TIMEOUT",
6085
+ NATIVE_PROFILER_PERFETTO_READY_EXITED: "NATIVE_PROFILER_PERFETTO_READY_EXITED",
5952
6086
  FLOW_PROJECT_ROOT_REQUIRED: "FLOW_PROJECT_ROOT_REQUIRED",
6087
+ FLOW_PROJECT_ROOT_INVALID: "FLOW_PROJECT_ROOT_INVALID",
6088
+ FLOW_NAME_INVALID: "FLOW_NAME_INVALID",
5953
6089
  FLOW_NO_ACTIVE_RECORDING: "FLOW_NO_ACTIVE_RECORDING",
5954
6090
  FLOW_FILE_INVALID: "FLOW_FILE_INVALID",
5955
6091
  FLOW_ENTRY_UNRECOGNIZED: "FLOW_ENTRY_UNRECOGNIZED",
@@ -5957,6 +6093,27 @@ var FAILURE_CODES = {
5957
6093
  PROFILER_QUERY_REQUIRED_PARAM_MISSING: "PROFILER_QUERY_REQUIRED_PARAM_MISSING",
5958
6094
  PROFILER_DATA_NOT_LOADED: "PROFILER_DATA_NOT_LOADED",
5959
6095
  PROFILER_NATIVE_TRACE_MISSING: "PROFILER_NATIVE_TRACE_MISSING",
6096
+ PROFILER_NATIVE_METADATA_MISSING: "PROFILER_NATIVE_METADATA_MISSING",
6097
+ PROFILER_NATIVE_METADATA_INVALID: "PROFILER_NATIVE_METADATA_INVALID",
6098
+ CHROMIUM_CDP_UNREACHABLE: "CHROMIUM_CDP_UNREACHABLE",
6099
+ CHROMIUM_CDP_NO_PAGE_TARGET: "CHROMIUM_CDP_NO_PAGE_TARGET",
6100
+ CHROMIUM_CDP_INVALID_RESPONSE: "CHROMIUM_CDP_INVALID_RESPONSE",
6101
+ CHROMIUM_DEVICE_ID_INVALID: "CHROMIUM_DEVICE_ID_INVALID",
6102
+ CHROMIUM_PARAM_INVALID: "CHROMIUM_PARAM_INVALID",
6103
+ CHROMIUM_INPUT_INVALID: "CHROMIUM_INPUT_INVALID",
6104
+ CHROMIUM_VIEWPORT_READ_FAILED: "CHROMIUM_VIEWPORT_READ_FAILED",
6105
+ CHROMIUM_SCREENSHOT_FAILED: "CHROMIUM_SCREENSHOT_FAILED",
6106
+ CHROMIUM_STORAGE_EVAL_FAILED: "CHROMIUM_STORAGE_EVAL_FAILED",
6107
+ CHROMIUM_TAB_NOT_FOUND: "CHROMIUM_TAB_NOT_FOUND",
6108
+ CHROMIUM_TAB_OPEN_FAILED: "CHROMIUM_TAB_OPEN_FAILED",
6109
+ CHROMIUM_DESCRIBE_FAILED: "CHROMIUM_DESCRIBE_FAILED",
6110
+ CHROMIUM_ELECTRON_APP_PATH_INVALID: "CHROMIUM_ELECTRON_APP_PATH_INVALID",
6111
+ CHROMIUM_ELECTRON_SPAWN_FAILED: "CHROMIUM_ELECTRON_SPAWN_FAILED",
6112
+ CHROMIUM_ELECTRON_CDP_TIMEOUT: "CHROMIUM_ELECTRON_CDP_TIMEOUT",
6113
+ CHROMIUM_ELECTRON_EXITED_BEFORE_READY: "CHROMIUM_ELECTRON_EXITED_BEFORE_READY",
6114
+ KEYBOARD_KEY_UNSUPPORTED: "KEYBOARD_KEY_UNSUPPORTED",
6115
+ KEYBOARD_CHARACTER_UNSUPPORTED: "KEYBOARD_CHARACTER_UNSUPPORTED",
6116
+ SCREENSHOT_DIFF_INPUT_INVALID: "SCREENSHOT_DIFF_INPUT_INVALID",
5960
6117
  BOOT_DEVICE_TARGET_SELECTION_INVALID: "BOOT_DEVICE_TARGET_SELECTION_INVALID",
5961
6118
  BOOT_IOS_UNSUPPORTED_HOST: "BOOT_IOS_UNSUPPORTED_HOST",
5962
6119
  BOOT_ANDROID_NO_AVDS: "BOOT_ANDROID_NO_AVDS",
@@ -5995,6 +6152,7 @@ var FAILURE_COMMANDS = [
5995
6152
  "ax_service",
5996
6153
  "simulator_server",
5997
6154
  "cdp",
6155
+ "electron",
5998
6156
  "npm",
5999
6157
  "npx",
6000
6158
  "unknown"
@@ -6028,7 +6186,15 @@ var FAILURE_SPAWN_CODE_SET = new Set(FAILURE_SPAWN_CODES);
6028
6186
  import { randomUUID as randomUUID2 } from "node:crypto";
6029
6187
 
6030
6188
  // ../telemetry/src/events.ts
6031
- var PLATFORMS = ["ios", "ios-remote", "android", "chromium", "vega"];
6189
+ var PLATFORMS = [
6190
+ "ios",
6191
+ "ios-remote",
6192
+ "android",
6193
+ "chromium",
6194
+ "vega",
6195
+ "tvos",
6196
+ "android-tv"
6197
+ ];
6032
6198
 
6033
6199
  // ../telemetry/src/ai-identity.ts
6034
6200
  var AI_CLIENTS = [
@@ -6094,6 +6260,7 @@ var FAILURE_SIGNAL_NAME = oneOf(FAILURE_SIGNAL_NAMES);
6094
6260
  var FAILURE_SPAWN_CODE = oneOf(FAILURE_SPAWN_CODES);
6095
6261
  var NETWORK_FAILURE = oneOf(NETWORK_FAILURES);
6096
6262
  var AI_CLIENT = oneOf(AI_CLIENTS);
6263
+ var INSTALL_MODE = oneOf(["global", "local"]);
6097
6264
  var AI_TELEMETRY = {
6098
6265
  ai_client: AI_CLIENT
6099
6266
  };
@@ -6117,10 +6284,21 @@ var ALLOWED = {
6117
6284
  duration_ms: DURATION_MS,
6118
6285
  is_success: bool,
6119
6286
  editors_configured_count: COUNT,
6287
+ install_mode: INSTALL_MODE,
6120
6288
  ...FAILURE_SIGNAL
6121
6289
  },
6122
6290
  "installation:cli_init_cancel": {
6123
- step: oneOf(["global_install", "editors", "scope", "skills", "allowlist"])
6291
+ step: oneOf([
6292
+ "global_install",
6293
+ "editors",
6294
+ "scope",
6295
+ "skills",
6296
+ "allowlist",
6297
+ "install_mode"
6298
+ ])
6299
+ },
6300
+ "installation:install_mode_decision": {
6301
+ install_mode: INSTALL_MODE
6124
6302
  },
6125
6303
  "installation:global_install_decision": {
6126
6304
  // `from_tar` is intentionally absent; the installer skips that dev path.
@@ -6134,11 +6312,16 @@ var ALLOWED = {
6134
6312
  "installation:editors_select": {
6135
6313
  editors: arrayOf(ADAPTER_NAME),
6136
6314
  detected_editor_count: COUNT,
6137
- scope: oneOf(["local", "global", "custom"])
6315
+ scope: oneOf(["local", "global", "custom"]),
6316
+ install_mode: INSTALL_MODE
6138
6317
  },
6139
6318
  "installation:allowlist_decision": {
6140
6319
  is_enabled: bool
6141
6320
  },
6321
+ "installation:stale_config_cleanup": {
6322
+ removed_count: COUNT,
6323
+ warned_count: COUNT
6324
+ },
6142
6325
  "installation:skill_install": {
6143
6326
  method: oneOf(["default", "interactive", "manual"]),
6144
6327
  is_online: bool,
@@ -6162,16 +6345,19 @@ var ALLOWED = {
6162
6345
  },
6163
6346
  "installation:cli_update_start": {},
6164
6347
  "installation:cli_update_complete": {
6165
- duration_ms: DURATION_MS
6348
+ duration_ms: DURATION_MS,
6349
+ install_mode: INSTALL_MODE
6166
6350
  },
6167
6351
  "installation:cli_update_fail": {
6168
6352
  duration_ms: DURATION_MS,
6353
+ install_mode: INSTALL_MODE,
6169
6354
  ...FAILURE_SIGNAL
6170
6355
  },
6171
6356
  "installation:cli_uninstall_start": {},
6172
6357
  "installation:cli_uninstall_complete": {
6173
6358
  has_pruned_content: bool,
6174
6359
  has_uninstalled_package: bool,
6360
+ install_mode: INSTALL_MODE,
6175
6361
  ...FAILURE_SIGNAL
6176
6362
  },
6177
6363
  "tool:invoke": {
@@ -6256,9 +6442,9 @@ function isReplitAgent(env) {
6256
6442
  }
6257
6443
  var DEVIN_MARKER_PATH = "/opt/.devin";
6258
6444
  var JULES_MARKER_PATH = "/opt/environment_summary.sh";
6259
- function safeExists(fileExists, path12) {
6445
+ function safeExists(fileExists, path13) {
6260
6446
  try {
6261
- return fileExists(path12);
6447
+ return fileExists(path13);
6262
6448
  } catch {
6263
6449
  return false;
6264
6450
  }
@@ -6679,7 +6865,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
6679
6865
  var SESSION_ID2 = randomUUID3();
6680
6866
  function readCliVersion() {
6681
6867
  if (true) {
6682
- return "0.14.0";
6868
+ return "0.15.0";
6683
6869
  }
6684
6870
  return "0.0.0";
6685
6871
  }
@@ -6958,17 +7144,141 @@ function debugLogPath() {
6958
7144
  }
6959
7145
 
6960
7146
  // ../telemetry/src/identity.ts
7147
+ var FINGERPRINT_PATTERN = /^[0-9a-f]{64}$/;
6961
7148
  var cached = null;
6962
- function readOrCreateAnonId() {
7149
+ var fingerprintResolved = null;
7150
+ var upgradeInFlight = false;
7151
+ var upgradeAttempts = 0;
7152
+ var upgradeLastAttemptMs = 0;
7153
+ var UPGRADE_COOLDOWN_MS = 6e4;
7154
+ var UPGRADE_MAX_ATTEMPTS = 3;
7155
+ function readOrCreateAnonId(resolveFingerprint) {
7156
+ const finalPath = identityFilePath();
7157
+ if (cached && cached.path === finalPath && FINGERPRINT_PATTERN.test(cached.id)) {
7158
+ return cached.id;
7159
+ }
7160
+ const stored = tryReadId(finalPath);
7161
+ if (stored && FINGERPRINT_PATTERN.test(stored)) {
7162
+ cached = { path: finalPath, id: stored };
7163
+ return stored;
7164
+ }
7165
+ if (stored) {
7166
+ cached = { path: finalPath, id: stored };
7167
+ return stored;
7168
+ }
7169
+ const target = resolveFingerprintOnce(resolveFingerprint);
7170
+ if (target) {
7171
+ try {
7172
+ writeIdFileAtomic(finalPath, target);
7173
+ } catch {
7174
+ }
7175
+ cached = { path: finalPath, id: target };
7176
+ return target;
7177
+ }
7178
+ return mintRandomId(finalPath);
7179
+ }
7180
+ function scheduleFingerprintUpgrade(resolveFingerprintAsync) {
7181
+ if (!resolveFingerprintAsync) return;
7182
+ if (upgradeInFlight) return;
6963
7183
  const finalPath = identityFilePath();
6964
- if (cached && cached.path === finalPath) return cached.id;
6965
- const existing = tryReadId(finalPath);
6966
- if (existing) {
6967
- cached = { path: finalPath, id: existing };
6968
- return existing;
7184
+ if (servedFingerprintId(finalPath)) return;
7185
+ if (upgradeAttempts >= UPGRADE_MAX_ATTEMPTS) return;
7186
+ const now = Date.now();
7187
+ if (upgradeAttempts > 0 && now - upgradeLastAttemptMs < UPGRADE_COOLDOWN_MS) return;
7188
+ upgradeInFlight = true;
7189
+ upgradeAttempts += 1;
7190
+ upgradeLastAttemptMs = now;
7191
+ void Promise.resolve().then(() => resolveFingerprintAsync()).then((raw) => {
7192
+ const fp = normalizeFingerprint(raw);
7193
+ if (fp) adoptFingerprint(fp);
7194
+ }).catch(() => {
7195
+ }).finally(() => {
7196
+ upgradeInFlight = false;
7197
+ });
7198
+ }
7199
+ function servedFingerprintId(finalPath) {
7200
+ if (cached && cached.path === finalPath && FINGERPRINT_PATTERN.test(cached.id)) {
7201
+ return cached.id;
7202
+ }
7203
+ const stored = tryReadId(finalPath);
7204
+ if (stored && FINGERPRINT_PATTERN.test(stored)) {
7205
+ cached = { path: finalPath, id: stored };
7206
+ return stored;
6969
7207
  }
7208
+ return null;
7209
+ }
7210
+ function normalizeFingerprint(raw) {
7211
+ if (!raw) return null;
7212
+ const normalized = raw.trim().toLowerCase();
7213
+ return FINGERPRINT_PATTERN.test(normalized) ? normalized : null;
7214
+ }
7215
+ function adoptFingerprint(fp) {
7216
+ const finalPath = identityFilePath();
7217
+ const stored = tryReadId(finalPath);
7218
+ if (stored !== fp) {
7219
+ try {
7220
+ writeIdFileAtomic(finalPath, fp);
7221
+ } catch {
7222
+ }
7223
+ }
7224
+ cached = { path: finalPath, id: fp };
7225
+ }
7226
+ function resolveFingerprintOnce(resolveFingerprint) {
7227
+ if (!resolveFingerprint) return null;
7228
+ if (fingerprintResolved) return fingerprintResolved.value;
7229
+ let raw;
7230
+ try {
7231
+ raw = resolveFingerprint();
7232
+ } catch {
7233
+ raw = null;
7234
+ }
7235
+ const value = normalizeFingerprint(raw);
7236
+ fingerprintResolved = { value };
7237
+ return value;
7238
+ }
7239
+ function isCorruptIdFile(filePath) {
7240
+ let isRegularFile;
7241
+ try {
7242
+ isRegularFile = fs4.lstatSync(filePath).isFile();
7243
+ } catch {
7244
+ return false;
7245
+ }
7246
+ return isRegularFile && tryReadId(filePath) === null;
7247
+ }
7248
+ function writeIdFileAtomic(finalPath, id) {
6970
7249
  fs4.mkdirSync(argentHomeDir(), { recursive: true });
6971
- const uuid = crypto2.randomUUID();
7250
+ let occupant;
7251
+ try {
7252
+ occupant = fs4.lstatSync(finalPath);
7253
+ } catch (err) {
7254
+ if (err.code !== "ENOENT") throw err;
7255
+ }
7256
+ if (occupant && !occupant.isFile()) {
7257
+ throw new Error("telemetry: refusing to replace a non-regular file at the identity path");
7258
+ }
7259
+ const tmpPath = path8.join(
7260
+ argentHomeDir(),
7261
+ `.telemetry-id.tmp.${process.pid}.${crypto2.randomUUID()}`
7262
+ );
7263
+ const fd = fs4.openSync(tmpPath, "wx", 384);
7264
+ try {
7265
+ try {
7266
+ fs4.writeSync(fd, id);
7267
+ fs4.fsyncSync(fd);
7268
+ } finally {
7269
+ fs4.closeSync(fd);
7270
+ }
7271
+ fs4.renameSync(tmpPath, finalPath);
7272
+ } finally {
7273
+ try {
7274
+ fs4.unlinkSync(tmpPath);
7275
+ } catch {
7276
+ }
7277
+ }
7278
+ }
7279
+ function mintRandomId(finalPath) {
7280
+ fs4.mkdirSync(argentHomeDir(), { recursive: true });
7281
+ let value = crypto2.randomUUID();
6972
7282
  for (let attempt = 0; attempt < 3; attempt++) {
6973
7283
  const tmpPath = path8.join(
6974
7284
  argentHomeDir(),
@@ -6983,14 +7293,14 @@ function readOrCreateAnonId() {
6983
7293
  }
6984
7294
  try {
6985
7295
  try {
6986
- fs4.writeSync(fd, uuid);
7296
+ fs4.writeSync(fd, value);
6987
7297
  fs4.fsyncSync(fd);
6988
7298
  } finally {
6989
7299
  fs4.closeSync(fd);
6990
7300
  }
6991
7301
  fs4.linkSync(tmpPath, finalPath);
6992
- cached = { path: finalPath, id: uuid };
6993
- return uuid;
7302
+ cached = { path: finalPath, id: value };
7303
+ return value;
6994
7304
  } catch (err) {
6995
7305
  if (err.code === "EEXIST") {
6996
7306
  const beatUs = tryReadId(finalPath);
@@ -6998,6 +7308,10 @@ function readOrCreateAnonId() {
6998
7308
  cached = { path: finalPath, id: beatUs };
6999
7309
  return beatUs;
7000
7310
  }
7311
+ if (isCorruptIdFile(finalPath)) {
7312
+ const adopted = claimCorruptOccupant(finalPath);
7313
+ if (adopted) value = adopted;
7314
+ }
7001
7315
  continue;
7002
7316
  }
7003
7317
  throw err;
@@ -7008,7 +7322,28 @@ function readOrCreateAnonId() {
7008
7322
  }
7009
7323
  }
7010
7324
  }
7011
- throw new Error("telemetry: failed to create anonymous identity after retries");
7325
+ throw new Error("telemetry: failed to create identity after retries");
7326
+ }
7327
+ function claimCorruptOccupant(finalPath) {
7328
+ const claimed = path8.join(
7329
+ argentHomeDir(),
7330
+ `.telemetry-id.corrupt.${process.pid}.${crypto2.randomUUID()}`
7331
+ );
7332
+ try {
7333
+ fs4.renameSync(finalPath, claimed);
7334
+ } catch {
7335
+ return null;
7336
+ }
7337
+ let grabbed;
7338
+ try {
7339
+ grabbed = tryReadId(claimed);
7340
+ } finally {
7341
+ try {
7342
+ fs4.unlinkSync(claimed);
7343
+ } catch {
7344
+ }
7345
+ }
7346
+ return grabbed;
7012
7347
  }
7013
7348
  function peekAnonId() {
7014
7349
  return tryReadId(identityFilePath());
@@ -7028,14 +7363,120 @@ function tryReadId(filePath) {
7028
7363
  return null;
7029
7364
  }
7030
7365
 
7031
- // ../telemetry/src/consent.ts
7366
+ // ../telemetry/src/fingerprint.ts
7367
+ import { execFileSync as execFileSync2, spawn as spawn2 } from "node:child_process";
7368
+
7369
+ // ../native-devtools-ios/src/index.ts
7370
+ import * as path9 from "node:path";
7032
7371
  import * as fs5 from "node:fs";
7372
+ var DYLIB_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_DIR ?? path9.join(__dirname, "..", "dylibs");
7373
+ var BIN_DIR = process.env.ARGENT_SIMULATOR_SERVER_DIR ?? path9.join(__dirname, "..", "bin");
7374
+ var DYLIB_TCP_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_TCP_DIR ?? path9.join(DYLIB_DIR, "tcp");
7375
+ var DYLIB_TVOS_DIR = path9.join(DYLIB_DIR, "tvos");
7376
+ function hostPlatformKey() {
7377
+ if (process.platform === "linux" && process.arch === "arm64") {
7378
+ return "linux-arm64";
7379
+ }
7380
+ return process.platform;
7381
+ }
7382
+ function platformBinDir() {
7383
+ return path9.join(BIN_DIR, hostPlatformKey());
7384
+ }
7385
+ function simulatorServerBinaryPath() {
7386
+ const p = path9.join(platformBinDir(), "simulator-server");
7387
+ if (!fs5.existsSync(p)) {
7388
+ const flat = path9.join(BIN_DIR, "simulator-server");
7389
+ const migrationHint = fs5.existsSync(flat) ? ` Found a binary at the old flat path ${flat}; move it to ${p} or update ARGENT_SIMULATOR_SERVER_DIR to point at the parent of the platform subdirectory.` : "";
7390
+ throw new Error(
7391
+ `simulator-server binary not found for platform "${hostPlatformKey()}" at ${p}. Supported hosts today: darwin, linux (x86_64 and arm64).${migrationHint}`
7392
+ );
7393
+ }
7394
+ return p;
7395
+ }
7396
+
7397
+ // ../telemetry/src/fingerprint.ts
7398
+ var FINGERPRINT_TIMEOUT_MS = 5e3;
7399
+ var FINGERPRINT_MAX_BUFFER = 4096;
7400
+ function resolveHostFingerprint() {
7401
+ try {
7402
+ const out = execFileSync2(simulatorServerBinaryPath(), ["fingerprint"], {
7403
+ encoding: "utf8",
7404
+ timeout: FINGERPRINT_TIMEOUT_MS,
7405
+ // Reap with SIGKILL, not the default SIGTERM: a binary that ignores SIGTERM
7406
+ // would otherwise block the (synchronous) event loop past the cap forever.
7407
+ // SIGKILL can't be trapped, so the timeout is a genuine bound here.
7408
+ killSignal: "SIGKILL",
7409
+ // Cap captured stdout (same limit as the async variant): a binary streaming
7410
+ // output is SIGKILL'd at this cap rather than filling Node's 1 MiB default.
7411
+ maxBuffer: FINGERPRINT_MAX_BUFFER,
7412
+ // Ignore stderr so a binary that logs diagnostics doesn't pollute the
7413
+ // caller's stderr; stdout (index 1) is captured as the return value.
7414
+ stdio: ["ignore", "pipe", "ignore"]
7415
+ }).trim();
7416
+ return out.length > 0 ? out : null;
7417
+ } catch {
7418
+ return null;
7419
+ }
7420
+ }
7421
+ function resolveHostFingerprintAsync() {
7422
+ return new Promise((resolve4) => {
7423
+ let binary;
7424
+ try {
7425
+ binary = simulatorServerBinaryPath();
7426
+ } catch {
7427
+ resolve4(null);
7428
+ return;
7429
+ }
7430
+ let settled = false;
7431
+ let child;
7432
+ const finish = (value) => {
7433
+ if (settled) return;
7434
+ settled = true;
7435
+ clearTimeout(watchdog);
7436
+ try {
7437
+ child?.kill("SIGKILL");
7438
+ } catch {
7439
+ }
7440
+ resolve4(value);
7441
+ };
7442
+ const watchdog = setTimeout(() => finish(null), FINGERPRINT_TIMEOUT_MS);
7443
+ watchdog.unref?.();
7444
+ try {
7445
+ child = spawn2(binary, ["fingerprint"], { stdio: ["ignore", "pipe", "ignore"] });
7446
+ } catch {
7447
+ finish(null);
7448
+ return;
7449
+ }
7450
+ let out = "";
7451
+ let overflowed = false;
7452
+ child.stdout?.setEncoding("utf8");
7453
+ child.stdout?.on("data", (chunk) => {
7454
+ if (overflowed) return;
7455
+ out += chunk;
7456
+ if (out.length > FINGERPRINT_MAX_BUFFER) {
7457
+ overflowed = true;
7458
+ finish(null);
7459
+ }
7460
+ });
7461
+ child.on("error", () => finish(null));
7462
+ child.on("close", (code) => {
7463
+ if (overflowed) return;
7464
+ const trimmed = out.trim();
7465
+ finish(code === 0 && trimmed.length > 0 ? trimmed : null);
7466
+ });
7467
+ child.unref?.();
7468
+ child.stdout?.unref?.();
7469
+ });
7470
+ }
7471
+
7472
+ // ../telemetry/src/consent.ts
7473
+ import * as fs6 from "node:fs";
7033
7474
  var cache = { current: null };
7034
7475
  var sessionOverride = null;
7035
7476
  function readConfigOverride() {
7036
7477
  let stats;
7037
7478
  try {
7038
- stats = fs5.lstatSync(configFilePath());
7479
+ stats = fs6.lstatSync(configFilePath());
7039
7480
  } catch (err) {
7040
7481
  if (err.code === "ENOENT") {
7041
7482
  cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
@@ -7055,7 +7496,7 @@ function readConfigOverride() {
7055
7496
  }
7056
7497
  let parsedEnabled = null;
7057
7498
  try {
7058
- const raw = fs5.readFileSync(configFilePath(), "utf8");
7499
+ const raw = fs6.readFileSync(configFilePath(), "utf8");
7059
7500
  const json = JSON.parse(raw);
7060
7501
  if (json && typeof json === "object") {
7061
7502
  const t2 = json.telemetry;
@@ -7116,7 +7557,7 @@ function writeConsentFlag(enabled) {
7116
7557
  }
7117
7558
 
7118
7559
  // ../telemetry/src/debug.ts
7119
- import * as fs6 from "node:fs";
7560
+ import * as fs7 from "node:fs";
7120
7561
  function isDebugEnabled(env = process.env) {
7121
7562
  const v = env.ARGENT_TELEMETRY_DEBUG;
7122
7563
  if (!v) return false;
@@ -7143,8 +7584,8 @@ function emitDebugPayload(payload) {
7143
7584
  } catch {
7144
7585
  }
7145
7586
  try {
7146
- fs6.mkdirSync(argentHomeDir(), { recursive: true });
7147
- fs6.appendFileSync(debugLogPath(), line + "\n");
7587
+ fs7.mkdirSync(argentHomeDir(), { recursive: true });
7588
+ fs7.appendFileSync(debugLogPath(), line + "\n");
7148
7589
  } catch {
7149
7590
  }
7150
7591
  }
@@ -7162,8 +7603,8 @@ function emitDebugError(prefix, err) {
7162
7603
  var TELEMETRY_OPT_OUT_COMMAND = "argent telemetry disable";
7163
7604
  var TELEMETRY_DETAILS_URL = "https://swmansion.com/legal/argent/privacy-notice/";
7164
7605
  var FIRST_RUN_NOTICE_BODY_LINES = [
7165
- "Argent collects anonymous usage data to help us improve the tool. We never",
7166
- "collect your source code, file paths, tool inputs, or error contents."
7606
+ "Argent collects usage data to help us improve the tool.",
7607
+ "We never collect your source code, file paths, tool inputs, or error contents."
7167
7608
  ];
7168
7609
  var FIRST_RUN_NOTICE = [
7169
7610
  ...FIRST_RUN_NOTICE_BODY_LINES,
@@ -7187,11 +7628,12 @@ function activeRuntime() {
7187
7628
  function buildPayload(event, props) {
7188
7629
  let distinctId;
7189
7630
  try {
7190
- distinctId = readOrCreateAnonId();
7631
+ distinctId = readOrCreateAnonId(resolveHostFingerprint);
7191
7632
  } catch (err) {
7192
7633
  emitDebugError("buildPayload: identity creation failed", err);
7193
7634
  return null;
7194
7635
  }
7636
+ scheduleFingerprintUpgrade(resolveHostFingerprintAsync);
7195
7637
  const base = getBaseProps(activeRuntime());
7196
7638
  const sanitized = sanitize(event, props);
7197
7639
  const properties = { ...base, ...sanitized };
@@ -7234,7 +7676,7 @@ async function shutdown(timeoutMs = SHORT_FLUSH_TIMEOUT_MS) {
7234
7676
  try {
7235
7677
  await Promise.race([
7236
7678
  client2.shutdown(timeoutMs),
7237
- new Promise((resolve3) => setTimeout(resolve3, timeoutMs + 250).unref())
7679
+ new Promise((resolve4) => setTimeout(resolve4, timeoutMs + 250).unref())
7238
7680
  ]);
7239
7681
  } catch (err) {
7240
7682
  emitDebugError("shutdown failed", err);
@@ -7254,7 +7696,7 @@ async function markDisabled() {
7254
7696
  try {
7255
7697
  await Promise.race([
7256
7698
  client2.shutdown(SHORT_FLUSH_TIMEOUT_MS),
7257
- new Promise((resolve3) => setTimeout(resolve3, SHORT_FLUSH_TIMEOUT_MS).unref())
7699
+ new Promise((resolve4) => setTimeout(resolve4, SHORT_FLUSH_TIMEOUT_MS).unref())
7258
7700
  ]);
7259
7701
  } catch {
7260
7702
  }
@@ -7321,6 +7763,7 @@ function parseJsonOrThrow(raw, label) {
7321
7763
  }
7322
7764
  function parseFlags(argv, schema) {
7323
7765
  const properties = schema?.properties ?? {};
7766
+ const argsHatchHint = properties.args === void 0 ? " or --args '<json>'" : "";
7324
7767
  const args = {};
7325
7768
  const positional = [];
7326
7769
  let helpRequested = false;
@@ -7356,7 +7799,7 @@ function parseFlags(argv, schema) {
7356
7799
  } else {
7357
7800
  flag = tok.slice(2);
7358
7801
  }
7359
- if (flag === "args") {
7802
+ if (flag === "args" && properties.args === void 0) {
7360
7803
  const { value: value2, nextIndex: nextIndex2 } = inlineValue !== void 0 ? { value: inlineValue, nextIndex: i2 } : takeNext(i2, "args");
7361
7804
  rawArgs = value2;
7362
7805
  i2 = nextIndex2;
@@ -7367,7 +7810,7 @@ function parseFlags(argv, schema) {
7367
7810
  const { value: value2, nextIndex: nextIndex2 } = inlineValue !== void 0 ? { value: inlineValue, nextIndex: i2 } : takeNext(i2, flag);
7368
7811
  if (seenArrayFields.has(fieldName)) {
7369
7812
  throw new FlagParseException(
7370
- `--${fieldName} and --${flag} cannot be mixed for the same field; pass it entirely as --${flag} '<json>' or --args '<json>'`
7813
+ `--${fieldName} and --${flag} cannot be mixed for the same field; pass it entirely as --${flag} '<json>'${argsHatchHint}`
7371
7814
  );
7372
7815
  }
7373
7816
  args[fieldName] = parseJsonOrThrow(value2, `--${flag}`);
@@ -7399,13 +7842,13 @@ function parseFlags(argv, schema) {
7399
7842
  const itemType = propSchema.items?.type;
7400
7843
  if (!isScalarType(itemType)) {
7401
7844
  throw new FlagParseException(
7402
- `--${flag} is an array of objects; pass it as --${flag}-json '<json>' or --args '<json>'`
7845
+ `--${flag} is an array of objects; pass it as --${flag}-json '<json>'${argsHatchHint}`
7403
7846
  );
7404
7847
  }
7405
7848
  const { value: value2, nextIndex: nextIndex2 } = inlineValue !== void 0 ? { value: inlineValue, nextIndex: i2 } : takeNext(i2, flag);
7406
7849
  if (jsonFields.has(flag)) {
7407
7850
  throw new FlagParseException(
7408
- `--${flag} and --${flag}-json cannot be mixed for the same field; pass it entirely as --${flag}-json '<json>' or --args '<json>'`
7851
+ `--${flag} and --${flag}-json cannot be mixed for the same field; pass it entirely as --${flag}-json '<json>'${argsHatchHint}`
7409
7852
  );
7410
7853
  }
7411
7854
  const coerced = coerceScalar(value2, itemType, flag);
@@ -7420,7 +7863,7 @@ function parseFlags(argv, schema) {
7420
7863
  }
7421
7864
  if (propSchema?.type === "object") {
7422
7865
  throw new FlagParseException(
7423
- `--${flag} is an object; pass it as --${flag}-json '<json>' or --args '<json>'`
7866
+ `--${flag} is an object; pass it as --${flag}-json '<json>'${argsHatchHint}`
7424
7867
  );
7425
7868
  }
7426
7869
  const { value, nextIndex } = inlineValue !== void 0 ? { value: inlineValue, nextIndex: i2 } : takeNext(i2, flag);
@@ -7495,27 +7938,31 @@ function splitOptions(argv) {
7495
7938
  return { json, outPath, argvForFlags: rest };
7496
7939
  }
7497
7940
  async function readStdin() {
7498
- return new Promise((resolve3, reject) => {
7941
+ return new Promise((resolve4, reject) => {
7499
7942
  let data = "";
7500
7943
  process.stdin.setEncoding("utf8");
7501
7944
  process.stdin.on("data", (chunk) => {
7502
7945
  data += chunk;
7503
7946
  });
7504
- process.stdin.on("end", () => resolve3(data));
7947
+ process.stdin.on("end", () => resolve4(data));
7505
7948
  process.stdin.on("error", reject);
7506
7949
  });
7507
7950
  }
7508
7951
  function printToolHelp(meta) {
7509
7952
  const description = meta.description?.trim() ?? "";
7953
+ const schema = meta.inputSchema;
7954
+ const hasOwnArgsField = schema?.properties?.args !== void 0;
7510
7955
  console.log(`argent run ${meta.name} [flags]`);
7511
7956
  if (description) console.log(`
7512
7957
  ${description}
7513
7958
  `);
7514
7959
  console.log("Flags:");
7515
- console.log(formatSchemaUsage(meta.inputSchema));
7960
+ console.log(formatSchemaUsage(schema));
7516
7961
  console.log("\nGlobal flags:");
7517
- console.log(" --args <json> Pass the entire payload as JSON (overrides flags)");
7518
- console.log(" --args - Read the entire payload as JSON from stdin");
7962
+ if (!hasOwnArgsField) {
7963
+ console.log(" --args <json> Pass the entire payload as JSON (overrides flags)");
7964
+ console.log(" --args - Read the entire payload as JSON from stdin");
7965
+ }
7519
7966
  console.log(" --<field>-json <json> Pass a single field as JSON (objects/nested arrays)");
7520
7967
  console.log(" --json Print the raw JSON result");
7521
7968
  console.log(" --out <path> For image results, save to <path> instead of fetching URL");
@@ -7529,8 +7976,8 @@ async function fetchImageToFile(result, outPath) {
7529
7976
  const res = await fetch(url);
7530
7977
  if (!res.ok) throw new Error(`Failed to download image: ${res.status} ${res.statusText}`);
7531
7978
  const buf = Buffer.from(await res.arrayBuffer());
7532
- fs7.mkdirSync(path9.dirname(path9.resolve(outPath)), { recursive: true });
7533
- fs7.writeFileSync(outPath, buf);
7979
+ fs8.mkdirSync(path10.dirname(path10.resolve(outPath)), { recursive: true });
7980
+ fs8.writeFileSync(outPath, buf);
7534
7981
  }
7535
7982
  function renderResult(result, outputHint, images, json) {
7536
7983
  if (json) return JSON.stringify(result, null, 2);
@@ -7669,8 +8116,8 @@ Examples:
7669
8116
  if (outPath && meta.outputHint === "image") {
7670
8117
  try {
7671
8118
  if (images.length > 0) {
7672
- fs7.mkdirSync(path9.dirname(path9.resolve(outPath)), { recursive: true });
7673
- fs7.writeFileSync(outPath, images[0].data);
8119
+ fs8.mkdirSync(path10.dirname(path10.resolve(outPath)), { recursive: true });
8120
+ fs8.writeFileSync(outPath, images[0].data);
7674
8121
  } else if (result && typeof result === "object") {
7675
8122
  await fetchImageToFile(result, outPath);
7676
8123
  }
@@ -7770,27 +8217,29 @@ Options:
7770
8217
  }
7771
8218
 
7772
8219
  // ../argent-cli/src/server.ts
7773
- import * as fs8 from "node:fs";
7774
- import * as path10 from "node:path";
8220
+ import * as fs9 from "node:fs";
8221
+ import * as path11 from "node:path";
7775
8222
  import { homedir as homedir5, networkInterfaces } from "node:os";
7776
- import { spawn as spawn2 } from "node:child_process";
7777
- var STATE_DIR2 = path10.join(homedir5(), ".argent");
7778
- var STATE_FILE2 = path10.join(STATE_DIR2, "tool-server.json");
7779
- var LOG_FILE2 = path10.join(STATE_DIR2, "tool-server.log");
7780
- function readState2() {
7781
- try {
7782
- return JSON.parse(fs8.readFileSync(STATE_FILE2, "utf8"));
7783
- } catch {
7784
- return null;
7785
- }
8223
+ import { spawn as spawn3 } from "node:child_process";
8224
+ var STATE_DIR2 = path11.join(homedir5(), ".argent");
8225
+ var LOG_FILE2 = path11.join(STATE_DIR2, "tool-server.log");
8226
+ async function describeForeignServers(ownBundlePath) {
8227
+ const others = (await readAllToolsServerStates()).filter(
8228
+ ({ state: state2 }) => state2.bundlePath !== ownBundlePath && isToolsServerProcessAlive(state2.pid)
8229
+ );
8230
+ if (others.length === 0) return null;
8231
+ const list = others.map(({ state: state2 }) => `pid ${state2.pid} (${state2.bundlePath})`).join(", ");
8232
+ return `Note: ${others.length} tool-server(s) from other argent installs: ${list}`;
7786
8233
  }
7787
- async function statusCmd(json) {
7788
- const state2 = readState2();
8234
+ async function statusCmd(json, paths) {
8235
+ const state2 = await readToolsServerState(paths?.bundlePath);
7789
8236
  if (!state2) {
8237
+ const foreign = await describeForeignServers(paths?.bundlePath);
7790
8238
  if (json) {
7791
8239
  console.log(JSON.stringify({ running: false }, null, 2));
7792
8240
  } else {
7793
- console.log("tool-server: not running (no state file)");
8241
+ console.log("tool-server: not running (no state file for this install)");
8242
+ if (foreign) console.log(foreign);
7794
8243
  }
7795
8244
  return;
7796
8245
  }
@@ -7819,25 +8268,28 @@ async function statusCmd(json) {
7819
8268
  State file is stale; next \`argent\` invocation will respawn the server.`);
7820
8269
  }
7821
8270
  }
7822
- async function stopCmd() {
7823
- const state2 = readState2();
8271
+ async function stopCmd(paths) {
8272
+ const state2 = await readToolsServerState(paths?.bundlePath);
7824
8273
  if (!state2) {
7825
8274
  console.log("tool-server: not running");
8275
+ const foreign = await describeForeignServers(paths?.bundlePath);
8276
+ if (foreign) console.log(`${foreign}
8277
+ Stop one with: kill <pid>`);
7826
8278
  return;
7827
8279
  }
7828
- await killToolServer();
8280
+ await killToolServer(paths?.bundlePath);
7829
8281
  console.log(`tool-server stopped (pid ${state2.pid}).`);
7830
8282
  }
7831
8283
  function logsCmd(follow) {
7832
- if (!fs8.existsSync(LOG_FILE2)) {
8284
+ if (!fs9.existsSync(LOG_FILE2)) {
7833
8285
  console.log(`No log file at ${LOG_FILE2}`);
7834
8286
  return;
7835
8287
  }
7836
8288
  if (!follow) {
7837
- process.stdout.write(fs8.readFileSync(LOG_FILE2, "utf8"));
8289
+ process.stdout.write(fs9.readFileSync(LOG_FILE2, "utf8"));
7838
8290
  return;
7839
8291
  }
7840
- const child = spawn2("tail", ["-f", LOG_FILE2], { stdio: "inherit" });
8292
+ const child = spawn3("tail", ["-f", LOG_FILE2], { stdio: "inherit" });
7841
8293
  child.on("exit", (code) => process.exit(code ?? 0));
7842
8294
  }
7843
8295
  var StartFlagError = class extends Error {
@@ -7981,11 +8433,11 @@ function printConnectionInfo(bindHost, port, token) {
7981
8433
  );
7982
8434
  }
7983
8435
  }
7984
- async function ensureNoExistingServer(force) {
7985
- const state2 = await readToolsServerState();
8436
+ async function ensureNoExistingServer(force, paths) {
8437
+ const state2 = await readToolsServerState(paths.bundlePath);
7986
8438
  if (!state2) return;
7987
8439
  const alive = isToolsServerProcessAlive(state2.pid);
7988
- const healthy = alive ? await isToolsServerHealthy(state2.port, state2.host ?? "127.0.0.1") : false;
8440
+ const healthy = alive ? await isToolsServerHealthy(state2.port, state2.host ?? "127.0.0.1", 2e3, state2.token) : false;
7989
8441
  if (alive && healthy && !force) {
7990
8442
  const url = formatUrl(state2.host ?? "127.0.0.1", state2.port);
7991
8443
  throw new StartFlagError(
@@ -7994,9 +8446,9 @@ Use \`argent server stop\` first, or pass \`--force\` to replace it.`
7994
8446
  );
7995
8447
  }
7996
8448
  if (alive && force) {
7997
- await killToolServer();
8449
+ await killToolServer(paths.bundlePath);
7998
8450
  } else {
7999
- await clearToolsServerState();
8451
+ await clearToolsServerState(paths.bundlePath);
8000
8452
  }
8001
8453
  }
8002
8454
  async function resolvePort(requested) {
@@ -8026,7 +8478,7 @@ async function startCmd(argv, paths) {
8026
8478
  return;
8027
8479
  }
8028
8480
  try {
8029
- await ensureNoExistingServer(flags2.force);
8481
+ await ensureNoExistingServer(flags2.force, paths);
8030
8482
  } catch (err) {
8031
8483
  if (err instanceof StartFlagError) {
8032
8484
  console.error(err.message);
@@ -8086,7 +8538,7 @@ async function runForeground(paths, port, host, idleTimeoutMinutes, token) {
8086
8538
  idleTimeoutMinutes,
8087
8539
  token
8088
8540
  });
8089
- const child = spawn2("node", [paths.bundlePath, "start"], {
8541
+ const child = spawn3("node", [paths.bundlePath, "start"], {
8090
8542
  stdio: "inherit",
8091
8543
  env
8092
8544
  });
@@ -8124,7 +8576,7 @@ async function runForeground(paths, port, host, idleTimeoutMinutes, token) {
8124
8576
  process.removeListener("SIGINT", onInt);
8125
8577
  process.removeListener("SIGTERM", onTerm);
8126
8578
  if (stateWritten) {
8127
- clearToolsServerState().catch(() => {
8579
+ clearToolsServerState(paths.bundlePath).catch(() => {
8128
8580
  });
8129
8581
  }
8130
8582
  };
@@ -8162,10 +8614,10 @@ async function server(argv, options) {
8162
8614
  await startCmd(argv.slice(1), options?.paths);
8163
8615
  return;
8164
8616
  case "status":
8165
- await statusCmd(json);
8617
+ await statusCmd(json, options?.paths);
8166
8618
  return;
8167
8619
  case "stop":
8168
- await stopCmd();
8620
+ await stopCmd(options?.paths);
8169
8621
  return;
8170
8622
  case "logs":
8171
8623
  logsCmd(follow);
@@ -8177,22 +8629,22 @@ async function server(argv, options) {
8177
8629
  }
8178
8630
 
8179
8631
  // ../argent-cli/src/lens.ts
8180
- import * as fs9 from "node:fs";
8632
+ import * as fs10 from "node:fs";
8181
8633
  import * as os2 from "node:os";
8182
- import * as path11 from "node:path";
8634
+ import * as path12 from "node:path";
8183
8635
 
8184
8636
  // ../argent-cli/src/lens-terminal.ts
8185
- import { execFileSync as execFileSync2 } from "node:child_process";
8186
- import { existsSync as existsSync5 } from "node:fs";
8637
+ import { execFileSync as execFileSync3 } from "node:child_process";
8638
+ import { existsSync as existsSync6 } from "node:fs";
8187
8639
  var ITERM_PATHS = ["/Applications/iTerm.app", `${process.env.HOME ?? ""}/Applications/iTerm.app`];
8188
- function isITermInstalled(existsSync7 = defaultExists) {
8189
- return ITERM_PATHS.some((p) => p && existsSync7(p));
8640
+ function isITermInstalled(existsSync8 = defaultExists) {
8641
+ return ITERM_PATHS.some((p) => p && existsSync8(p));
8190
8642
  }
8191
8643
  function defaultExists(p) {
8192
- return existsSync5(p);
8644
+ return existsSync6(p);
8193
8645
  }
8194
- function resolveTerminal(preferred = "iterm", existsSync7 = defaultExists) {
8195
- if (preferred === "iterm" && isITermInstalled(existsSync7)) return "iterm";
8646
+ function resolveTerminal(preferred = "iterm", existsSync8 = defaultExists) {
8647
+ if (preferred === "iterm" && isITermInstalled(existsSync8)) return "iterm";
8196
8648
  return "terminal";
8197
8649
  }
8198
8650
  function escapeAppleScript(s) {
@@ -8341,7 +8793,7 @@ function parseAliveTtys(psOutput) {
8341
8793
  }
8342
8794
  function runOsascript(script) {
8343
8795
  try {
8344
- return execFileSync2("/usr/bin/osascript", ["-e", script], {
8796
+ return execFileSync3("/usr/bin/osascript", ["-e", script], {
8345
8797
  encoding: "utf8",
8346
8798
  stdio: ["ignore", "pipe", "pipe"]
8347
8799
  });
@@ -8383,7 +8835,7 @@ function pressEnter(session) {
8383
8835
  }
8384
8836
  function aliveTtys() {
8385
8837
  try {
8386
- const out = execFileSync2("/bin/ps", ["-A", "-o", "tty="], { encoding: "utf8" });
8838
+ const out = execFileSync3("/bin/ps", ["-A", "-o", "tty="], { encoding: "utf8" });
8387
8839
  return parseAliveTtys(out);
8388
8840
  } catch {
8389
8841
  return /* @__PURE__ */ new Set();
@@ -8420,7 +8872,7 @@ function ptyInjectBeats(text2) {
8420
8872
  ];
8421
8873
  }
8422
8874
  function sleep(ms) {
8423
- return new Promise((resolve3) => setTimeout(resolve3, ms));
8875
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
8424
8876
  }
8425
8877
  var DEFAULT_COLS = 80;
8426
8878
  var DEFAULT_ROWS = 24;
@@ -8578,7 +9030,7 @@ async function* lensEvents(baseUrl, signal) {
8578
9030
  }
8579
9031
 
8580
9032
  // ../argent-cli/src/lens-agents.ts
8581
- import { execFileSync as execFileSync3 } from "node:child_process";
9033
+ import { execFileSync as execFileSync4 } from "node:child_process";
8582
9034
  var AGENTS = [
8583
9035
  {
8584
9036
  id: "claude",
@@ -8620,7 +9072,7 @@ function agentIds() {
8620
9072
  }
8621
9073
  function defaultIsOnPath(bin) {
8622
9074
  try {
8623
- execFileSync3(process.platform === "win32" ? "where" : "which", [bin], {
9075
+ execFileSync4(process.platform === "win32" ? "where" : "which", [bin], {
8624
9076
  stdio: ["ignore", "ignore", "ignore"]
8625
9077
  });
8626
9078
  return true;
@@ -8641,7 +9093,7 @@ var SPAWN_GRACE_MS = 8e3;
8641
9093
  var DEATH_CONFIRMATIONS = 3;
8642
9094
  var SSE_RECONNECT_MS = 1e3;
8643
9095
  function sleep2(ms) {
8644
- return new Promise((resolve3) => setTimeout(resolve3, ms));
9096
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
8645
9097
  }
8646
9098
  var TRUST_PROMPT_RE = /trust this folder|do you trust|yes,? i trust|trust the files in this/i;
8647
9099
  async function dismissTrustPrompt(session) {
@@ -8793,11 +9245,11 @@ function parseArgs(argv) {
8793
9245
  let terminal;
8794
9246
  let agent;
8795
9247
  let help = false;
8796
- let forget2 = false;
9248
+ let forget = false;
8797
9249
  for (let i2 = 0; i2 < argv.length; i2++) {
8798
9250
  const tok = argv[i2];
8799
9251
  if (tok === "--help" || tok === "-h") help = true;
8800
- else if (tok === "--forget") forget2 = true;
9252
+ else if (tok === "--forget") forget = true;
8801
9253
  else if (tok === "--terminal" || tok === "-t") {
8802
9254
  const v = argv[++i2];
8803
9255
  if (v === "iterm" || v === "terminal") terminal = v;
@@ -8815,7 +9267,7 @@ function parseArgs(argv) {
8815
9267
  }
8816
9268
  }
8817
9269
  }
8818
- return { terminal, agent, help, forget: forget2 };
9270
+ return { terminal, agent, help, forget };
8819
9271
  }
8820
9272
  function printHelp() {
8821
9273
  process.stdout.write(
@@ -8842,12 +9294,12 @@ Options:
8842
9294
  );
8843
9295
  }
8844
9296
  async function lens(argv, options) {
8845
- const { terminal: preferred, agent: agentId, help, forget: forget2 } = parseArgs(argv);
9297
+ const { terminal: preferred, agent: agentId, help, forget } = parseArgs(argv);
8846
9298
  if (help) {
8847
9299
  printHelp();
8848
9300
  return;
8849
9301
  }
8850
- if (forget2) {
9302
+ if (forget) {
8851
9303
  const had = getRememberedAgent();
8852
9304
  clearRememberedAgent();
8853
9305
  process.stdout.write(
@@ -8914,12 +9366,12 @@ async function lens(argv, options) {
8914
9366
  await endSession(baseUrl);
8915
9367
  process.exit(1);
8916
9368
  }
8917
- const seedFile = path11.join(os2.tmpdir(), `argent-lens-seed-${process.pid}-${Date.now()}.txt`);
8918
- fs9.writeFileSync(seedFile, buildSeedPrompt(), "utf8");
9369
+ const seedFile = path12.join(os2.tmpdir(), `argent-lens-seed-${process.pid}-${Date.now()}.txt`);
9370
+ fs10.writeFileSync(seedFile, buildSeedPrompt(), "utf8");
8919
9371
  const launchCmd = agent.launch(shellQuote(process.cwd()), shellQuote(seedFile));
8920
9372
  const removeSeedFile = () => {
8921
9373
  try {
8922
- fs9.rmSync(seedFile, { force: true });
9374
+ fs10.rmSync(seedFile, { force: true });
8923
9375
  } catch {
8924
9376
  }
8925
9377
  };
@@ -10023,8 +10475,8 @@ var n = class extends V {
10023
10475
  import { styleText as styleText2, stripVTControlCharacters } from "node:util";
10024
10476
  import process$1 from "node:process";
10025
10477
  var import_sisteransi2 = __toESM(require_src(), 1);
10026
- import { existsSync as existsSync6, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
10027
- import { dirname as dirname5, join as join11 } from "node:path";
10478
+ import { existsSync as existsSync7, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
10479
+ import { dirname as dirname6, join as join12 } from "node:path";
10028
10480
  function isUnicodeSupported() {
10029
10481
  if (process$1.platform !== "win32") {
10030
10482
  return process$1.env.TERM !== "linux";
@@ -10955,17 +11407,17 @@ async function telemetry(args) {
10955
11407
  }
10956
11408
  function printUsage() {
10957
11409
  console.log(`Usage:
10958
- argent telemetry status Show telemetry state and anonymous id
11410
+ argent telemetry status Show telemetry state and device id
10959
11411
  argent telemetry enable Enable telemetry
10960
11412
  argent telemetry disable Disable telemetry
10961
11413
  `);
10962
11414
  }
10963
11415
  function printStatus() {
10964
11416
  const s = status();
10965
- const anonLabel = s.anonIdPrefix ? `${s.anonIdPrefix}...` : s.hasAnonIdOnDisk ? "present" : "not created";
11417
+ const idLabel = s.anonIdPrefix ? `${s.anonIdPrefix}...` : s.hasAnonIdOnDisk ? "present" : "not created";
10966
11418
  console.log("telemetry:");
10967
- console.log(` state: ${s.enabled ? "enabled" : "disabled"}`);
10968
- console.log(` anon id: ${anonLabel}`);
11419
+ console.log(` state: ${s.enabled ? "enabled" : "disabled"}`);
11420
+ console.log(` device id: ${idLabel}`);
10969
11421
  }
10970
11422
  async function cmdEnable() {
10971
11423
  const wasEnabled = isEnabled();