@swmansion/argent 0.10.0 → 0.11.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.
@@ -2980,7 +2980,7 @@ var require_compile = __commonJS({
2980
2980
  const schOrFunc = root.refs[ref];
2981
2981
  if (schOrFunc)
2982
2982
  return schOrFunc;
2983
- let _sch = resolve.call(this, root, ref);
2983
+ let _sch = resolve2.call(this, root, ref);
2984
2984
  if (_sch === void 0) {
2985
2985
  const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
2986
2986
  const { schemaId } = this.opts;
@@ -3007,7 +3007,7 @@ var require_compile = __commonJS({
3007
3007
  function sameSchemaEnv(s1, s2) {
3008
3008
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
3009
3009
  }
3010
- function resolve(root, ref) {
3010
+ function resolve2(root, ref) {
3011
3011
  let sch;
3012
3012
  while (typeof (sch = this.refs[ref]) == "string")
3013
3013
  ref = sch;
@@ -3225,8 +3225,8 @@ var require_utils = __commonJS({
3225
3225
  }
3226
3226
  return ind;
3227
3227
  }
3228
- function removeDotSegments(path3) {
3229
- let input = path3;
3228
+ function removeDotSegments(path4) {
3229
+ let input = path4;
3230
3230
  const output = [];
3231
3231
  let nextSlash = -1;
3232
3232
  let len = 0;
@@ -3478,8 +3478,8 @@ var require_schemes = __commonJS({
3478
3478
  wsComponent.secure = void 0;
3479
3479
  }
3480
3480
  if (wsComponent.resourceName) {
3481
- const [path3, query] = wsComponent.resourceName.split("?");
3482
- wsComponent.path = path3 && path3 !== "/" ? path3 : void 0;
3481
+ const [path4, query] = wsComponent.resourceName.split("?");
3482
+ wsComponent.path = path4 && path4 !== "/" ? path4 : void 0;
3483
3483
  wsComponent.query = query;
3484
3484
  wsComponent.resourceName = void 0;
3485
3485
  }
@@ -3638,7 +3638,7 @@ var require_fast_uri = __commonJS({
3638
3638
  }
3639
3639
  return uri;
3640
3640
  }
3641
- function resolve(baseURI, relativeURI, options) {
3641
+ function resolve2(baseURI, relativeURI, options) {
3642
3642
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3643
3643
  const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
3644
3644
  schemelessOptions.skipEscape = true;
@@ -3896,7 +3896,7 @@ var require_fast_uri = __commonJS({
3896
3896
  var fastUri = {
3897
3897
  SCHEMES,
3898
3898
  normalize,
3899
- resolve,
3899
+ resolve: resolve2,
3900
3900
  resolveComponent,
3901
3901
  equal,
3902
3902
  serialize,
@@ -6872,12 +6872,12 @@ var require_dist = __commonJS({
6872
6872
  throw new Error(`Unknown format "${name}"`);
6873
6873
  return f;
6874
6874
  };
6875
- function addFormats(ajv, list, fs2, exportName) {
6875
+ function addFormats(ajv, list, fs3, exportName) {
6876
6876
  var _a3;
6877
6877
  var _b;
6878
6878
  (_a3 = (_b = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
6879
6879
  for (const f of list)
6880
- ajv.addFormat(f, fs2[f]);
6880
+ ajv.addFormat(f, fs3[f]);
6881
6881
  }
6882
6882
  module.exports = exports = formatsPlugin;
6883
6883
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -6886,9 +6886,9 @@ var require_dist = __commonJS({
6886
6886
  });
6887
6887
 
6888
6888
  // ../argent-mcp/src/mcp-server.ts
6889
- import { appendFile, mkdir as mkdir3 } from "node:fs/promises";
6890
- import { dirname } from "node:path";
6891
- import { homedir as homedir3 } from "node:os";
6889
+ import { appendFile, mkdir as mkdir4 } from "node:fs/promises";
6890
+ import { dirname as dirname2 } from "node:path";
6891
+ import { homedir as homedir4 } from "node:os";
6892
6892
 
6893
6893
  // ../../node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
6894
6894
  import process3 from "node:process";
@@ -7133,10 +7133,10 @@ function mergeDefs(...defs) {
7133
7133
  function cloneDef(schema) {
7134
7134
  return mergeDefs(schema._zod.def);
7135
7135
  }
7136
- function getElementAtPath(obj, path3) {
7137
- if (!path3)
7136
+ function getElementAtPath(obj, path4) {
7137
+ if (!path4)
7138
7138
  return obj;
7139
- return path3.reduce((acc, key) => acc?.[key], obj);
7139
+ return path4.reduce((acc, key) => acc?.[key], obj);
7140
7140
  }
7141
7141
  function promiseAllObject(promisesObj) {
7142
7142
  const keys = Object.keys(promisesObj);
@@ -7545,11 +7545,11 @@ function explicitlyAborted(x, startIndex = 0) {
7545
7545
  }
7546
7546
  return false;
7547
7547
  }
7548
- function prefixIssues(path3, issues) {
7548
+ function prefixIssues(path4, issues) {
7549
7549
  return issues.map((iss) => {
7550
7550
  var _a3;
7551
7551
  (_a3 = iss).path ?? (_a3.path = []);
7552
- iss.path.unshift(path3);
7552
+ iss.path.unshift(path4);
7553
7553
  return iss;
7554
7554
  });
7555
7555
  }
@@ -7696,16 +7696,16 @@ function flattenError(error2, mapper = (issue2) => issue2.message) {
7696
7696
  }
7697
7697
  function formatError(error2, mapper = (issue2) => issue2.message) {
7698
7698
  const fieldErrors = { _errors: [] };
7699
- const processError = (error3, path3 = []) => {
7699
+ const processError = (error3, path4 = []) => {
7700
7700
  for (const issue2 of error3.issues) {
7701
7701
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7702
- issue2.errors.map((issues) => processError({ issues }, [...path3, ...issue2.path]));
7702
+ issue2.errors.map((issues) => processError({ issues }, [...path4, ...issue2.path]));
7703
7703
  } else if (issue2.code === "invalid_key") {
7704
- processError({ issues: issue2.issues }, [...path3, ...issue2.path]);
7704
+ processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
7705
7705
  } else if (issue2.code === "invalid_element") {
7706
- processError({ issues: issue2.issues }, [...path3, ...issue2.path]);
7706
+ processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
7707
7707
  } else {
7708
- const fullpath = [...path3, ...issue2.path];
7708
+ const fullpath = [...path4, ...issue2.path];
7709
7709
  if (fullpath.length === 0) {
7710
7710
  fieldErrors._errors.push(mapper(issue2));
7711
7711
  } else {
@@ -13697,12 +13697,12 @@ var StdioServerTransport = class {
13697
13697
  this.onclose?.();
13698
13698
  }
13699
13699
  send(message) {
13700
- return new Promise((resolve) => {
13700
+ return new Promise((resolve2) => {
13701
13701
  const json = serializeMessage(message);
13702
13702
  if (this._stdout.write(json)) {
13703
- resolve();
13703
+ resolve2();
13704
13704
  } else {
13705
- this._stdout.once("drain", resolve);
13705
+ this._stdout.once("drain", resolve2);
13706
13706
  }
13707
13707
  });
13708
13708
  }
@@ -14300,7 +14300,7 @@ var Protocol = class {
14300
14300
  return;
14301
14301
  }
14302
14302
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
14303
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
14303
+ await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
14304
14304
  options?.signal?.throwIfAborted();
14305
14305
  }
14306
14306
  } catch (error2) {
@@ -14317,7 +14317,7 @@ var Protocol = class {
14317
14317
  */
14318
14318
  request(request, resultSchema, options) {
14319
14319
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
14320
- return new Promise((resolve, reject) => {
14320
+ return new Promise((resolve2, reject) => {
14321
14321
  const earlyReject = (error2) => {
14322
14322
  reject(error2);
14323
14323
  };
@@ -14395,7 +14395,7 @@ var Protocol = class {
14395
14395
  if (!parseResult.success) {
14396
14396
  reject(parseResult.error);
14397
14397
  } else {
14398
- resolve(parseResult.data);
14398
+ resolve2(parseResult.data);
14399
14399
  }
14400
14400
  } catch (error2) {
14401
14401
  reject(error2);
@@ -14611,21 +14611,21 @@ var Protocol = class {
14611
14611
  * the error appropriately (e.g., by failing the task, logging, etc.). The Protocol layer
14612
14612
  * simply propagates the error.
14613
14613
  */
14614
- async _enqueueTaskMessage(taskId, message, sessionId) {
14614
+ async _enqueueTaskMessage(taskId, message, sessionId2) {
14615
14615
  if (!this._taskStore || !this._taskMessageQueue) {
14616
14616
  throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
14617
14617
  }
14618
14618
  const maxQueueSize = this._options?.maxTaskQueueSize;
14619
- await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize);
14619
+ await this._taskMessageQueue.enqueue(taskId, message, sessionId2, maxQueueSize);
14620
14620
  }
14621
14621
  /**
14622
14622
  * Clears the message queue for a task and rejects any pending request resolvers.
14623
14623
  * @param taskId The task ID whose queue should be cleared
14624
14624
  * @param sessionId Optional session ID for binding the operation to a specific session
14625
14625
  */
14626
- async _clearTaskQueue(taskId, sessionId) {
14626
+ async _clearTaskQueue(taskId, sessionId2) {
14627
14627
  if (this._taskMessageQueue) {
14628
- const messages = await this._taskMessageQueue.dequeueAll(taskId, sessionId);
14628
+ const messages = await this._taskMessageQueue.dequeueAll(taskId, sessionId2);
14629
14629
  for (const message of messages) {
14630
14630
  if (message.type === "request" && isJSONRPCRequest(message.message)) {
14631
14631
  const requestId = message.message.id;
@@ -14656,19 +14656,19 @@ var Protocol = class {
14656
14656
  }
14657
14657
  } catch {
14658
14658
  }
14659
- return new Promise((resolve, reject) => {
14659
+ return new Promise((resolve2, reject) => {
14660
14660
  if (signal.aborted) {
14661
14661
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
14662
14662
  return;
14663
14663
  }
14664
- const timeoutId = setTimeout(resolve, interval);
14664
+ const timeoutId = setTimeout(resolve2, interval);
14665
14665
  signal.addEventListener("abort", () => {
14666
14666
  clearTimeout(timeoutId);
14667
14667
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
14668
14668
  }, { once: true });
14669
14669
  });
14670
14670
  }
14671
- requestTaskStore(request, sessionId) {
14671
+ requestTaskStore(request, sessionId2) {
14672
14672
  const taskStore = this._taskStore;
14673
14673
  if (!taskStore) {
14674
14674
  throw new Error("No task store configured");
@@ -14681,18 +14681,18 @@ var Protocol = class {
14681
14681
  return await taskStore.createTask(taskParams, request.id, {
14682
14682
  method: request.method,
14683
14683
  params: request.params
14684
- }, sessionId);
14684
+ }, sessionId2);
14685
14685
  },
14686
14686
  getTask: async (taskId) => {
14687
- const task = await taskStore.getTask(taskId, sessionId);
14687
+ const task = await taskStore.getTask(taskId, sessionId2);
14688
14688
  if (!task) {
14689
14689
  throw new McpError(ErrorCode.InvalidParams, "Failed to retrieve task: Task not found");
14690
14690
  }
14691
14691
  return task;
14692
14692
  },
14693
14693
  storeTaskResult: async (taskId, status, result) => {
14694
- await taskStore.storeTaskResult(taskId, status, result, sessionId);
14695
- const task = await taskStore.getTask(taskId, sessionId);
14694
+ await taskStore.storeTaskResult(taskId, status, result, sessionId2);
14695
+ const task = await taskStore.getTask(taskId, sessionId2);
14696
14696
  if (task) {
14697
14697
  const notification = TaskStatusNotificationSchema.parse({
14698
14698
  method: "notifications/tasks/status",
@@ -14705,18 +14705,18 @@ var Protocol = class {
14705
14705
  }
14706
14706
  },
14707
14707
  getTaskResult: (taskId) => {
14708
- return taskStore.getTaskResult(taskId, sessionId);
14708
+ return taskStore.getTaskResult(taskId, sessionId2);
14709
14709
  },
14710
14710
  updateTaskStatus: async (taskId, status, statusMessage) => {
14711
- const task = await taskStore.getTask(taskId, sessionId);
14711
+ const task = await taskStore.getTask(taskId, sessionId2);
14712
14712
  if (!task) {
14713
14713
  throw new McpError(ErrorCode.InvalidParams, `Task "${taskId}" not found - it may have been cleaned up`);
14714
14714
  }
14715
14715
  if (isTerminal(task.status)) {
14716
14716
  throw new McpError(ErrorCode.InvalidParams, `Cannot update task "${taskId}" from terminal status "${task.status}" to "${status}". Terminal states (completed, failed, cancelled) cannot transition to other states.`);
14717
14717
  }
14718
- await taskStore.updateTaskStatus(taskId, status, statusMessage, sessionId);
14719
- const updatedTask = await taskStore.getTask(taskId, sessionId);
14718
+ await taskStore.updateTaskStatus(taskId, status, statusMessage, sessionId2);
14719
+ const updatedTask = await taskStore.getTask(taskId, sessionId2);
14720
14720
  if (updatedTask) {
14721
14721
  const notification = TaskStatusNotificationSchema.parse({
14722
14722
  method: "notifications/tasks/status",
@@ -14729,7 +14729,7 @@ var Protocol = class {
14729
14729
  }
14730
14730
  },
14731
14731
  listTasks: (cursor) => {
14732
- return taskStore.listTasks(cursor, sessionId);
14732
+ return taskStore.listTasks(cursor, sessionId2);
14733
14733
  }
14734
14734
  };
14735
14735
  }
@@ -15080,8 +15080,8 @@ var Server = class extends Protocol {
15080
15080
  this._serverInfo = _serverInfo;
15081
15081
  this._loggingLevels = /* @__PURE__ */ new Map();
15082
15082
  this.LOG_LEVEL_SEVERITY = new Map(LoggingLevelSchema.options.map((level, index) => [level, index]));
15083
- this.isMessageIgnored = (level, sessionId) => {
15084
- const currentLevel = this._loggingLevels.get(sessionId);
15083
+ this.isMessageIgnored = (level, sessionId2) => {
15084
+ const currentLevel = this._loggingLevels.get(sessionId2);
15085
15085
  return currentLevel ? this.LOG_LEVEL_SEVERITY.get(level) < this.LOG_LEVEL_SEVERITY.get(currentLevel) : false;
15086
15086
  };
15087
15087
  this._capabilities = options?.capabilities ?? {};
@@ -15424,9 +15424,9 @@ var Server = class extends Protocol {
15424
15424
  * @param params
15425
15425
  * @param sessionId optional for stateless and backward compatibility
15426
15426
  */
15427
- async sendLoggingMessage(params, sessionId) {
15427
+ async sendLoggingMessage(params, sessionId2) {
15428
15428
  if (this._capabilities.logging) {
15429
- if (!this.isMessageIgnored(params.level, sessionId)) {
15429
+ if (!this.isMessageIgnored(params.level, sessionId2)) {
15430
15430
  return this.notification({ method: "notifications/message", params });
15431
15431
  }
15432
15432
  }
@@ -15483,7 +15483,7 @@ function generateToken() {
15483
15483
  return randomBytes(AUTH_TOKEN_BYTES).toString("hex");
15484
15484
  }
15485
15485
  function findFreePort() {
15486
- return new Promise((resolve, reject) => {
15486
+ return new Promise((resolve2, reject) => {
15487
15487
  const srv = net.createServer();
15488
15488
  srv.listen(0, "127.0.0.1", () => {
15489
15489
  const addr = srv.address();
@@ -15494,7 +15494,7 @@ function findFreePort() {
15494
15494
  const port = addr.port;
15495
15495
  srv.close((err) => {
15496
15496
  if (err) reject(err);
15497
- else resolve(port);
15497
+ else resolve2(port);
15498
15498
  });
15499
15499
  });
15500
15500
  srv.on("error", reject);
@@ -15536,7 +15536,7 @@ async function isToolsServerHealthy(port, host = "127.0.0.1", timeoutMs = 2e3, t
15536
15536
  }
15537
15537
  }
15538
15538
  function spawnToolsServer(paths, port, options = {}) {
15539
- return new Promise((resolve, reject) => {
15539
+ return new Promise((resolve2, reject) => {
15540
15540
  let logFd;
15541
15541
  try {
15542
15542
  fs.mkdirSync(STATE_DIR, { recursive: true });
@@ -15568,7 +15568,7 @@ function spawnToolsServer(paths, port, options = {}) {
15568
15568
  const actualPort = parseInt(match[1], 10);
15569
15569
  rl.close();
15570
15570
  child.stdout?.resume();
15571
- settle(() => resolve({ port: actualPort, pid }));
15571
+ settle(() => resolve2({ port: actualPort, pid }));
15572
15572
  }
15573
15573
  });
15574
15574
  child.on("error", (err) => {
@@ -15699,9 +15699,144 @@ async function isRemoteRouted() {
15699
15699
  return url !== null;
15700
15700
  }
15701
15701
 
15702
+ // ../argent-tools-client/src/artifacts.ts
15703
+ import { mkdir as mkdir3, readFile as readFile3, rm, stat, writeFile as writeFile3 } from "node:fs/promises";
15704
+ import { tmpdir } from "node:os";
15705
+ import { basename, join as join3 } from "node:path";
15706
+ import { createHash } from "node:crypto";
15707
+ import { execFile } from "node:child_process";
15708
+ import { promisify } from "node:util";
15709
+ var execFileAsync = promisify(execFile);
15710
+ var ARTIFACT_MARKER = "__argentArtifact";
15711
+ function isArtifactHandle(value) {
15712
+ return !!value && typeof value === "object" && value[ARTIFACT_MARKER] === true && typeof value.id === "string" && typeof value.filename === "string";
15713
+ }
15714
+ var SESSION_ID = null;
15715
+ function sessionId() {
15716
+ if (!SESSION_ID) {
15717
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:T]/g, (m) => m === "T" ? "-" : "").slice(0, 15);
15718
+ SESSION_ID = `${stamp}-${process.pid}`;
15719
+ }
15720
+ return SESSION_ID;
15721
+ }
15722
+ function sanitizeSegment(segment) {
15723
+ return segment.replace(/[^A-Za-z0-9._-]/g, "_");
15724
+ }
15725
+ function projectSlug() {
15726
+ const cwd = process.cwd();
15727
+ const hash = createHash("sha1").update(cwd).digest("hex").slice(0, 6);
15728
+ const name = sanitizeSegment(basename(cwd)) || "root";
15729
+ return `${name}-${hash}`;
15730
+ }
15731
+ function artifactsRoot() {
15732
+ return process.env.ARGENT_ARTIFACTS_DIR ?? join3(tmpdir(), "argent-artifacts");
15733
+ }
15734
+ function artifactDir(deviceId) {
15735
+ const parts = [artifactsRoot(), projectSlug(), sessionId()];
15736
+ if (deviceId) parts.push(sanitizeSegment(deviceId));
15737
+ return join3(...parts);
15738
+ }
15739
+ async function resolveLocalFile(handle) {
15740
+ if (!handle.hostPath) return null;
15741
+ try {
15742
+ const st = await stat(handle.hostPath);
15743
+ if (handle.archive) {
15744
+ return st.isDirectory() ? handle.hostPath : null;
15745
+ }
15746
+ if (!st.isFile()) return null;
15747
+ if (st.size !== handle.size) return null;
15748
+ if (handle.mtimeMs != null && Math.round(st.mtimeMs) !== Math.round(handle.mtimeMs)) {
15749
+ return null;
15750
+ }
15751
+ return handle.hostPath;
15752
+ } catch {
15753
+ return null;
15754
+ }
15755
+ }
15756
+ async function downloadAndExtractArchive(handle, data, dir) {
15757
+ const tarball = join3(dir, `${sanitizeSegment(handle.filename)}.tar.gz`);
15758
+ try {
15759
+ await writeFile3(tarball, data);
15760
+ await execFileAsync("tar", ["-xzf", tarball, "-C", dir]);
15761
+ return join3(dir, handle.filename);
15762
+ } catch {
15763
+ return null;
15764
+ } finally {
15765
+ await rm(tarball, { force: true }).catch(() => {
15766
+ });
15767
+ }
15768
+ }
15769
+ async function materializeArtifacts(result, ctx) {
15770
+ const images = [];
15771
+ const fetchFn = ctx.fetchImpl ?? fetch;
15772
+ const authHeaders2 = ctx.authToken ? { Authorization: `Bearer ${ctx.authToken}` } : {};
15773
+ const dir = artifactDir(ctx.deviceId);
15774
+ let dirReady = false;
15775
+ async function ensureDir() {
15776
+ if (!dirReady) {
15777
+ await mkdir3(dir, { recursive: true });
15778
+ dirReady = true;
15779
+ }
15780
+ }
15781
+ async function walk(value) {
15782
+ if (isArtifactHandle(value)) {
15783
+ const localPath = await resolveLocalFile(value);
15784
+ if (localPath) {
15785
+ if (value.mimeType.startsWith("image/")) {
15786
+ images.push({ localPath, data: await readFile3(localPath), mimeType: value.mimeType });
15787
+ }
15788
+ return localPath;
15789
+ }
15790
+ try {
15791
+ const res = await fetchFn(`${ctx.toolsUrl}/artifacts/${value.id}`, {
15792
+ headers: authHeaders2
15793
+ });
15794
+ if (!res.ok) return null;
15795
+ const data = Buffer.from(await res.arrayBuffer());
15796
+ await ensureDir();
15797
+ if (value.archive === "tar.gz") {
15798
+ return await downloadAndExtractArchive(value, data, dir);
15799
+ }
15800
+ if (value.size > 0 && data.length !== value.size) return null;
15801
+ const downloadedPath = join3(dir, sanitizeSegment(value.filename));
15802
+ await writeFile3(downloadedPath, data);
15803
+ if (value.mimeType.startsWith("image/")) {
15804
+ images.push({ localPath: downloadedPath, data, mimeType: value.mimeType });
15805
+ }
15806
+ return downloadedPath;
15807
+ } catch {
15808
+ return null;
15809
+ }
15810
+ }
15811
+ if (Array.isArray(value)) {
15812
+ return Promise.all(value.map(walk));
15813
+ }
15814
+ if (value && typeof value === "object") {
15815
+ const out = {};
15816
+ for (const [k, v] of Object.entries(value)) {
15817
+ out[k] = await walk(v);
15818
+ }
15819
+ return out;
15820
+ }
15821
+ return value;
15822
+ }
15823
+ const rewritten = await walk(result);
15824
+ return { result: rewritten, images };
15825
+ }
15826
+ function getDeviceIdFromArgs(args) {
15827
+ if (!args || typeof args !== "object") return void 0;
15828
+ const rec = args;
15829
+ if (typeof rec.udid === "string") return rec.udid;
15830
+ if (typeof rec.device_id === "string") return rec.device_id;
15831
+ return void 0;
15832
+ }
15833
+
15702
15834
  // ../argent-mcp/src/content.ts
15703
- import { readFile as readFile3 } from "node:fs/promises";
15835
+ import { readFile as readFile4 } from "node:fs/promises";
15704
15836
  var PNG_SIGNATURE = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
15837
+ function imageBlock(data, mimeType) {
15838
+ return { type: "image", data: data.toString("base64"), mimeType };
15839
+ }
15705
15840
  async function fetchPngBytes(url) {
15706
15841
  try {
15707
15842
  const res = await fetch(url);
@@ -15714,22 +15849,38 @@ async function fetchPngBytes(url) {
15714
15849
  return null;
15715
15850
  }
15716
15851
  }
15717
- async function toMcpContent(result, outputHint, args) {
15718
- if (outputHint === "image" && result && typeof result === "object" && "url" in result) {
15852
+ async function toMcpContent(result, outputHint, ctx, args) {
15853
+ const suppressImage = isRecord(args) && args.includeImageInContext === false;
15854
+ if (ctx) {
15855
+ const { result: rewritten, images } = await materializeArtifacts(result, ctx);
15856
+ if (outputHint === "image") {
15857
+ if (images.length > 0) {
15858
+ const saved = { type: "text", text: `Saved: ${images[0].localPath}` };
15859
+ if (suppressImage) return [saved];
15860
+ const blocks2 = images.map((img) => imageBlock(img.data, img.mimeType));
15861
+ blocks2.push(saved);
15862
+ return blocks2;
15863
+ }
15864
+ return legacyImageContent(rewritten, suppressImage);
15865
+ }
15866
+ const blocks = [{ type: "text", text: JSON.stringify(rewritten, null, 2) }];
15867
+ if (!suppressImage) for (const img of images) blocks.push(imageBlock(img.data, img.mimeType));
15868
+ return blocks;
15869
+ }
15870
+ if (outputHint === "image") {
15871
+ return legacyImageContent(result, suppressImage);
15872
+ }
15873
+ return [{ type: "text", text: JSON.stringify(result, null, 2) }];
15874
+ }
15875
+ async function legacyImageContent(result, suppressImage) {
15876
+ if (result && typeof result === "object" && "url" in result) {
15719
15877
  const r = result;
15720
- if (isRecord(args) && args.includeImageInContext === false) {
15721
- return [{ type: "text", text: `Saved: ${r.path}` }];
15878
+ if (suppressImage) {
15879
+ return [{ type: "text", text: `Saved: ${r.path ?? ""}` }];
15722
15880
  }
15723
15881
  const buf = await fetchPngBytes(r.url);
15724
15882
  if (buf) {
15725
- return [
15726
- {
15727
- type: "image",
15728
- data: buf.toString("base64"),
15729
- mimeType: "image/png"
15730
- },
15731
- { type: "text", text: `Saved: ${r.path ?? ""}` }
15732
- ];
15883
+ return [imageBlock(buf, "image/png"), { type: "text", text: `Saved: ${r.path ?? ""}` }];
15733
15884
  }
15734
15885
  return [
15735
15886
  {
@@ -15750,7 +15901,7 @@ function isScreenshotDiffResult(value) {
15750
15901
  async function screenshotDiffToMcpContent(result) {
15751
15902
  const blocks = [];
15752
15903
  if (typeof result.contextDiffPath === "string") {
15753
- const buf = await readFile3(result.contextDiffPath);
15904
+ const buf = await readFile4(result.contextDiffPath);
15754
15905
  blocks.push({
15755
15906
  type: "image",
15756
15907
  data: buf.toString("base64"),
@@ -15760,7 +15911,7 @@ async function screenshotDiffToMcpContent(result) {
15760
15911
  blocks.push({ type: "text", text: result.summary });
15761
15912
  return blocks;
15762
15913
  }
15763
- async function flowRunToMcpContent(result) {
15914
+ async function flowRunToMcpContent(result, ctx) {
15764
15915
  const blocks = [];
15765
15916
  if (result.executionPrerequisite) {
15766
15917
  blocks.push({
@@ -15784,7 +15935,7 @@ async function flowRunToMcpContent(result) {
15784
15935
  });
15785
15936
  } else {
15786
15937
  blocks.push({ type: "text", text: `[${num}] ${step.tool}` });
15787
- const stepContent = await toMcpContent(step.result, step.outputHint, step.args);
15938
+ const stepContent = await toMcpContent(step.result, step.outputHint, ctx, step.args);
15788
15939
  blocks.push(...stepContent);
15789
15940
  }
15790
15941
  }
@@ -15792,6 +15943,64 @@ async function flowRunToMcpContent(result) {
15792
15943
  return blocks;
15793
15944
  }
15794
15945
 
15946
+ // ../configuration-core/src/flags.ts
15947
+ import * as fs2 from "node:fs";
15948
+ import * as path3 from "node:path";
15949
+ import { homedir as homedir3 } from "node:os";
15950
+ var PROJECT_MARKERS = [".argent", ".git", "package.json"];
15951
+ function resolveProjectRoot(startDir) {
15952
+ const initial = path3.resolve(startDir);
15953
+ let current = initial;
15954
+ while (true) {
15955
+ for (const marker of PROJECT_MARKERS) {
15956
+ if (fs2.existsSync(path3.join(current, marker))) return current;
15957
+ }
15958
+ const parent = path3.dirname(current);
15959
+ if (parent === current) return initial;
15960
+ current = parent;
15961
+ }
15962
+ }
15963
+ function getFlagsPath(scope, options = {}) {
15964
+ const home = options.homeDir ?? homedir3();
15965
+ if (scope === "global") {
15966
+ return path3.join(home, ".argent", "flags.json");
15967
+ }
15968
+ const cwd = options.cwd ?? process.cwd();
15969
+ return path3.join(resolveProjectRoot(cwd), ".argent", "flags.json");
15970
+ }
15971
+ function readFlagsFile(filePath) {
15972
+ let raw;
15973
+ try {
15974
+ raw = fs2.readFileSync(filePath, "utf8");
15975
+ } catch {
15976
+ return {};
15977
+ }
15978
+ let parsed;
15979
+ try {
15980
+ parsed = JSON.parse(raw);
15981
+ } catch {
15982
+ return {};
15983
+ }
15984
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
15985
+ const flags = parsed.flags;
15986
+ if (!flags || typeof flags !== "object" || Array.isArray(flags)) return {};
15987
+ const out = {};
15988
+ for (const [k, v] of Object.entries(flags)) {
15989
+ if (typeof v === "boolean") out[k] = v;
15990
+ }
15991
+ return out;
15992
+ }
15993
+ function readFlags(scope, options = {}) {
15994
+ return readFlagsFile(getFlagsPath(scope, options));
15995
+ }
15996
+ function isFlagEnabled(name, options = {}) {
15997
+ const projectFlags = readFlags("project", options);
15998
+ if (Object.hasOwn(projectFlags, name)) return projectFlags[name];
15999
+ const globalFlags = readFlags("global", options);
16000
+ if (Object.hasOwn(globalFlags, name)) return globalFlags[name];
16001
+ return false;
16002
+ }
16003
+
15795
16004
  // ../argent-mcp/src/auto-screenshot.ts
15796
16005
  var AUTO_SCREENSHOT_TOOLS = /* @__PURE__ */ new Set([
15797
16006
  "gesture-tap",
@@ -15824,9 +16033,8 @@ var AUTO_SCREENSHOT_DELAY_MS_BY_TOOL = {
15824
16033
  "describe": 100
15825
16034
  };
15826
16035
  var DEFAULT_DELAY_MS = 1400;
15827
- function autoScreenshotEnabled() {
15828
- const v = process.env.ARGENT_AUTO_SCREENSHOT;
15829
- return v === void 0 || v === "" || v === "1" || v.toLowerCase() === "true";
16036
+ function autoScreenshotEnabled(options) {
16037
+ return !isFlagEnabled("disable-auto-screenshot", options);
15830
16038
  }
15831
16039
  function getUdidFromArgs(args) {
15832
16040
  if (args && typeof args === "object" && "udid" in args && typeof args.udid === "string") {
@@ -15897,6 +16105,7 @@ async function fetchWithReconnect(getUrl, reconnect, config2) {
15897
16105
  throw lastError;
15898
16106
  }
15899
16107
  async function startMcpServer(options) {
16108
+ const autoScreenshotOn = autoScreenshotEnabled();
15900
16109
  let TOOLS_URL;
15901
16110
  let AUTH_TOKEN;
15902
16111
  const resolved = await getResolvedToolsUrl();
@@ -15930,12 +16139,12 @@ async function startMcpServer(options) {
15930
16139
  }
15931
16140
  return reconnectPromise;
15932
16141
  }
15933
- const LOG_FILE2 = process.env.ARGENT_MCP_LOG ?? `${homedir3()}/.argent/mcp-calls.log`;
16142
+ const LOG_FILE2 = process.env.ARGENT_MCP_LOG ?? `${homedir4()}/.argent/mcp-calls.log`;
15934
16143
  let logDirReady = false;
15935
16144
  async function spyLog(entry) {
15936
16145
  try {
15937
16146
  if (!logDirReady) {
15938
- await mkdir3(dirname(LOG_FILE2), { recursive: true });
16147
+ await mkdir4(dirname2(LOG_FILE2), { recursive: true });
15939
16148
  logDirReady = true;
15940
16149
  }
15941
16150
  await appendFile(LOG_FILE2, JSON.stringify(entry) + "\n");
@@ -16006,21 +16215,30 @@ async function startMcpServer(options) {
16006
16215
  isError: false,
16007
16216
  result
16008
16217
  });
16218
+ const ctx = {
16219
+ toolsUrl: TOOLS_URL,
16220
+ authToken: AUTH_TOKEN,
16221
+ deviceId: getDeviceIdFromArgs(params.arguments)
16222
+ };
16009
16223
  let content;
16010
16224
  if (params.name === "flow-execute" && result && typeof result === "object" && "flow" in result && "steps" in result) {
16011
- content = await flowRunToMcpContent(result);
16225
+ content = await flowRunToMcpContent(result, ctx);
16012
16226
  } else if (params.name === "screenshot-diff" && isScreenshotDiffResult(result)) {
16013
16227
  content = await screenshotDiffToMcpContent(result);
16014
16228
  } else {
16015
- content = await toMcpContent(result, outputHint, params.arguments);
16229
+ content = await toMcpContent(result, outputHint, ctx, params.arguments);
16016
16230
  }
16017
16231
  const udid = getUdidFromArgs(params.arguments);
16018
- if (autoScreenshotEnabled() && udid && shouldAutoScreenshot(params.name)) {
16232
+ if (autoScreenshotOn && udid && shouldAutoScreenshot(params.name)) {
16019
16233
  const delayMs = getAutoScreenshotDelayMs(params.name);
16020
16234
  if (delayMs > 0) await new Promise((r) => setTimeout(r, delayMs));
16021
16235
  try {
16022
16236
  const screenshotResult = await callTool("screenshot", { udid });
16023
- const screenshotContent = await toMcpContent(screenshotResult.result, "image", { udid });
16237
+ const screenshotContent = await toMcpContent(screenshotResult.result, "image", {
16238
+ toolsUrl: TOOLS_URL,
16239
+ authToken: AUTH_TOKEN,
16240
+ deviceId: udid
16241
+ });
16024
16242
  const hasImage = screenshotContent.some((b) => b.type === "image");
16025
16243
  if (hasImage) {
16026
16244
  content = [
@@ -16083,7 +16301,7 @@ async function startMcpServer(options) {
16083
16301
  }, HEALTH_INTERVAL_MS);
16084
16302
  healthInterval.unref();
16085
16303
  }
16086
- if (process.env.ARGENT_AUTO_SHUTDOWN === "1") {
16304
+ if (process.env.ARGENT_TOOL_SERVER_SHUTDOWN_ON_MCP_EXIT === "1") {
16087
16305
  process.stdin.on("close", () => {
16088
16306
  fetch(`${TOOLS_URL}/shutdown`, { method: "POST", headers: authHeader() }).catch(() => {
16089
16307
  });