@swmansion/argent 0.14.1-next.2 → 0.14.1-next.21

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);
359
418
  }
360
- async function clearToolsServerState() {
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
+ }
432
+ }
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
  }
@@ -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) {
6963
7156
  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;
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;
7183
+ const finalPath = identityFilePath();
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;
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) {
7249
+ fs4.mkdirSync(argentHomeDir(), { recursive: true });
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
+ }
6969
7277
  }
7278
+ }
7279
+ function mintRandomId(finalPath) {
6970
7280
  fs4.mkdirSync(argentHomeDir(), { recursive: true });
6971
- const uuid = crypto2.randomUUID();
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
  }
@@ -7289,11 +7731,15 @@ function isScalarType(type) {
7289
7731
  }
7290
7732
  function coerceScalar(raw, type, field) {
7291
7733
  if (type === "number") {
7734
+ if (raw.trim() === "")
7735
+ throw new FlagParseException(`--${field} expected a number, got "${raw}"`);
7292
7736
  const n2 = Number(raw);
7293
7737
  if (Number.isNaN(n2)) throw new FlagParseException(`--${field} expected a number, got "${raw}"`);
7294
7738
  return n2;
7295
7739
  }
7296
7740
  if (type === "integer") {
7741
+ if (raw.trim() === "")
7742
+ throw new FlagParseException(`--${field} expected an integer, got "${raw}"`);
7297
7743
  const n2 = Number(raw);
7298
7744
  if (!Number.isInteger(n2))
7299
7745
  throw new FlagParseException(`--${field} expected an integer, got "${raw}"`);
@@ -7317,11 +7763,13 @@ function parseJsonOrThrow(raw, label) {
7317
7763
  }
7318
7764
  function parseFlags(argv, schema) {
7319
7765
  const properties = schema?.properties ?? {};
7766
+ const argsHatchHint = properties.args === void 0 ? " or --args '<json>'" : "";
7320
7767
  const args = {};
7321
7768
  const positional = [];
7322
7769
  let helpRequested = false;
7323
7770
  let rawArgs = null;
7324
7771
  const seenArrayFields = /* @__PURE__ */ new Set();
7772
+ const jsonFields = /* @__PURE__ */ new Set();
7325
7773
  function takeNext(i2, flag) {
7326
7774
  if (i2 + 1 >= argv.length) {
7327
7775
  throw new FlagParseException(`--${flag} requires a value`);
@@ -7351,7 +7799,7 @@ function parseFlags(argv, schema) {
7351
7799
  } else {
7352
7800
  flag = tok.slice(2);
7353
7801
  }
7354
- if (flag === "args") {
7802
+ if (flag === "args" && properties.args === void 0) {
7355
7803
  const { value: value2, nextIndex: nextIndex2 } = inlineValue !== void 0 ? { value: inlineValue, nextIndex: i2 } : takeNext(i2, "args");
7356
7804
  rawArgs = value2;
7357
7805
  i2 = nextIndex2;
@@ -7360,7 +7808,13 @@ function parseFlags(argv, schema) {
7360
7808
  if (flag.endsWith("-json")) {
7361
7809
  const fieldName = flag.slice(0, -"-json".length);
7362
7810
  const { value: value2, nextIndex: nextIndex2 } = inlineValue !== void 0 ? { value: inlineValue, nextIndex: i2 } : takeNext(i2, flag);
7811
+ if (seenArrayFields.has(fieldName)) {
7812
+ throw new FlagParseException(
7813
+ `--${fieldName} and --${flag} cannot be mixed for the same field; pass it entirely as --${flag} '<json>'${argsHatchHint}`
7814
+ );
7815
+ }
7363
7816
  args[fieldName] = parseJsonOrThrow(value2, `--${flag}`);
7817
+ jsonFields.add(fieldName);
7364
7818
  i2 = nextIndex2;
7365
7819
  continue;
7366
7820
  }
@@ -7388,10 +7842,15 @@ function parseFlags(argv, schema) {
7388
7842
  const itemType = propSchema.items?.type;
7389
7843
  if (!isScalarType(itemType)) {
7390
7844
  throw new FlagParseException(
7391
- `--${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}`
7392
7846
  );
7393
7847
  }
7394
7848
  const { value: value2, nextIndex: nextIndex2 } = inlineValue !== void 0 ? { value: inlineValue, nextIndex: i2 } : takeNext(i2, flag);
7849
+ if (jsonFields.has(flag)) {
7850
+ throw new FlagParseException(
7851
+ `--${flag} and --${flag}-json cannot be mixed for the same field; pass it entirely as --${flag}-json '<json>'${argsHatchHint}`
7852
+ );
7853
+ }
7395
7854
  const coerced = coerceScalar(value2, itemType, flag);
7396
7855
  if (!seenArrayFields.has(flag)) {
7397
7856
  args[flag] = [coerced];
@@ -7404,7 +7863,7 @@ function parseFlags(argv, schema) {
7404
7863
  }
7405
7864
  if (propSchema?.type === "object") {
7406
7865
  throw new FlagParseException(
7407
- `--${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}`
7408
7867
  );
7409
7868
  }
7410
7869
  const { value, nextIndex } = inlineValue !== void 0 ? { value: inlineValue, nextIndex: i2 } : takeNext(i2, flag);
@@ -7479,27 +7938,31 @@ function splitOptions(argv) {
7479
7938
  return { json, outPath, argvForFlags: rest };
7480
7939
  }
7481
7940
  async function readStdin() {
7482
- return new Promise((resolve3, reject) => {
7941
+ return new Promise((resolve4, reject) => {
7483
7942
  let data = "";
7484
7943
  process.stdin.setEncoding("utf8");
7485
7944
  process.stdin.on("data", (chunk) => {
7486
7945
  data += chunk;
7487
7946
  });
7488
- process.stdin.on("end", () => resolve3(data));
7947
+ process.stdin.on("end", () => resolve4(data));
7489
7948
  process.stdin.on("error", reject);
7490
7949
  });
7491
7950
  }
7492
7951
  function printToolHelp(meta) {
7493
7952
  const description = meta.description?.trim() ?? "";
7953
+ const schema = meta.inputSchema;
7954
+ const hasOwnArgsField = schema?.properties?.args !== void 0;
7494
7955
  console.log(`argent run ${meta.name} [flags]`);
7495
7956
  if (description) console.log(`
7496
7957
  ${description}
7497
7958
  `);
7498
7959
  console.log("Flags:");
7499
- console.log(formatSchemaUsage(meta.inputSchema));
7960
+ console.log(formatSchemaUsage(schema));
7500
7961
  console.log("\nGlobal flags:");
7501
- console.log(" --args <json> Pass the entire payload as JSON (overrides flags)");
7502
- 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
+ }
7503
7966
  console.log(" --<field>-json <json> Pass a single field as JSON (objects/nested arrays)");
7504
7967
  console.log(" --json Print the raw JSON result");
7505
7968
  console.log(" --out <path> For image results, save to <path> instead of fetching URL");
@@ -7513,8 +7976,8 @@ async function fetchImageToFile(result, outPath) {
7513
7976
  const res = await fetch(url);
7514
7977
  if (!res.ok) throw new Error(`Failed to download image: ${res.status} ${res.statusText}`);
7515
7978
  const buf = Buffer.from(await res.arrayBuffer());
7516
- fs7.mkdirSync(path9.dirname(path9.resolve(outPath)), { recursive: true });
7517
- fs7.writeFileSync(outPath, buf);
7979
+ fs8.mkdirSync(path10.dirname(path10.resolve(outPath)), { recursive: true });
7980
+ fs8.writeFileSync(outPath, buf);
7518
7981
  }
7519
7982
  function renderResult(result, outputHint, images, json) {
7520
7983
  if (json) return JSON.stringify(result, null, 2);
@@ -7653,8 +8116,8 @@ Examples:
7653
8116
  if (outPath && meta.outputHint === "image") {
7654
8117
  try {
7655
8118
  if (images.length > 0) {
7656
- fs7.mkdirSync(path9.dirname(path9.resolve(outPath)), { recursive: true });
7657
- fs7.writeFileSync(outPath, images[0].data);
8119
+ fs8.mkdirSync(path10.dirname(path10.resolve(outPath)), { recursive: true });
8120
+ fs8.writeFileSync(outPath, images[0].data);
7658
8121
  } else if (result && typeof result === "object") {
7659
8122
  await fetchImageToFile(result, outPath);
7660
8123
  }
@@ -7754,27 +8217,29 @@ Options:
7754
8217
  }
7755
8218
 
7756
8219
  // ../argent-cli/src/server.ts
7757
- import * as fs8 from "node:fs";
7758
- import * as path10 from "node:path";
8220
+ import * as fs9 from "node:fs";
8221
+ import * as path11 from "node:path";
7759
8222
  import { homedir as homedir5, networkInterfaces } from "node:os";
7760
- import { spawn as spawn2 } from "node:child_process";
7761
- var STATE_DIR2 = path10.join(homedir5(), ".argent");
7762
- var STATE_FILE2 = path10.join(STATE_DIR2, "tool-server.json");
7763
- var LOG_FILE2 = path10.join(STATE_DIR2, "tool-server.log");
7764
- function readState2() {
7765
- try {
7766
- return JSON.parse(fs8.readFileSync(STATE_FILE2, "utf8"));
7767
- } catch {
7768
- return null;
7769
- }
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}`;
7770
8233
  }
7771
- async function statusCmd(json) {
7772
- const state2 = readState2();
8234
+ async function statusCmd(json, paths) {
8235
+ const state2 = await readToolsServerState(paths?.bundlePath);
7773
8236
  if (!state2) {
8237
+ const foreign = await describeForeignServers(paths?.bundlePath);
7774
8238
  if (json) {
7775
8239
  console.log(JSON.stringify({ running: false }, null, 2));
7776
8240
  } else {
7777
- 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);
7778
8243
  }
7779
8244
  return;
7780
8245
  }
@@ -7803,25 +8268,28 @@ async function statusCmd(json) {
7803
8268
  State file is stale; next \`argent\` invocation will respawn the server.`);
7804
8269
  }
7805
8270
  }
7806
- async function stopCmd() {
7807
- const state2 = readState2();
8271
+ async function stopCmd(paths) {
8272
+ const state2 = await readToolsServerState(paths?.bundlePath);
7808
8273
  if (!state2) {
7809
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>`);
7810
8278
  return;
7811
8279
  }
7812
- await killToolServer();
8280
+ await killToolServer(paths?.bundlePath);
7813
8281
  console.log(`tool-server stopped (pid ${state2.pid}).`);
7814
8282
  }
7815
8283
  function logsCmd(follow) {
7816
- if (!fs8.existsSync(LOG_FILE2)) {
8284
+ if (!fs9.existsSync(LOG_FILE2)) {
7817
8285
  console.log(`No log file at ${LOG_FILE2}`);
7818
8286
  return;
7819
8287
  }
7820
8288
  if (!follow) {
7821
- process.stdout.write(fs8.readFileSync(LOG_FILE2, "utf8"));
8289
+ process.stdout.write(fs9.readFileSync(LOG_FILE2, "utf8"));
7822
8290
  return;
7823
8291
  }
7824
- const child = spawn2("tail", ["-f", LOG_FILE2], { stdio: "inherit" });
8292
+ const child = spawn3("tail", ["-f", LOG_FILE2], { stdio: "inherit" });
7825
8293
  child.on("exit", (code) => process.exit(code ?? 0));
7826
8294
  }
7827
8295
  var StartFlagError = class extends Error {
@@ -7965,11 +8433,11 @@ function printConnectionInfo(bindHost, port, token) {
7965
8433
  );
7966
8434
  }
7967
8435
  }
7968
- async function ensureNoExistingServer(force) {
7969
- const state2 = await readToolsServerState();
8436
+ async function ensureNoExistingServer(force, paths) {
8437
+ const state2 = await readToolsServerState(paths.bundlePath);
7970
8438
  if (!state2) return;
7971
8439
  const alive = isToolsServerProcessAlive(state2.pid);
7972
- 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;
7973
8441
  if (alive && healthy && !force) {
7974
8442
  const url = formatUrl(state2.host ?? "127.0.0.1", state2.port);
7975
8443
  throw new StartFlagError(
@@ -7978,9 +8446,9 @@ Use \`argent server stop\` first, or pass \`--force\` to replace it.`
7978
8446
  );
7979
8447
  }
7980
8448
  if (alive && force) {
7981
- await killToolServer();
8449
+ await killToolServer(paths.bundlePath);
7982
8450
  } else {
7983
- await clearToolsServerState();
8451
+ await clearToolsServerState(paths.bundlePath);
7984
8452
  }
7985
8453
  }
7986
8454
  async function resolvePort(requested) {
@@ -8010,7 +8478,7 @@ async function startCmd(argv, paths) {
8010
8478
  return;
8011
8479
  }
8012
8480
  try {
8013
- await ensureNoExistingServer(flags2.force);
8481
+ await ensureNoExistingServer(flags2.force, paths);
8014
8482
  } catch (err) {
8015
8483
  if (err instanceof StartFlagError) {
8016
8484
  console.error(err.message);
@@ -8070,7 +8538,7 @@ async function runForeground(paths, port, host, idleTimeoutMinutes, token) {
8070
8538
  idleTimeoutMinutes,
8071
8539
  token
8072
8540
  });
8073
- const child = spawn2("node", [paths.bundlePath, "start"], {
8541
+ const child = spawn3("node", [paths.bundlePath, "start"], {
8074
8542
  stdio: "inherit",
8075
8543
  env
8076
8544
  });
@@ -8108,7 +8576,7 @@ async function runForeground(paths, port, host, idleTimeoutMinutes, token) {
8108
8576
  process.removeListener("SIGINT", onInt);
8109
8577
  process.removeListener("SIGTERM", onTerm);
8110
8578
  if (stateWritten) {
8111
- clearToolsServerState().catch(() => {
8579
+ clearToolsServerState(paths.bundlePath).catch(() => {
8112
8580
  });
8113
8581
  }
8114
8582
  };
@@ -8146,10 +8614,10 @@ async function server(argv, options) {
8146
8614
  await startCmd(argv.slice(1), options?.paths);
8147
8615
  return;
8148
8616
  case "status":
8149
- await statusCmd(json);
8617
+ await statusCmd(json, options?.paths);
8150
8618
  return;
8151
8619
  case "stop":
8152
- await stopCmd();
8620
+ await stopCmd(options?.paths);
8153
8621
  return;
8154
8622
  case "logs":
8155
8623
  logsCmd(follow);
@@ -8161,22 +8629,22 @@ async function server(argv, options) {
8161
8629
  }
8162
8630
 
8163
8631
  // ../argent-cli/src/lens.ts
8164
- import * as fs9 from "node:fs";
8632
+ import * as fs10 from "node:fs";
8165
8633
  import * as os2 from "node:os";
8166
- import * as path11 from "node:path";
8634
+ import * as path12 from "node:path";
8167
8635
 
8168
8636
  // ../argent-cli/src/lens-terminal.ts
8169
- import { execFileSync as execFileSync2 } from "node:child_process";
8170
- import { existsSync as existsSync5 } from "node:fs";
8637
+ import { execFileSync as execFileSync3 } from "node:child_process";
8638
+ import { existsSync as existsSync6 } from "node:fs";
8171
8639
  var ITERM_PATHS = ["/Applications/iTerm.app", `${process.env.HOME ?? ""}/Applications/iTerm.app`];
8172
- function isITermInstalled(existsSync7 = defaultExists) {
8173
- return ITERM_PATHS.some((p) => p && existsSync7(p));
8640
+ function isITermInstalled(existsSync8 = defaultExists) {
8641
+ return ITERM_PATHS.some((p) => p && existsSync8(p));
8174
8642
  }
8175
8643
  function defaultExists(p) {
8176
- return existsSync5(p);
8644
+ return existsSync6(p);
8177
8645
  }
8178
- function resolveTerminal(preferred = "iterm", existsSync7 = defaultExists) {
8179
- if (preferred === "iterm" && isITermInstalled(existsSync7)) return "iterm";
8646
+ function resolveTerminal(preferred = "iterm", existsSync8 = defaultExists) {
8647
+ if (preferred === "iterm" && isITermInstalled(existsSync8)) return "iterm";
8180
8648
  return "terminal";
8181
8649
  }
8182
8650
  function escapeAppleScript(s) {
@@ -8325,7 +8793,7 @@ function parseAliveTtys(psOutput) {
8325
8793
  }
8326
8794
  function runOsascript(script) {
8327
8795
  try {
8328
- return execFileSync2("/usr/bin/osascript", ["-e", script], {
8796
+ return execFileSync3("/usr/bin/osascript", ["-e", script], {
8329
8797
  encoding: "utf8",
8330
8798
  stdio: ["ignore", "pipe", "pipe"]
8331
8799
  });
@@ -8367,7 +8835,7 @@ function pressEnter(session) {
8367
8835
  }
8368
8836
  function aliveTtys() {
8369
8837
  try {
8370
- const out = execFileSync2("/bin/ps", ["-A", "-o", "tty="], { encoding: "utf8" });
8838
+ const out = execFileSync3("/bin/ps", ["-A", "-o", "tty="], { encoding: "utf8" });
8371
8839
  return parseAliveTtys(out);
8372
8840
  } catch {
8373
8841
  return /* @__PURE__ */ new Set();
@@ -8404,7 +8872,7 @@ function ptyInjectBeats(text2) {
8404
8872
  ];
8405
8873
  }
8406
8874
  function sleep(ms) {
8407
- return new Promise((resolve3) => setTimeout(resolve3, ms));
8875
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
8408
8876
  }
8409
8877
  var DEFAULT_COLS = 80;
8410
8878
  var DEFAULT_ROWS = 24;
@@ -8562,7 +9030,7 @@ async function* lensEvents(baseUrl, signal) {
8562
9030
  }
8563
9031
 
8564
9032
  // ../argent-cli/src/lens-agents.ts
8565
- import { execFileSync as execFileSync3 } from "node:child_process";
9033
+ import { execFileSync as execFileSync4 } from "node:child_process";
8566
9034
  var AGENTS = [
8567
9035
  {
8568
9036
  id: "claude",
@@ -8604,7 +9072,7 @@ function agentIds() {
8604
9072
  }
8605
9073
  function defaultIsOnPath(bin) {
8606
9074
  try {
8607
- execFileSync3(process.platform === "win32" ? "where" : "which", [bin], {
9075
+ execFileSync4(process.platform === "win32" ? "where" : "which", [bin], {
8608
9076
  stdio: ["ignore", "ignore", "ignore"]
8609
9077
  });
8610
9078
  return true;
@@ -8625,7 +9093,7 @@ var SPAWN_GRACE_MS = 8e3;
8625
9093
  var DEATH_CONFIRMATIONS = 3;
8626
9094
  var SSE_RECONNECT_MS = 1e3;
8627
9095
  function sleep2(ms) {
8628
- return new Promise((resolve3) => setTimeout(resolve3, ms));
9096
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
8629
9097
  }
8630
9098
  var TRUST_PROMPT_RE = /trust this folder|do you trust|yes,? i trust|trust the files in this/i;
8631
9099
  async function dismissTrustPrompt(session) {
@@ -8777,11 +9245,11 @@ function parseArgs(argv) {
8777
9245
  let terminal;
8778
9246
  let agent;
8779
9247
  let help = false;
8780
- let forget2 = false;
9248
+ let forget = false;
8781
9249
  for (let i2 = 0; i2 < argv.length; i2++) {
8782
9250
  const tok = argv[i2];
8783
9251
  if (tok === "--help" || tok === "-h") help = true;
8784
- else if (tok === "--forget") forget2 = true;
9252
+ else if (tok === "--forget") forget = true;
8785
9253
  else if (tok === "--terminal" || tok === "-t") {
8786
9254
  const v = argv[++i2];
8787
9255
  if (v === "iterm" || v === "terminal") terminal = v;
@@ -8799,7 +9267,7 @@ function parseArgs(argv) {
8799
9267
  }
8800
9268
  }
8801
9269
  }
8802
- return { terminal, agent, help, forget: forget2 };
9270
+ return { terminal, agent, help, forget };
8803
9271
  }
8804
9272
  function printHelp() {
8805
9273
  process.stdout.write(
@@ -8826,12 +9294,12 @@ Options:
8826
9294
  );
8827
9295
  }
8828
9296
  async function lens(argv, options) {
8829
- const { terminal: preferred, agent: agentId, help, forget: forget2 } = parseArgs(argv);
9297
+ const { terminal: preferred, agent: agentId, help, forget } = parseArgs(argv);
8830
9298
  if (help) {
8831
9299
  printHelp();
8832
9300
  return;
8833
9301
  }
8834
- if (forget2) {
9302
+ if (forget) {
8835
9303
  const had = getRememberedAgent();
8836
9304
  clearRememberedAgent();
8837
9305
  process.stdout.write(
@@ -8898,12 +9366,12 @@ async function lens(argv, options) {
8898
9366
  await endSession(baseUrl);
8899
9367
  process.exit(1);
8900
9368
  }
8901
- const seedFile = path11.join(os2.tmpdir(), `argent-lens-seed-${process.pid}-${Date.now()}.txt`);
8902
- 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");
8903
9371
  const launchCmd = agent.launch(shellQuote(process.cwd()), shellQuote(seedFile));
8904
9372
  const removeSeedFile = () => {
8905
9373
  try {
8906
- fs9.rmSync(seedFile, { force: true });
9374
+ fs10.rmSync(seedFile, { force: true });
8907
9375
  } catch {
8908
9376
  }
8909
9377
  };
@@ -10007,8 +10475,8 @@ var n = class extends V {
10007
10475
  import { styleText as styleText2, stripVTControlCharacters } from "node:util";
10008
10476
  import process$1 from "node:process";
10009
10477
  var import_sisteransi2 = __toESM(require_src(), 1);
10010
- import { existsSync as existsSync6, lstatSync as lstatSync3, readdirSync as readdirSync2 } from "node:fs";
10011
- 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";
10012
10480
  function isUnicodeSupported() {
10013
10481
  if (process$1.platform !== "win32") {
10014
10482
  return process$1.env.TERM !== "linux";
@@ -10939,17 +11407,17 @@ async function telemetry(args) {
10939
11407
  }
10940
11408
  function printUsage() {
10941
11409
  console.log(`Usage:
10942
- argent telemetry status Show telemetry state and anonymous id
11410
+ argent telemetry status Show telemetry state and device id
10943
11411
  argent telemetry enable Enable telemetry
10944
11412
  argent telemetry disable Disable telemetry
10945
11413
  `);
10946
11414
  }
10947
11415
  function printStatus() {
10948
11416
  const s = status();
10949
- const anonLabel = s.anonIdPrefix ? `${s.anonIdPrefix}...` : s.hasAnonIdOnDisk ? "present" : "not created";
11417
+ const idLabel = s.anonIdPrefix ? `${s.anonIdPrefix}...` : s.hasAnonIdOnDisk ? "present" : "not created";
10950
11418
  console.log("telemetry:");
10951
- console.log(` state: ${s.enabled ? "enabled" : "disabled"}`);
10952
- console.log(` anon id: ${anonLabel}`);
11419
+ console.log(` state: ${s.enabled ? "enabled" : "disabled"}`);
11420
+ console.log(` device id: ${idLabel}`);
10953
11421
  }
10954
11422
  async function cmdEnable() {
10955
11423
  const wasEnabled = isEnabled();