@pmate/cli 0.24.14 → 0.24.15

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.
Files changed (2) hide show
  1. package/dist/index.js +275 -182
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9016,10 +9016,33 @@ function unwrapAgentResult(agentId, value) {
9016
9016
  }
9017
9017
  return value;
9018
9018
  }
9019
- var DEFAULT_AGENT_API_BASE_URL, DEFAULT_AGENT_HUB_BASE_URL, DEFAULT_NAMESPACE, DEFAULT_FROM, DEFAULT_AGENT_PROMPT_TIMEOUT_MS, AgentLlmClient;
9019
+ function resolveMimeType(filePath) {
9020
+ const ext = import_node_path11.default.extname(filePath).toLowerCase();
9021
+ switch (ext) {
9022
+ case ".wav":
9023
+ return "audio/wav";
9024
+ case ".mp3":
9025
+ return "audio/mpeg";
9026
+ case ".m4a":
9027
+ return "audio/mp4";
9028
+ case ".mp4":
9029
+ return "audio/mp4";
9030
+ case ".ogg":
9031
+ return "audio/ogg";
9032
+ case ".webm":
9033
+ return "audio/webm";
9034
+ case ".flac":
9035
+ return "audio/flac";
9036
+ default:
9037
+ return "application/octet-stream";
9038
+ }
9039
+ }
9040
+ var import_node_fs7, import_node_path11, DEFAULT_AGENT_API_BASE_URL, DEFAULT_AGENT_HUB_BASE_URL, DEFAULT_NAMESPACE, DEFAULT_FROM, DEFAULT_AGENT_PROMPT_TIMEOUT_MS, AgentLlmClient;
9020
9041
  var init_AgentLlmClient = __esm({
9021
9042
  "src/llm/AgentLlmClient.ts"() {
9022
9043
  "use strict";
9044
+ import_node_fs7 = require("fs");
9045
+ import_node_path11 = __toESM(require("path"));
9023
9046
  init_dist2();
9024
9047
  init_sessionStore();
9025
9048
  DEFAULT_AGENT_API_BASE_URL = "https://agent-api.pmate.chat";
@@ -9061,6 +9084,33 @@ var init_AgentLlmClient = __esm({
9061
9084
  client.close();
9062
9085
  }
9063
9086
  }
9087
+ async callFile(agentId, filePath, params, options) {
9088
+ const client = new AgentClient({
9089
+ baseUrl: options?.hubBaseUrl ?? this.hubBaseUrl,
9090
+ agentService: this.agentService,
9091
+ timeoutMs: DEFAULT_AGENT_PROMPT_TIMEOUT_MS,
9092
+ streamTimeoutMs: DEFAULT_AGENT_PROMPT_TIMEOUT_MS,
9093
+ minChunkSizeBytes: 0
9094
+ });
9095
+ try {
9096
+ await client.login(options?.from ?? this.from, {
9097
+ token: this.token
9098
+ });
9099
+ const input = new AsyncStream();
9100
+ const stream = client.stream({
9101
+ agentId,
9102
+ stream: input,
9103
+ params,
9104
+ minChunkSizeBytes: 0
9105
+ });
9106
+ const file = (0, import_node_fs7.readFileSync)(filePath);
9107
+ input.push(new Blob([file], { type: resolveMimeType(filePath) }));
9108
+ input.end();
9109
+ return await stream.finish();
9110
+ } finally {
9111
+ client.close();
9112
+ }
9113
+ }
9064
9114
  };
9065
9115
  }
9066
9116
  });
@@ -9071,8 +9121,8 @@ __export(index_exports, {
9071
9121
  parseCommandArgs: () => parseCommandArgs
9072
9122
  });
9073
9123
  module.exports = __toCommonJS(index_exports);
9074
- var import_node_fs22 = require("fs");
9075
- var import_node_path26 = __toESM(require("path"));
9124
+ var import_node_fs23 = require("fs");
9125
+ var import_node_path27 = __toESM(require("path"));
9076
9126
  var import_chalk4 = __toESM(require("chalk"));
9077
9127
 
9078
9128
  // src/cli.ts
@@ -12326,7 +12376,7 @@ var CommitCommandHandler = class {
12326
12376
 
12327
12377
  // src/commands/SummaryCommandHandler.ts
12328
12378
  var import_node_child_process7 = require("child_process");
12329
- var import_node_path11 = __toESM(require("path"));
12379
+ var import_node_path12 = __toESM(require("path"));
12330
12380
  var SummaryCommandHandler = class {
12331
12381
  async handle(args) {
12332
12382
  const cwd = this.resolveCwd(args.cwd);
@@ -12511,7 +12561,7 @@ var SummaryCommandHandler = class {
12511
12561
  return this.runCapture("gh", args, allowFailure, await this.getGhEnv(cwd), cwd);
12512
12562
  }
12513
12563
  resolveCwd(value) {
12514
- return value ? import_node_path11.default.resolve(process.cwd(), value) : process.cwd();
12564
+ return value ? import_node_path12.default.resolve(process.cwd(), value) : process.cwd();
12515
12565
  }
12516
12566
  };
12517
12567
  function truncate2(value, limit) {
@@ -12524,9 +12574,9 @@ function truncate2(value, limit) {
12524
12574
 
12525
12575
  // src/commands/LinearCommandHandler.ts
12526
12576
  var import_node_child_process8 = require("child_process");
12527
- var import_node_fs7 = require("fs");
12577
+ var import_node_fs8 = require("fs");
12528
12578
  var import_node_os4 = __toESM(require("os"));
12529
- var import_node_path12 = __toESM(require("path"));
12579
+ var import_node_path13 = __toESM(require("path"));
12530
12580
  var import_promises3 = require("readline/promises");
12531
12581
  var import_openai = __toESM(require("openai"));
12532
12582
  var import_sdk = require("@linear/sdk");
@@ -13410,15 +13460,15 @@ var LinearCommandHandler = class {
13410
13460
  }
13411
13461
  }
13412
13462
  getLinearSelectionPath() {
13413
- return import_node_path12.default.join(import_node_os4.default.homedir(), ".pmate", "linear-selection.json");
13463
+ return import_node_path13.default.join(import_node_os4.default.homedir(), ".pmate", "linear-selection.json");
13414
13464
  }
13415
13465
  readCachedLinearSelection(cwd) {
13416
13466
  const selectionPath = this.getLinearSelectionPath();
13417
- if (!(0, import_node_fs7.existsSync)(selectionPath)) {
13467
+ if (!(0, import_node_fs8.existsSync)(selectionPath)) {
13418
13468
  return void 0;
13419
13469
  }
13420
13470
  try {
13421
- const raw = (0, import_node_fs7.readFileSync)(selectionPath, "utf8").trim();
13471
+ const raw = (0, import_node_fs8.readFileSync)(selectionPath, "utf8").trim();
13422
13472
  if (!raw) return void 0;
13423
13473
  const parsed = JSON.parse(raw);
13424
13474
  const value = parsed[cwd];
@@ -13429,12 +13479,12 @@ var LinearCommandHandler = class {
13429
13479
  }
13430
13480
  writeCachedLinearSelection(cwd, title) {
13431
13481
  const selectionPath = this.getLinearSelectionPath();
13432
- const dir = import_node_path12.default.dirname(selectionPath);
13433
- (0, import_node_fs7.mkdirSync)(dir, { recursive: true });
13482
+ const dir = import_node_path13.default.dirname(selectionPath);
13483
+ (0, import_node_fs8.mkdirSync)(dir, { recursive: true });
13434
13484
  let data = {};
13435
- if ((0, import_node_fs7.existsSync)(selectionPath)) {
13485
+ if ((0, import_node_fs8.existsSync)(selectionPath)) {
13436
13486
  try {
13437
- const raw = (0, import_node_fs7.readFileSync)(selectionPath, "utf8").trim();
13487
+ const raw = (0, import_node_fs8.readFileSync)(selectionPath, "utf8").trim();
13438
13488
  if (raw) {
13439
13489
  data = JSON.parse(raw);
13440
13490
  }
@@ -13443,7 +13493,7 @@ var LinearCommandHandler = class {
13443
13493
  }
13444
13494
  }
13445
13495
  data[cwd] = title;
13446
- (0, import_node_fs7.writeFileSync)(selectionPath, `${JSON.stringify(data, null, 2)}
13496
+ (0, import_node_fs8.writeFileSync)(selectionPath, `${JSON.stringify(data, null, 2)}
13447
13497
  `, "utf8");
13448
13498
  }
13449
13499
  async lookupIssue(client, issueRef) {
@@ -13620,14 +13670,14 @@ var LinearCommandHandler = class {
13620
13670
  if (process.platform !== "darwin") {
13621
13671
  throw new Error("Screenshot capture only supports macOS.");
13622
13672
  }
13623
- const dir = await import_node_fs7.promises.mkdtemp(import_node_path12.default.join(import_node_os4.default.tmpdir(), "pmate-screenshot-"));
13624
- const filePath = import_node_path12.default.join(dir, `screenshot-${index}.png`);
13673
+ const dir = await import_node_fs8.promises.mkdtemp(import_node_path13.default.join(import_node_os4.default.tmpdir(), "pmate-screenshot-"));
13674
+ const filePath = import_node_path13.default.join(dir, `screenshot-${index}.png`);
13625
13675
  try {
13626
13676
  const code = await this.run("screencapture", ["-i", "-x", filePath], true);
13627
13677
  if (code !== 0) {
13628
13678
  throw new Error("Screenshot capture canceled or failed.");
13629
13679
  }
13630
- const buffer = await import_node_fs7.promises.readFile(filePath);
13680
+ const buffer = await import_node_fs8.promises.readFile(filePath);
13631
13681
  if (buffer.length === 0) {
13632
13682
  throw new Error("Screenshot capture produced an empty file.");
13633
13683
  }
@@ -13639,7 +13689,7 @@ var LinearCommandHandler = class {
13639
13689
  return { buffer, mime, filename: `screenshot-${index}.${extension}` };
13640
13690
  } finally {
13641
13691
  try {
13642
- await import_node_fs7.promises.rm(dir, { recursive: true, force: true });
13692
+ await import_node_fs8.promises.rm(dir, { recursive: true, force: true });
13643
13693
  } catch {
13644
13694
  }
13645
13695
  }
@@ -13783,17 +13833,17 @@ var LinearCommandHandler = class {
13783
13833
  return compact.length > limit ? `${compact.slice(0, limit)}...` : compact;
13784
13834
  }
13785
13835
  async convertToPng(buffer, ext) {
13786
- const dir = await import_node_fs7.promises.mkdtemp(import_node_path12.default.join(import_node_os4.default.tmpdir(), "pmate-"));
13787
- const inputPath = import_node_path12.default.join(dir, `clipboard.${ext}`);
13788
- const outputPath = import_node_path12.default.join(dir, "clipboard.png");
13836
+ const dir = await import_node_fs8.promises.mkdtemp(import_node_path13.default.join(import_node_os4.default.tmpdir(), "pmate-"));
13837
+ const inputPath = import_node_path13.default.join(dir, `clipboard.${ext}`);
13838
+ const outputPath = import_node_path13.default.join(dir, "clipboard.png");
13789
13839
  try {
13790
- await import_node_fs7.promises.writeFile(inputPath, buffer);
13840
+ await import_node_fs8.promises.writeFile(inputPath, buffer);
13791
13841
  const stderr = await this.runCapture(
13792
13842
  "sips",
13793
13843
  ["-s", "format", "png", inputPath, "--out", outputPath],
13794
13844
  true
13795
13845
  );
13796
- const out = await import_node_fs7.promises.readFile(outputPath);
13846
+ const out = await import_node_fs8.promises.readFile(outputPath);
13797
13847
  if (this.detectImageMime(out) !== "image/png") {
13798
13848
  throw new Error(
13799
13849
  stderr?.trim() ? `Failed to convert clipboard ${ext} to PNG: ${stderr.trim()}` : `Failed to convert clipboard ${ext} to PNG.`
@@ -13802,7 +13852,7 @@ var LinearCommandHandler = class {
13802
13852
  return out;
13803
13853
  } finally {
13804
13854
  try {
13805
- await import_node_fs7.promises.rm(dir, { recursive: true, force: true });
13855
+ await import_node_fs8.promises.rm(dir, { recursive: true, force: true });
13806
13856
  } catch {
13807
13857
  }
13808
13858
  }
@@ -14096,7 +14146,7 @@ var LinearCommandHandler = class {
14096
14146
  return this.runCapture("gh", args, allowFailure, await this.getGhEnv(cwd), cwd);
14097
14147
  }
14098
14148
  resolveCwd(value) {
14099
- return value ? import_node_path12.default.resolve(process.cwd(), value) : process.cwd();
14149
+ return value ? import_node_path13.default.resolve(process.cwd(), value) : process.cwd();
14100
14150
  }
14101
14151
  createOpenAiClient() {
14102
14152
  const config = loadPmateConfig();
@@ -14148,8 +14198,8 @@ function sleep2(ms) {
14148
14198
  }
14149
14199
 
14150
14200
  // src/commands/NotionCommandHandler.ts
14151
- var import_node_fs8 = require("fs");
14152
- var import_node_path13 = __toESM(require("path"));
14201
+ var import_node_fs9 = require("fs");
14202
+ var import_node_path14 = __toESM(require("path"));
14153
14203
 
14154
14204
  // src/services/NotionService.ts
14155
14205
  var NotionService = class {
@@ -14388,9 +14438,9 @@ ${indent}\`\`\``;
14388
14438
  static richTextToPlain(richText) {
14389
14439
  return richText.map((item) => item.plain_text ?? item.text?.content ?? "").join("").trim();
14390
14440
  }
14391
- static async requestJson(path27, init) {
14441
+ static async requestJson(path28, init) {
14392
14442
  const token = this.getToken();
14393
- const response = await fetch(`${this.baseUrl}${path27}`, {
14443
+ const response = await fetch(`${this.baseUrl}${path28}`, {
14394
14444
  method: init.method,
14395
14445
  headers: {
14396
14446
  Authorization: `Bearer ${token}`,
@@ -14488,16 +14538,16 @@ var NotionCommandHandler = class {
14488
14538
  if (!args.filePath) {
14489
14539
  return "";
14490
14540
  }
14491
- const resolved = import_node_path13.default.resolve(process.cwd(), args.filePath);
14492
- return (0, import_node_fs8.readFileSync)(resolved, "utf8");
14541
+ const resolved = import_node_path14.default.resolve(process.cwd(), args.filePath);
14542
+ return (0, import_node_fs9.readFileSync)(resolved, "utf8");
14493
14543
  }
14494
14544
  };
14495
14545
 
14496
14546
  // src/commands/QrcodeCommandHandler.ts
14497
14547
  var import_node_child_process9 = require("child_process");
14498
- var import_node_fs9 = require("fs");
14548
+ var import_node_fs10 = require("fs");
14499
14549
  var import_node_os5 = __toESM(require("os"));
14500
- var import_node_path14 = __toESM(require("path"));
14550
+ var import_node_path15 = __toESM(require("path"));
14501
14551
  var import_promises4 = require("readline/promises");
14502
14552
  var import_jsqr = __toESM(require("jsqr"));
14503
14553
  var import_pngjs = require("pngjs");
@@ -14523,7 +14573,7 @@ var QrcodeCommandHandler = class {
14523
14573
  ui.success("QR code value:", value);
14524
14574
  } finally {
14525
14575
  try {
14526
- await import_node_fs9.promises.rm(dir, { recursive: true, force: true });
14576
+ await import_node_fs10.promises.rm(dir, { recursive: true, force: true });
14527
14577
  } catch {
14528
14578
  }
14529
14579
  }
@@ -14539,13 +14589,13 @@ var QrcodeCommandHandler = class {
14539
14589
  } finally {
14540
14590
  rl.close();
14541
14591
  }
14542
- const dir = await import_node_fs9.promises.mkdtemp(import_node_path14.default.join(import_node_os5.default.tmpdir(), "pmate-qrcode-"));
14543
- const filePath = import_node_path14.default.join(dir, "qrcode.png");
14592
+ const dir = await import_node_fs10.promises.mkdtemp(import_node_path15.default.join(import_node_os5.default.tmpdir(), "pmate-qrcode-"));
14593
+ const filePath = import_node_path15.default.join(dir, "qrcode.png");
14544
14594
  const code = await this.run("screencapture", ["-i", "-x", filePath], true);
14545
14595
  if (code !== 0) {
14546
14596
  throw new Error("Screenshot capture canceled or failed.");
14547
14597
  }
14548
- const buffer = await import_node_fs9.promises.readFile(filePath);
14598
+ const buffer = await import_node_fs10.promises.readFile(filePath);
14549
14599
  if (buffer.length === 0) {
14550
14600
  throw new Error("Screenshot capture produced an empty file.");
14551
14601
  }
@@ -14561,7 +14611,7 @@ var QrcodeCommandHandler = class {
14561
14611
  async decodeQr(filePath) {
14562
14612
  let buffer;
14563
14613
  try {
14564
- buffer = await import_node_fs9.promises.readFile(filePath);
14614
+ buffer = await import_node_fs10.promises.readFile(filePath);
14565
14615
  } catch {
14566
14616
  return null;
14567
14617
  }
@@ -14819,8 +14869,8 @@ function clampNumber(value, min, max, fallback) {
14819
14869
  }
14820
14870
 
14821
14871
  // src/commands/QuizCommandHandler.ts
14822
- var import_node_fs10 = require("fs");
14823
- var import_node_path15 = __toESM(require("path"));
14872
+ var import_node_fs11 = require("fs");
14873
+ var import_node_path16 = __toESM(require("path"));
14824
14874
  init_sessionStore();
14825
14875
 
14826
14876
  // src/services/QuizService.ts
@@ -15336,8 +15386,8 @@ var QuizCommandHandler = class {
15336
15386
  return;
15337
15387
  }
15338
15388
  if (args.action === "update-meta") {
15339
- const resolvedFilePath = import_node_path15.default.resolve(process.cwd(), args.filePath);
15340
- const metadata = JSON.parse((0, import_node_fs10.readFileSync)(resolvedFilePath, "utf8"));
15389
+ const resolvedFilePath = import_node_path16.default.resolve(process.cwd(), args.filePath);
15390
+ const metadata = JSON.parse((0, import_node_fs11.readFileSync)(resolvedFilePath, "utf8"));
15341
15391
  const result = await updateQuizPaperMetadata({
15342
15392
  apiBaseUrl,
15343
15393
  linkBaseUrl,
@@ -15349,8 +15399,8 @@ var QuizCommandHandler = class {
15349
15399
  return;
15350
15400
  }
15351
15401
  if (args.action === "append-step") {
15352
- const resolvedFilePath = import_node_path15.default.resolve(process.cwd(), args.filePath);
15353
- const step = JSON.parse((0, import_node_fs10.readFileSync)(resolvedFilePath, "utf8"));
15402
+ const resolvedFilePath = import_node_path16.default.resolve(process.cwd(), args.filePath);
15403
+ const step = JSON.parse((0, import_node_fs11.readFileSync)(resolvedFilePath, "utf8"));
15354
15404
  const result = await appendQuizPaperStep({
15355
15405
  apiBaseUrl,
15356
15406
  linkBaseUrl,
@@ -15363,8 +15413,8 @@ var QuizCommandHandler = class {
15363
15413
  return;
15364
15414
  }
15365
15415
  if (args.action === "update-step") {
15366
- const resolvedFilePath = import_node_path15.default.resolve(process.cwd(), args.filePath);
15367
- const step = JSON.parse((0, import_node_fs10.readFileSync)(resolvedFilePath, "utf8"));
15416
+ const resolvedFilePath = import_node_path16.default.resolve(process.cwd(), args.filePath);
15417
+ const step = JSON.parse((0, import_node_fs11.readFileSync)(resolvedFilePath, "utf8"));
15368
15418
  step.stepId = args.stepId;
15369
15419
  const result = await updateQuizPaperStep({
15370
15420
  apiBaseUrl,
@@ -15415,8 +15465,8 @@ var QuizCommandHandler = class {
15415
15465
  if (targetIndex < 0) {
15416
15466
  throw new Error(`\u672A\u627E\u5230 stepId=${args.stepId}\uFF0C\u65E0\u6CD5\u66F4\u65B0\u8BE5\u9898\u76EE\u3002`);
15417
15467
  }
15418
- const resolvedFilePath = import_node_path15.default.resolve(process.cwd(), args.filePath);
15419
- const nextStep = JSON.parse((0, import_node_fs10.readFileSync)(resolvedFilePath, "utf8"));
15468
+ const resolvedFilePath = import_node_path16.default.resolve(process.cwd(), args.filePath);
15469
+ const nextStep = JSON.parse((0, import_node_fs11.readFileSync)(resolvedFilePath, "utf8"));
15420
15470
  nextStep.stepId = args.stepId;
15421
15471
  const nextSteps = [...basePaper.steps];
15422
15472
  nextSteps[targetIndex] = nextStep;
@@ -15470,13 +15520,13 @@ var import_playwright = require("playwright");
15470
15520
 
15471
15521
  // src/collectStore.ts
15472
15522
  var import_node_crypto3 = require("crypto");
15473
- var import_node_fs11 = require("fs");
15523
+ var import_node_fs12 = require("fs");
15474
15524
  var import_node_os6 = __toESM(require("os"));
15475
- var import_node_path16 = __toESM(require("path"));
15525
+ var import_node_path17 = __toESM(require("path"));
15476
15526
  function resolveCollectTarget(input) {
15477
15527
  const endpoint = input.endpoint ?? (input.source === "cc" ? "http://localhost:9223" : "http://localhost:9222");
15478
15528
  const sourceKey = input.source ?? `endpoint-${(0, import_node_crypto3.createHash)("sha1").update(endpoint).digest("hex").slice(0, 8)}`;
15479
- const rootDir = import_node_path16.default.join(import_node_os6.default.homedir(), ".pmate", "collect", sourceKey);
15529
+ const rootDir = import_node_path17.default.join(import_node_os6.default.homedir(), ".pmate", "collect", sourceKey);
15480
15530
  return { sourceKey, endpoint, rootDir };
15481
15531
  }
15482
15532
  function toThreadKey(name) {
@@ -15488,7 +15538,7 @@ function toThreadKey(name) {
15488
15538
  async function readStoredThread(rootDir, threadKey) {
15489
15539
  const filePath = getThreadMetaFilePath(rootDir, threadKey);
15490
15540
  try {
15491
- const raw = await import_node_fs11.promises.readFile(filePath, "utf8");
15541
+ const raw = await import_node_fs12.promises.readFile(filePath, "utf8");
15492
15542
  const parsed = JSON.parse(raw);
15493
15543
  if ("messages" in parsed && Array.isArray(parsed.messages)) {
15494
15544
  return parsed;
@@ -15506,15 +15556,15 @@ async function writeStoredThread(rootDir, thread) {
15506
15556
  const metaPath = getThreadMetaFilePath(rootDir, thread.threadKey);
15507
15557
  const messagePath = getThreadMessagesFilePath(rootDir, thread.threadKey);
15508
15558
  const { messages: messages2, ...meta } = thread;
15509
- await import_node_fs11.promises.mkdir(import_node_path16.default.dirname(metaPath), { recursive: true });
15510
- await import_node_fs11.promises.writeFile(metaPath, JSON.stringify(meta, null, 2) + "\n", "utf8");
15559
+ await import_node_fs12.promises.mkdir(import_node_path17.default.dirname(metaPath), { recursive: true });
15560
+ await import_node_fs12.promises.writeFile(metaPath, JSON.stringify(meta, null, 2) + "\n", "utf8");
15511
15561
  const body = messages2.map((message) => JSON.stringify(message)).join("\n");
15512
- await import_node_fs11.promises.writeFile(messagePath, `${body}${body ? "\n" : ""}`, "utf8");
15562
+ await import_node_fs12.promises.writeFile(messagePath, `${body}${body ? "\n" : ""}`, "utf8");
15513
15563
  }
15514
15564
  async function writeStoredIndex(rootDir, index) {
15515
- await import_node_fs11.promises.mkdir(rootDir, { recursive: true });
15516
- const filePath = import_node_path16.default.join(rootDir, "index.json");
15517
- await import_node_fs11.promises.writeFile(filePath, JSON.stringify(index, null, 2) + "\n", "utf8");
15565
+ await import_node_fs12.promises.mkdir(rootDir, { recursive: true });
15566
+ const filePath = import_node_path17.default.join(rootDir, "index.json");
15567
+ await import_node_fs12.promises.writeFile(filePath, JSON.stringify(index, null, 2) + "\n", "utf8");
15518
15568
  }
15519
15569
  function mergeMessages(existing, incoming) {
15520
15570
  const seenMessageIds = new Set(
@@ -15567,7 +15617,7 @@ function joinNormalized(values) {
15567
15617
  async function readStoredMessages(rootDir, threadKey) {
15568
15618
  const filePath = getThreadMessagesFilePath(rootDir, threadKey);
15569
15619
  try {
15570
- const raw = await import_node_fs11.promises.readFile(filePath, "utf8");
15620
+ const raw = await import_node_fs12.promises.readFile(filePath, "utf8");
15571
15621
  return raw.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => normalizeStoredMessage(JSON.parse(line)));
15572
15622
  } catch {
15573
15623
  return [];
@@ -15576,20 +15626,20 @@ async function readStoredMessages(rootDir, threadKey) {
15576
15626
  async function readLegacyStoredThread(rootDir, threadKey) {
15577
15627
  const filePath = getLegacyThreadFilePath(rootDir, threadKey);
15578
15628
  try {
15579
- const raw = await import_node_fs11.promises.readFile(filePath, "utf8");
15629
+ const raw = await import_node_fs12.promises.readFile(filePath, "utf8");
15580
15630
  return JSON.parse(raw);
15581
15631
  } catch {
15582
15632
  return null;
15583
15633
  }
15584
15634
  }
15585
15635
  function getThreadMetaFilePath(rootDir, threadKey) {
15586
- return import_node_path16.default.join(rootDir, "threads", `${threadKey}.json`);
15636
+ return import_node_path17.default.join(rootDir, "threads", `${threadKey}.json`);
15587
15637
  }
15588
15638
  function getThreadMessagesFilePath(rootDir, threadKey) {
15589
- return import_node_path16.default.join(rootDir, "threads", `${threadKey}.jsonl`);
15639
+ return import_node_path17.default.join(rootDir, "threads", `${threadKey}.jsonl`);
15590
15640
  }
15591
15641
  function getLegacyThreadFilePath(rootDir, threadKey) {
15592
- return import_node_path16.default.join(rootDir, "threads", `${threadKey}.json`);
15642
+ return import_node_path17.default.join(rootDir, "threads", `${threadKey}.json`);
15593
15643
  }
15594
15644
  function normalizeStoredMessage(message) {
15595
15645
  return {
@@ -16053,7 +16103,7 @@ function pad2(value) {
16053
16103
  }
16054
16104
 
16055
16105
  // src/commands/ChatRoomCommandHandler.ts
16056
- var import_node_fs12 = require("fs");
16106
+ var import_node_fs13 = require("fs");
16057
16107
  var ChatRoomCommandHandler = class {
16058
16108
  async handle(args) {
16059
16109
  const sdk = await loadChatSdk();
@@ -16103,8 +16153,8 @@ var ChatRoomCommandHandler = class {
16103
16153
  const a = await this.connect(sdk, args.botA, args.app, args.hubUrl, args.authBaseUrl);
16104
16154
  const b = await this.connect(sdk, args.botB, args.app, args.hubUrl, args.authBaseUrl);
16105
16155
  try {
16106
- const botA = sdk.parsePmateBotKeyJson((0, import_node_fs12.readFileSync)(args.botA, "utf8"));
16107
- const botB = sdk.parsePmateBotKeyJson((0, import_node_fs12.readFileSync)(args.botB, "utf8"));
16156
+ const botA = sdk.parsePmateBotKeyJson((0, import_node_fs13.readFileSync)(args.botA, "utf8"));
16157
+ const botB = sdk.parsePmateBotKeyJson((0, import_node_fs13.readFileSync)(args.botB, "utf8"));
16108
16158
  await a.requestFriend({ to: botB.name, message: "smoke friend request" });
16109
16159
  await b.acceptFriend({ to: botA.name, message: "smoke friend accept" });
16110
16160
  await a.sendDm({ to: botB.name, text: "smoke dm from a" });
@@ -16123,7 +16173,7 @@ var ChatRoomCommandHandler = class {
16123
16173
  if (!botPath) {
16124
16174
  throw new Error("Missing required option: --bot");
16125
16175
  }
16126
- const botKey = sdk.parsePmateBotKeyJson((0, import_node_fs12.readFileSync)(botPath, "utf8"));
16176
+ const botKey = sdk.parsePmateBotKeyJson((0, import_node_fs13.readFileSync)(botPath, "utf8"));
16127
16177
  const client = sdk.createChatClient({ appId, botKey, hubUrl, authBaseUrl });
16128
16178
  await client.connect();
16129
16179
  return client;
@@ -16135,8 +16185,8 @@ async function loadChatSdk() {
16135
16185
  }
16136
16186
 
16137
16187
  // src/commands/AgentCommandHandler.ts
16138
- var import_node_fs13 = require("fs");
16139
- var import_node_path17 = __toESM(require("path"));
16188
+ var import_node_fs14 = require("fs");
16189
+ var import_node_path18 = __toESM(require("path"));
16140
16190
  init_AgentLlmClient();
16141
16191
  init_sessionStore();
16142
16192
 
@@ -16169,8 +16219,8 @@ function descriptorPathSegments(descriptor) {
16169
16219
  return ["chains", normalized.chain, "namespaces", normalized.ns, normalized.kind, normalized.name];
16170
16220
  }
16171
16221
  function buildPathUrl(baseUrl, pathSegments, query) {
16172
- const path27 = `/${pathSegments.map((segment) => encodeURIComponent(segment)).join("/")}`;
16173
- const url = new URL(path27, baseUrl);
16222
+ const path28 = `/${pathSegments.map((segment) => encodeURIComponent(segment)).join("/")}`;
16223
+ const url = new URL(path28, baseUrl);
16174
16224
  if (query) {
16175
16225
  for (const [key, value] of Object.entries(query)) {
16176
16226
  url.searchParams.set(key, String(value));
@@ -16507,16 +16557,44 @@ var AgentCommandHandler = class {
16507
16557
  return;
16508
16558
  }
16509
16559
  case "call": {
16510
- const payload = args.filePath ? this.readJsonObjectFile(args.filePath) : args.payload;
16511
16560
  const client = this.createRuntimeClient({
16512
16561
  token,
16513
16562
  agentApiBaseUrl: baseUrl,
16514
16563
  hubBaseUrl: args.hubBaseUrl,
16515
16564
  from: args.from
16516
16565
  });
16566
+ if (args.filePath) {
16567
+ const filePayload = this.tryReadJsonObjectFile(args.filePath);
16568
+ if (filePayload) {
16569
+ if (args.payload) {
16570
+ throw new Error("Agent call accepts --payload with --file only when --file is a binary stream input.");
16571
+ }
16572
+ const result3 = await client.call(
16573
+ formatNamespacedDisplayId(args.namespace, args.name),
16574
+ filePayload,
16575
+ {
16576
+ hubBaseUrl: args.hubBaseUrl,
16577
+ from: args.from
16578
+ }
16579
+ );
16580
+ this.renderCallResult(result3, args.json);
16581
+ return;
16582
+ }
16583
+ const result2 = await client.callFile(
16584
+ formatNamespacedDisplayId(args.namespace, args.name),
16585
+ this.resolveExistingFile(args.filePath),
16586
+ args.payload,
16587
+ {
16588
+ hubBaseUrl: args.hubBaseUrl,
16589
+ from: args.from
16590
+ }
16591
+ );
16592
+ this.renderCallResult(result2, args.json);
16593
+ return;
16594
+ }
16517
16595
  const result = await client.call(
16518
16596
  formatNamespacedDisplayId(args.namespace, args.name),
16519
- payload,
16597
+ args.payload,
16520
16598
  {
16521
16599
  hubBaseUrl: args.hubBaseUrl,
16522
16600
  from: args.from
@@ -16602,11 +16680,11 @@ var AgentCommandHandler = class {
16602
16680
  }).token;
16603
16681
  }
16604
16682
  readJsonFile(filePath) {
16605
- const absolutePath = import_node_path17.default.resolve(process.cwd(), filePath);
16606
- if (!(0, import_node_fs13.existsSync)(absolutePath)) {
16683
+ const absolutePath = import_node_path18.default.resolve(process.cwd(), filePath);
16684
+ if (!(0, import_node_fs14.existsSync)(absolutePath)) {
16607
16685
  throw new Error(`JSON file not found: ${absolutePath}`);
16608
16686
  }
16609
- const raw = (0, import_node_fs13.readFileSync)(absolutePath, "utf8");
16687
+ const raw = (0, import_node_fs14.readFileSync)(absolutePath, "utf8");
16610
16688
  try {
16611
16689
  return JSON.parse(raw);
16612
16690
  } catch (error) {
@@ -16617,11 +16695,31 @@ var AgentCommandHandler = class {
16617
16695
  readJsonObjectFile(filePath) {
16618
16696
  const parsed = this.readJsonFile(filePath);
16619
16697
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
16620
- const absolutePath = import_node_path17.default.resolve(process.cwd(), filePath);
16698
+ const absolutePath = import_node_path18.default.resolve(process.cwd(), filePath);
16621
16699
  throw new Error(`Invalid JSON in ${absolutePath}: expected an object`);
16622
16700
  }
16623
16701
  return parsed;
16624
16702
  }
16703
+ tryReadJsonObjectFile(filePath) {
16704
+ const absolutePath = this.resolveExistingFile(filePath);
16705
+ const raw = (0, import_node_fs14.readFileSync)(absolutePath, "utf8");
16706
+ try {
16707
+ const parsed = JSON.parse(raw);
16708
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
16709
+ throw new Error("expected an object");
16710
+ }
16711
+ return parsed;
16712
+ } catch {
16713
+ return null;
16714
+ }
16715
+ }
16716
+ resolveExistingFile(filePath) {
16717
+ const absolutePath = import_node_path18.default.resolve(process.cwd(), filePath);
16718
+ if (!(0, import_node_fs14.existsSync)(absolutePath)) {
16719
+ throw new Error(`File not found: ${absolutePath}`);
16720
+ }
16721
+ return absolutePath;
16722
+ }
16625
16723
  async request(baseUrl, token, method, pathname, body) {
16626
16724
  const response = await fetch(`${baseUrl}${pathname}`, {
16627
16725
  method,
@@ -16701,8 +16799,8 @@ var AgentCommandHandler = class {
16701
16799
  };
16702
16800
 
16703
16801
  // src/commands/RunnerCommandHandler.ts
16704
- var import_node_fs14 = require("fs");
16705
- var import_node_path18 = __toESM(require("path"));
16802
+ var import_node_fs15 = require("fs");
16803
+ var import_node_path19 = __toESM(require("path"));
16706
16804
  init_sessionStore();
16707
16805
  init_namespacedRef();
16708
16806
  var RunnerCommandHandler = class {
@@ -16797,11 +16895,11 @@ var RunnerCommandHandler = class {
16797
16895
  }).token;
16798
16896
  }
16799
16897
  readJsonFile(filePath) {
16800
- const absolutePath = import_node_path18.default.resolve(process.cwd(), filePath);
16801
- if (!(0, import_node_fs14.existsSync)(absolutePath)) {
16898
+ const absolutePath = import_node_path19.default.resolve(process.cwd(), filePath);
16899
+ if (!(0, import_node_fs15.existsSync)(absolutePath)) {
16802
16900
  throw new Error(`JSON file not found: ${absolutePath}`);
16803
16901
  }
16804
- const raw = (0, import_node_fs14.readFileSync)(absolutePath, "utf8");
16902
+ const raw = (0, import_node_fs15.readFileSync)(absolutePath, "utf8");
16805
16903
  try {
16806
16904
  return JSON.parse(raw);
16807
16905
  } catch (error) {
@@ -16920,8 +17018,8 @@ var NsCommandHandler = class {
16920
17018
  };
16921
17019
 
16922
17020
  // src/commands/StoreCommandHandler.ts
16923
- var import_node_fs15 = require("fs");
16924
- var import_node_path19 = __toESM(require("path"));
17021
+ var import_node_fs16 = require("fs");
17022
+ var import_node_path20 = __toESM(require("path"));
16925
17023
  var StoreCommandHandler = class {
16926
17024
  async handle(args) {
16927
17025
  if (args.scope === "namespace") {
@@ -17063,11 +17161,11 @@ var StoreCommandHandler = class {
17063
17161
  return payload.data ?? [];
17064
17162
  }
17065
17163
  readJsonFile(filePath) {
17066
- const absolutePath = import_node_path19.default.resolve(process.cwd(), filePath);
17067
- if (!(0, import_node_fs15.existsSync)(absolutePath)) {
17164
+ const absolutePath = import_node_path20.default.resolve(process.cwd(), filePath);
17165
+ if (!(0, import_node_fs16.existsSync)(absolutePath)) {
17068
17166
  throw new Error(`JSON file not found: ${absolutePath}`);
17069
17167
  }
17070
- const raw = (0, import_node_fs15.readFileSync)(absolutePath, "utf8");
17168
+ const raw = (0, import_node_fs16.readFileSync)(absolutePath, "utf8");
17071
17169
  try {
17072
17170
  return JSON.parse(raw);
17073
17171
  } catch (error) {
@@ -17119,14 +17217,14 @@ var StoreCommandHandler = class {
17119
17217
  };
17120
17218
 
17121
17219
  // src/commands/AppCommandHandler.ts
17122
- var import_node_fs17 = require("fs");
17123
- var import_node_path21 = __toESM(require("path"));
17220
+ var import_node_fs18 = require("fs");
17221
+ var import_node_path22 = __toESM(require("path"));
17124
17222
  init_sessionStore();
17125
17223
 
17126
17224
  // src/appIcon.ts
17127
- var import_node_fs16 = require("fs");
17225
+ var import_node_fs17 = require("fs");
17128
17226
  var import_node_os7 = __toESM(require("os"));
17129
- var import_node_path20 = __toESM(require("path"));
17227
+ var import_node_path21 = __toESM(require("path"));
17130
17228
  var import_sharp = __toESM(require("sharp"));
17131
17229
  init_namespacedRef();
17132
17230
  var ANDROID_ICON_SPECS = [
@@ -17231,13 +17329,13 @@ function createAppIconExportPlans(input) {
17231
17329
  if (!input.outDir) {
17232
17330
  throw new Error("App icon preset export requires --out-dir.");
17233
17331
  }
17234
- const outDir = import_node_path20.default.resolve(input.cwd, input.outDir);
17235
- (0, import_node_fs16.mkdirSync)(outDir, { recursive: true });
17332
+ const outDir = import_node_path21.default.resolve(input.cwd, input.outDir);
17333
+ (0, import_node_fs17.mkdirSync)(outDir, { recursive: true });
17236
17334
  return specs.map((spec) => ({
17237
17335
  width: spec.width,
17238
17336
  height: spec.height,
17239
17337
  format: "png",
17240
- outputPath: import_node_path20.default.join(
17338
+ outputPath: import_node_path21.default.join(
17241
17339
  outDir,
17242
17340
  `${namespace}-${objectId}-${spec.name}-${spec.width}x${spec.height}.png`
17243
17341
  )
@@ -17250,8 +17348,8 @@ function createAppIconExportPlans(input) {
17250
17348
  if (!input.output) {
17251
17349
  throw new Error("Single-size app icon export requires --output.");
17252
17350
  }
17253
- const resolvedOutput = import_node_path20.default.resolve(input.cwd, input.output);
17254
- (0, import_node_fs16.mkdirSync)(import_node_path20.default.dirname(resolvedOutput), { recursive: true });
17351
+ const resolvedOutput = import_node_path21.default.resolve(input.cwd, input.output);
17352
+ (0, import_node_fs17.mkdirSync)(import_node_path21.default.dirname(resolvedOutput), { recursive: true });
17255
17353
  return [
17256
17354
  {
17257
17355
  width: input.width,
@@ -17265,7 +17363,7 @@ async function exportAppIcon(icon, plans) {
17265
17363
  const svg = await resolveAppIconSvg(icon);
17266
17364
  for (const plan of plans) {
17267
17365
  const bytes = await renderAppIcon(svg, plan.width, plan.height, plan.format);
17268
- (0, import_node_fs16.writeFileSync)(plan.outputPath, bytes);
17366
+ (0, import_node_fs17.writeFileSync)(plan.outputPath, bytes);
17269
17367
  }
17270
17368
  }
17271
17369
  async function renderAppIconVariant(input) {
@@ -17273,9 +17371,9 @@ async function renderAppIconVariant(input) {
17273
17371
  const bytes = await renderAppIcon(svg, input.width, input.height, input.format);
17274
17372
  let outputPath;
17275
17373
  if (input.output) {
17276
- outputPath = import_node_path20.default.resolve(input.cwd, input.output);
17277
- (0, import_node_fs16.mkdirSync)(import_node_path20.default.dirname(outputPath), { recursive: true });
17278
- (0, import_node_fs16.writeFileSync)(outputPath, bytes);
17374
+ outputPath = import_node_path21.default.resolve(input.cwd, input.output);
17375
+ (0, import_node_fs17.mkdirSync)(import_node_path21.default.dirname(outputPath), { recursive: true });
17376
+ (0, import_node_fs17.writeFileSync)(outputPath, bytes);
17279
17377
  }
17280
17378
  if (input.name) {
17281
17379
  return {
@@ -17296,7 +17394,7 @@ async function renderAppIconVariant(input) {
17296
17394
  };
17297
17395
  }
17298
17396
  async function loadAppIconVariantFile(input) {
17299
- const absolutePath = import_node_path20.default.resolve(input.cwd, input.filePath);
17397
+ const absolutePath = import_node_path21.default.resolve(input.cwd, input.filePath);
17300
17398
  const format = inferVariantFormatFromPath(absolutePath);
17301
17399
  return {
17302
17400
  value: input.name ? await uploadAppIconVariantAsset({
@@ -17305,7 +17403,7 @@ async function loadAppIconVariantFile(input) {
17305
17403
  name: input.name,
17306
17404
  format,
17307
17405
  sourcePath: absolutePath
17308
- }) : createImageDataUrl((0, import_node_fs16.readFileSync)(absolutePath), format),
17406
+ }) : createImageDataUrl((0, import_node_fs17.readFileSync)(absolutePath), format),
17309
17407
  format,
17310
17408
  absolutePath
17311
17409
  };
@@ -17364,7 +17462,7 @@ function shouldAutoGenerateDefaultVariant(icon) {
17364
17462
  return looksLikeSvgMarkup(icon) || looksLikeSvgUrl(icon);
17365
17463
  }
17366
17464
  function inferVariantFormatFromPath(filePath) {
17367
- const ext = import_node_path20.default.extname(filePath).toLowerCase();
17465
+ const ext = import_node_path21.default.extname(filePath).toLowerCase();
17368
17466
  switch (ext) {
17369
17467
  case ".png":
17370
17468
  return "png";
@@ -17435,13 +17533,13 @@ async function uploadAppIconVariantAsset(input) {
17435
17533
  await AliyunService.uploadFile(sourcePath, DEFAULT_APP_ICON_VARIANT_BUCKET, objectKey);
17436
17534
  } finally {
17437
17535
  if (shouldCleanup) {
17438
- (0, import_node_fs16.rmSync)(import_node_path20.default.dirname(sourcePath), { recursive: true, force: true });
17536
+ (0, import_node_fs17.rmSync)(import_node_path21.default.dirname(sourcePath), { recursive: true, force: true });
17439
17537
  }
17440
17538
  }
17441
17539
  return `${DEFAULT_APP_ICON_VARIANT_PUBLIC_BASE_URL}/${objectKey}`;
17442
17540
  }
17443
17541
  function buildAppIconVariantObjectKey(input) {
17444
- return import_node_path20.default.posix.join(
17542
+ return import_node_path21.default.posix.join(
17445
17543
  "apps",
17446
17544
  `${resolveAppIconAssetStem(input.icon, input.appRef)}-${input.name}.${extensionForIconFormat(input.format)}`
17447
17545
  );
@@ -17450,8 +17548,8 @@ function resolveAppIconAssetStem(icon, appRef) {
17450
17548
  if (icon) {
17451
17549
  try {
17452
17550
  const url = new URL(icon);
17453
- const ext = import_node_path20.default.posix.extname(url.pathname);
17454
- const basename = import_node_path20.default.posix.basename(url.pathname, ext);
17551
+ const ext = import_node_path21.default.posix.extname(url.pathname);
17552
+ const basename = import_node_path21.default.posix.basename(url.pathname, ext);
17455
17553
  const normalized = sanitizeAppIconAssetStem(basename);
17456
17554
  if (normalized) {
17457
17555
  return normalized;
@@ -17480,9 +17578,9 @@ function writeTempAppIconVariantFile(objectKey, format, bytes) {
17480
17578
  if (!bytes) {
17481
17579
  throw new Error("App icon variant upload requires bytes or a source file.");
17482
17580
  }
17483
- const tempDir = (0, import_node_fs16.mkdtempSync)(import_node_path20.default.join(import_node_os7.default.tmpdir(), "pmate-app-icon-"));
17484
- const tempPath = import_node_path20.default.join(tempDir, import_node_path20.default.basename(objectKey) || `variant.${extensionForIconFormat(format)}`);
17485
- (0, import_node_fs16.writeFileSync)(tempPath, bytes);
17581
+ const tempDir = (0, import_node_fs17.mkdtempSync)(import_node_path21.default.join(import_node_os7.default.tmpdir(), "pmate-app-icon-"));
17582
+ const tempPath = import_node_path21.default.join(tempDir, import_node_path21.default.basename(objectKey) || `variant.${extensionForIconFormat(format)}`);
17583
+ (0, import_node_fs17.writeFileSync)(tempPath, bytes);
17486
17584
  return tempPath;
17487
17585
  }
17488
17586
 
@@ -17691,10 +17789,10 @@ var AppCommandHandler = class {
17691
17789
  }
17692
17790
  readJsonFile(filePath) {
17693
17791
  const absolutePath = this.resolveFilePath(filePath);
17694
- if (!(0, import_node_fs17.existsSync)(absolutePath)) {
17792
+ if (!(0, import_node_fs18.existsSync)(absolutePath)) {
17695
17793
  throw new Error(`JSON file not found: ${absolutePath}`);
17696
17794
  }
17697
- const raw = (0, import_node_fs17.readFileSync)(absolutePath, "utf8");
17795
+ const raw = (0, import_node_fs18.readFileSync)(absolutePath, "utf8");
17698
17796
  try {
17699
17797
  return JSON.parse(raw);
17700
17798
  } catch (error) {
@@ -17704,10 +17802,10 @@ var AppCommandHandler = class {
17704
17802
  }
17705
17803
  async preparePayload(filePath, appRef) {
17706
17804
  const absolutePath = this.resolveFilePath(filePath);
17707
- return prepareAppPayload(this.readJsonFile(filePath), import_node_path21.default.dirname(absolutePath), { appRef });
17805
+ return prepareAppPayload(this.readJsonFile(filePath), import_node_path22.default.dirname(absolutePath), { appRef });
17708
17806
  }
17709
17807
  resolveFilePath(filePath) {
17710
- return import_node_path21.default.resolve(process.cwd(), filePath);
17808
+ return import_node_path22.default.resolve(process.cwd(), filePath);
17711
17809
  }
17712
17810
  async request(baseUrl, token, method, pathname, body) {
17713
17811
  const response = await fetch(`${baseUrl}${pathname}`, {
@@ -17824,15 +17922,15 @@ function readNamespaceFromPayload(payload) {
17824
17922
  }
17825
17923
 
17826
17924
  // src/commands/ServiceCommandHandler.ts
17827
- var import_node_fs19 = require("fs");
17925
+ var import_node_fs20 = require("fs");
17828
17926
  var import_promises5 = require("fs/promises");
17829
- var import_node_path23 = __toESM(require("path"));
17927
+ var import_node_path24 = __toESM(require("path"));
17830
17928
  var import_promises6 = require("readline/promises");
17831
17929
 
17832
17930
  // src/services/ServiceRuntimeRunner.ts
17833
- var import_node_fs18 = require("fs");
17931
+ var import_node_fs19 = require("fs");
17834
17932
  var import_node_os8 = __toESM(require("os"));
17835
- var import_node_path22 = __toESM(require("path"));
17933
+ var import_node_path23 = __toESM(require("path"));
17836
17934
  var import_node_child_process10 = require("child_process");
17837
17935
  var import_node_readline = require("readline");
17838
17936
  var import_chalk3 = __toESM(require("chalk"));
@@ -18226,18 +18324,18 @@ var ServiceRuntimeRunner = class {
18226
18324
  }
18227
18325
  resolveRepoRoot(service, cwd) {
18228
18326
  if (cwd) {
18229
- return import_node_path22.default.resolve(process.cwd(), cwd);
18327
+ return import_node_path23.default.resolve(process.cwd(), cwd);
18230
18328
  }
18231
18329
  const repository = this.getType(service) === "vite" || this.getType(service) === "static" ? this.getSite(service).repository?.trim() : this.getType(service) === "fc" ? this.getFc(service).repository?.trim() : this.getType(service) === "ios" || this.getType(service) === "android" ? void 0 : this.getNetwork(service).repository?.trim();
18232
18330
  if (repository) {
18233
18331
  const repoName = repository.replace(/\/+$/, "").split("/").pop()?.replace(/\.git$/i, "");
18234
18332
  if (repoName) {
18235
18333
  const candidates = [
18236
- import_node_path22.default.join(import_node_os8.default.homedir(), "dev", "pmate", repoName),
18237
- import_node_path22.default.join(import_node_os8.default.homedir(), "dev", "pmate-envs", repoName)
18334
+ import_node_path23.default.join(import_node_os8.default.homedir(), "dev", "pmate", repoName),
18335
+ import_node_path23.default.join(import_node_os8.default.homedir(), "dev", "pmate-envs", repoName)
18238
18336
  ];
18239
18337
  for (const candidate of candidates) {
18240
- if ((0, import_node_fs18.existsSync)(candidate)) {
18338
+ if ((0, import_node_fs19.existsSync)(candidate)) {
18241
18339
  return candidate;
18242
18340
  }
18243
18341
  }
@@ -18251,12 +18349,12 @@ var ServiceRuntimeRunner = class {
18251
18349
  if (!dir) {
18252
18350
  throw new Error(`Missing service dir for ${service.id}`);
18253
18351
  }
18254
- return import_node_path22.default.resolve(repoRoot, dir);
18352
+ return import_node_path23.default.resolve(repoRoot, dir);
18255
18353
  }
18256
18354
  async deployVite(service, options) {
18257
18355
  const appDir = this.resolveLocalDir(service, options.cwd);
18258
- const packageJsonPath = import_node_path22.default.join(appDir, "package.json");
18259
- if (!(0, import_node_fs18.existsSync)(packageJsonPath)) {
18356
+ const packageJsonPath = import_node_path23.default.join(appDir, "package.json");
18357
+ if (!(0, import_node_fs19.existsSync)(packageJsonPath)) {
18260
18358
  throw new Error(`No package.json found at ${packageJsonPath}`);
18261
18359
  }
18262
18360
  const pkg2 = this.loadPackageJson(packageJsonPath);
@@ -18265,8 +18363,8 @@ var ServiceRuntimeRunner = class {
18265
18363
  throw new Error(`Missing package name in ${packageJsonPath}`);
18266
18364
  }
18267
18365
  await this.runCommand("pnpm", ["--filter", pkgName, "build"], this.resolveRepoRoot(service, options.cwd));
18268
- const distDir = import_node_path22.default.join(appDir, "dist");
18269
- if (!(0, import_node_fs18.existsSync)(distDir)) {
18366
+ const distDir = import_node_path23.default.join(appDir, "dist");
18367
+ if (!(0, import_node_fs19.existsSync)(distDir)) {
18270
18368
  throw new Error(`No dist directory found at ${distDir}`);
18271
18369
  }
18272
18370
  const site = this.getSite(service);
@@ -18278,8 +18376,8 @@ var ServiceRuntimeRunner = class {
18278
18376
  }
18279
18377
  async deployStatic(service, options) {
18280
18378
  const appDir = this.resolveLocalDir(service, options.cwd);
18281
- const srcDir = import_node_path22.default.join(appDir, "src");
18282
- if (!(0, import_node_fs18.existsSync)(srcDir)) {
18379
+ const srcDir = import_node_path23.default.join(appDir, "src");
18380
+ if (!(0, import_node_fs19.existsSync)(srcDir)) {
18283
18381
  throw new Error(`No src directory found at ${srcDir}`);
18284
18382
  }
18285
18383
  const site = this.getSite(service);
@@ -18294,8 +18392,8 @@ var ServiceRuntimeRunner = class {
18294
18392
  this.validateFcConfig(service, fc);
18295
18393
  const repoRoot = this.resolveRepoRoot(service);
18296
18394
  const appDir = this.resolveLocalDir(service);
18297
- const packageJsonPath = import_node_path22.default.join(appDir, "package.json");
18298
- if (!(0, import_node_fs18.existsSync)(packageJsonPath)) {
18395
+ const packageJsonPath = import_node_path23.default.join(appDir, "package.json");
18396
+ if (!(0, import_node_fs19.existsSync)(packageJsonPath)) {
18299
18397
  throw new Error(`No package.json found at ${packageJsonPath}`);
18300
18398
  }
18301
18399
  const pkg2 = this.loadPackageJson(packageJsonPath);
@@ -18348,15 +18446,15 @@ var ServiceRuntimeRunner = class {
18348
18446
  const repoRoot = this.resolveRepoRoot(service, options.cwd);
18349
18447
  const appDir = this.resolveLocalDir(service, options.cwd);
18350
18448
  await this.ensurePnpmWorkspaceRoot(repoRoot);
18351
- const configPath = import_node_path22.default.join(appDir, fc.configFile ?? "s.yaml");
18352
- if (!(0, import_node_fs18.existsSync)(configPath)) {
18449
+ const configPath = import_node_path23.default.join(appDir, fc.configFile ?? "s.yaml");
18450
+ if (!(0, import_node_fs19.existsSync)(configPath)) {
18353
18451
  throw new Error(`Missing FC config file at ${configPath}`);
18354
18452
  }
18355
- const packageJsonPath = import_node_path22.default.join(appDir, "package.json");
18356
- if (!(0, import_node_fs18.existsSync)(packageJsonPath)) {
18453
+ const packageJsonPath = import_node_path23.default.join(appDir, "package.json");
18454
+ if (!(0, import_node_fs19.existsSync)(packageJsonPath)) {
18357
18455
  throw new Error(`No package.json found at ${packageJsonPath}`);
18358
18456
  }
18359
- const rawConfig = (0, import_node_fs18.readFileSync)(configPath, "utf8");
18457
+ const rawConfig = (0, import_node_fs19.readFileSync)(configPath, "utf8");
18360
18458
  if (!rawConfig.includes(fc.functionName)) {
18361
18459
  throw new Error(`FC config ${configPath} does not mention functionName ${fc.functionName}`);
18362
18460
  }
@@ -18570,7 +18668,7 @@ var ServiceRuntimeRunner = class {
18570
18668
  const serverAddress = await resolveServerAddress(server);
18571
18669
  const templateName = exposeType === "websocket" ? "nginx.ws.template" : "nginx.rest.template";
18572
18670
  const templatePath = this.resolveTemplatePath(templateName);
18573
- const template = (0, import_node_fs18.readFileSync)(templatePath, "utf8");
18671
+ const template = (0, import_node_fs19.readFileSync)(templatePath, "utf8");
18574
18672
  const host = `${subdomain}.${("domain" in network ? network.domain?.trim() : void 0) || "pmate.chat"}`;
18575
18673
  const rendered = template.replace(/\$\{\{PORT\}\}/g, String(port)).replace(/\$\{\{HOSTS\}\}/g, host).replace(/\$\{\{HOST\}\}/g, host);
18576
18674
  const remotePath = `/etc/nginx/sites-enabled/${subdomain}.conf`;
@@ -18602,11 +18700,11 @@ var ServiceRuntimeRunner = class {
18602
18700
  }
18603
18701
  if (config.ensurePackageJson) {
18604
18702
  const appDir = this.resolveLocalDir(service, options.cwd);
18605
- const packageJsonPath = import_node_path22.default.join(appDir, "package.json");
18606
- if (!(0, import_node_fs18.existsSync)(packageJsonPath)) {
18703
+ const packageJsonPath = import_node_path23.default.join(appDir, "package.json");
18704
+ if (!(0, import_node_fs19.existsSync)(packageJsonPath)) {
18607
18705
  throw new Error(`Missing package.json at ${packageJsonPath}`);
18608
18706
  }
18609
- const pkgStat = (0, import_node_fs18.statSync)(packageJsonPath);
18707
+ const pkgStat = (0, import_node_fs19.statSync)(packageJsonPath);
18610
18708
  if (!pkgStat.isFile()) {
18611
18709
  throw new Error(`package.json is not a file at ${packageJsonPath}`);
18612
18710
  }
@@ -19030,9 +19128,9 @@ var ServiceRuntimeRunner = class {
19030
19128
  return tokens;
19031
19129
  }
19032
19130
  readPathValue(source, pathExpr) {
19033
- const path27 = pathExpr.split(".").map((segment) => segment.trim()).filter(Boolean);
19131
+ const path28 = pathExpr.split(".").map((segment) => segment.trim()).filter(Boolean);
19034
19132
  let cursor = source;
19035
- for (const segment of path27) {
19133
+ for (const segment of path28) {
19036
19134
  if (!cursor || typeof cursor !== "object" || Array.isArray(cursor)) {
19037
19135
  return void 0;
19038
19136
  }
@@ -19075,12 +19173,12 @@ var ServiceRuntimeRunner = class {
19075
19173
  }
19076
19174
  resolveTemplatePath(templateName) {
19077
19175
  const candidates = [
19078
- import_node_path22.default.join(__dirname, "..", "templates", templateName),
19079
- import_node_path22.default.join(__dirname, "..", "src", "templates", templateName),
19080
- import_node_path22.default.join(__dirname, "templates", templateName)
19176
+ import_node_path23.default.join(__dirname, "..", "templates", templateName),
19177
+ import_node_path23.default.join(__dirname, "..", "src", "templates", templateName),
19178
+ import_node_path23.default.join(__dirname, "templates", templateName)
19081
19179
  ];
19082
19180
  for (const candidate of candidates) {
19083
- if ((0, import_node_fs18.existsSync)(candidate)) {
19181
+ if ((0, import_node_fs19.existsSync)(candidate)) {
19084
19182
  return candidate;
19085
19183
  }
19086
19184
  }
@@ -19112,7 +19210,7 @@ var ServiceRuntimeRunner = class {
19112
19210
  });
19113
19211
  }
19114
19212
  loadPackageJson(packageJsonPath) {
19115
- const raw = (0, import_node_fs18.readFileSync)(packageJsonPath, "utf8");
19213
+ const raw = (0, import_node_fs19.readFileSync)(packageJsonPath, "utf8");
19116
19214
  const parsed = JSON.parse(raw);
19117
19215
  if (!parsed || typeof parsed !== "object") {
19118
19216
  throw new Error(`Invalid package.json at ${packageJsonPath}`);
@@ -19121,7 +19219,7 @@ var ServiceRuntimeRunner = class {
19121
19219
  }
19122
19220
  writePackageJson(packageJsonPath, data) {
19123
19221
  const serialized = JSON.stringify(data, null, 2);
19124
- (0, import_node_fs18.writeFileSync)(packageJsonPath, `${serialized}
19222
+ (0, import_node_fs19.writeFileSync)(packageJsonPath, `${serialized}
19125
19223
  `, "utf8");
19126
19224
  }
19127
19225
  validateFcConfig(service, fc) {
@@ -19148,8 +19246,8 @@ var ServiceRuntimeRunner = class {
19148
19246
  }
19149
19247
  }
19150
19248
  async ensurePnpmWorkspaceRoot(repoRoot) {
19151
- const workspacePath = import_node_path22.default.join(repoRoot, "pnpm-workspace.yaml");
19152
- if (!(0, import_node_fs18.existsSync)(workspacePath)) {
19249
+ const workspacePath = import_node_path23.default.join(repoRoot, "pnpm-workspace.yaml");
19250
+ if (!(0, import_node_fs19.existsSync)(workspacePath)) {
19153
19251
  throw new Error(`Missing pnpm-workspace.yaml at ${workspacePath}`);
19154
19252
  }
19155
19253
  }
@@ -19218,16 +19316,16 @@ var ServiceRuntimeRunner = class {
19218
19316
  if (!privateKeyPath) {
19219
19317
  throw new Error("Missing ssl.prv in ~/.pmate/config.yaml.");
19220
19318
  }
19221
- if (!(0, import_node_fs18.existsSync)(certificatePath)) {
19319
+ if (!(0, import_node_fs19.existsSync)(certificatePath)) {
19222
19320
  throw new Error(`SSL certificate file not found: ${certificatePath}`);
19223
19321
  }
19224
- if (!(0, import_node_fs18.existsSync)(privateKeyPath)) {
19322
+ if (!(0, import_node_fs19.existsSync)(privateKeyPath)) {
19225
19323
  throw new Error(`SSL private key file not found: ${privateKeyPath}`);
19226
19324
  }
19227
19325
  return {
19228
19326
  certName: host,
19229
- certificate: (0, import_node_fs18.readFileSync)(certificatePath, "utf8"),
19230
- privateKey: (0, import_node_fs18.readFileSync)(privateKeyPath, "utf8")
19327
+ certificate: (0, import_node_fs19.readFileSync)(certificatePath, "utf8"),
19328
+ privateKey: (0, import_node_fs19.readFileSync)(privateKeyPath, "utf8")
19231
19329
  };
19232
19330
  }
19233
19331
  resolveFcProtocol(fc, certConfig) {
@@ -19555,7 +19653,7 @@ var ServiceCommandHandler = class {
19555
19653
  format: "dotenv"
19556
19654
  }
19557
19655
  );
19558
- const outputPath = import_node_path23.default.resolve(process.cwd(), args.output);
19656
+ const outputPath = import_node_path24.default.resolve(process.cwd(), args.output);
19559
19657
  await (0, import_promises5.writeFile)(outputPath, payload.content, "utf8");
19560
19658
  ui.success(`Wrote env file for ${args.appId} to ${outputPath}`);
19561
19659
  this.renderJson({ ...payload, output: outputPath }, args.json);
@@ -19584,11 +19682,11 @@ var ServiceCommandHandler = class {
19584
19682
  return (baseUrl || process.env.PMATE_APPS_API_BASE_URL || "https://apps-api.pmate.chat").replace(/\/+$/, "");
19585
19683
  }
19586
19684
  readJsonFile(filePath) {
19587
- const absolutePath = import_node_path23.default.resolve(process.cwd(), filePath);
19588
- if (!(0, import_node_fs19.existsSync)(absolutePath)) {
19685
+ const absolutePath = import_node_path24.default.resolve(process.cwd(), filePath);
19686
+ if (!(0, import_node_fs20.existsSync)(absolutePath)) {
19589
19687
  throw new Error(`JSON file not found: ${absolutePath}`);
19590
19688
  }
19591
- const raw = (0, import_node_fs19.readFileSync)(absolutePath, "utf8");
19689
+ const raw = (0, import_node_fs20.readFileSync)(absolutePath, "utf8");
19592
19690
  try {
19593
19691
  return JSON.parse(raw);
19594
19692
  } catch (error) {
@@ -19970,9 +20068,9 @@ var RoleCommandHandler = class {
19970
20068
  };
19971
20069
 
19972
20070
  // src/commands/AccountCommandHandler.ts
19973
- var import_node_fs20 = require("fs");
20071
+ var import_node_fs21 = require("fs");
19974
20072
  var import_node_crypto4 = require("crypto");
19975
- var import_node_path24 = __toESM(require("path"));
20073
+ var import_node_path25 = __toESM(require("path"));
19976
20074
  init_sessionStore();
19977
20075
  var AccountCommandHandler = class {
19978
20076
  async handle(args) {
@@ -19980,9 +20078,9 @@ var AccountCommandHandler = class {
19980
20078
  case "bot-keygen": {
19981
20079
  const keyFile = this.generateBotKeyFile(args.app, args.name);
19982
20080
  const outPath = args.out ? this.resolveFilePath(args.out) : this.resolveDefaultBotKeyPath(args.app, args.name);
19983
- (0, import_node_fs20.mkdirSync)(import_node_path24.default.dirname(outPath), { recursive: true });
19984
- (0, import_node_fs20.writeFileSync)(outPath, JSON.stringify(keyFile, null, 2), { mode: 384 });
19985
- (0, import_node_fs20.chmodSync)(outPath, 384);
20081
+ (0, import_node_fs21.mkdirSync)(import_node_path25.default.dirname(outPath), { recursive: true });
20082
+ (0, import_node_fs21.writeFileSync)(outPath, JSON.stringify(keyFile, null, 2), { mode: 384 });
20083
+ (0, import_node_fs21.chmodSync)(outPath, 384);
19986
20084
  if (!args.json) {
19987
20085
  ui.success(`Bot key saved to ${outPath}`);
19988
20086
  }
@@ -20426,10 +20524,10 @@ var AccountCommandHandler = class {
20426
20524
  throw new Error("Missing visible apps input");
20427
20525
  }
20428
20526
  const absolutePath = this.resolveFilePath(args.filePath);
20429
- if (!(0, import_node_fs20.existsSync)(absolutePath)) {
20527
+ if (!(0, import_node_fs21.existsSync)(absolutePath)) {
20430
20528
  throw new Error(`JSON file not found: ${absolutePath}`);
20431
20529
  }
20432
- const raw = (0, import_node_fs20.readFileSync)(absolutePath, "utf8");
20530
+ const raw = (0, import_node_fs21.readFileSync)(absolutePath, "utf8");
20433
20531
  let parsed;
20434
20532
  try {
20435
20533
  parsed = JSON.parse(raw);
@@ -20443,10 +20541,10 @@ var AccountCommandHandler = class {
20443
20541
  return parsed;
20444
20542
  }
20445
20543
  resolveFilePath(filePath) {
20446
- return import_node_path24.default.resolve(process.cwd(), filePath);
20544
+ return import_node_path25.default.resolve(process.cwd(), filePath);
20447
20545
  }
20448
20546
  resolveDefaultBotKeyPath(app, name) {
20449
- return import_node_path24.default.join(this.homeDir(), ".pmate", "bots", app, `${name}.bot-key.json`);
20547
+ return import_node_path25.default.join(this.homeDir(), ".pmate", "bots", app, `${name}.bot-key.json`);
20450
20548
  }
20451
20549
  homeDir() {
20452
20550
  return process.env.HOME || process.env.USERPROFILE || process.cwd();
@@ -20469,10 +20567,10 @@ var AccountCommandHandler = class {
20469
20567
  throw new Error("Missing bot key file");
20470
20568
  }
20471
20569
  const absolutePath = this.resolveFilePath(filePath);
20472
- if (!(0, import_node_fs20.existsSync)(absolutePath)) {
20570
+ if (!(0, import_node_fs21.existsSync)(absolutePath)) {
20473
20571
  throw new Error(`Bot key file not found: ${absolutePath}`);
20474
20572
  }
20475
- const parsed = JSON.parse((0, import_node_fs20.readFileSync)(absolutePath, "utf8"));
20573
+ const parsed = JSON.parse((0, import_node_fs21.readFileSync)(absolutePath, "utf8"));
20476
20574
  if (parsed.type !== "pmate-bot-key" || parsed.version !== 1 || parsed.algorithm !== "ed25519" || !parsed.publicKey || !parsed.privateKey) {
20477
20575
  throw new Error(`Invalid PMate bot key file: ${absolutePath}`);
20478
20576
  }
@@ -20524,8 +20622,8 @@ function encodePathSegment(value) {
20524
20622
  }
20525
20623
 
20526
20624
  // src/commands/OrgCommandHandler.ts
20527
- var import_node_fs21 = require("fs");
20528
- var import_node_path25 = __toESM(require("path"));
20625
+ var import_node_fs22 = require("fs");
20626
+ var import_node_path26 = __toESM(require("path"));
20529
20627
  init_sessionStore();
20530
20628
  var OrgCommandHandler = class {
20531
20629
  async handle(args) {
@@ -20696,11 +20794,11 @@ var OrgCommandHandler = class {
20696
20794
  if (!filePath) {
20697
20795
  throw new Error(`Missing ${itemLabel} input`);
20698
20796
  }
20699
- const absolutePath = import_node_path25.default.resolve(process.cwd(), filePath);
20700
- if (!(0, import_node_fs21.existsSync)(absolutePath)) {
20797
+ const absolutePath = import_node_path26.default.resolve(process.cwd(), filePath);
20798
+ if (!(0, import_node_fs22.existsSync)(absolutePath)) {
20701
20799
  throw new Error(`JSON file not found: ${absolutePath}`);
20702
20800
  }
20703
- const raw = (0, import_node_fs21.readFileSync)(absolutePath, "utf8");
20801
+ const raw = (0, import_node_fs22.readFileSync)(absolutePath, "utf8");
20704
20802
  let parsed;
20705
20803
  try {
20706
20804
  parsed = JSON.parse(raw);
@@ -20958,15 +21056,9 @@ function parseAgentArgs(tokens) {
20958
21056
  const token = rest.shift();
20959
21057
  switch (token) {
20960
21058
  case "--payload":
20961
- if (filePath) {
20962
- throw new Error("Agent call accepts either --payload or --file, not both.");
20963
- }
20964
21059
  payload = parseJsonObject(requireValue(rest, token), token);
20965
21060
  break;
20966
21061
  case "--file":
20967
- if (payload) {
20968
- throw new Error("Agent call accepts either --payload or --file, not both.");
20969
- }
20970
21062
  filePath = requireValue(rest, token);
20971
21063
  break;
20972
21064
  case "--base-url":
@@ -23614,7 +23706,7 @@ function requireValue12(tokens, option) {
23614
23706
 
23615
23707
  // src/index.ts
23616
23708
  var pkg = JSON.parse(
23617
- (0, import_node_fs22.readFileSync)(import_node_path26.default.resolve(__dirname, "..", "package.json"), "utf8")
23709
+ (0, import_node_fs23.readFileSync)(import_node_path27.default.resolve(__dirname, "..", "package.json"), "utf8")
23618
23710
  );
23619
23711
  var HELP_TEXT = [
23620
23712
  import_chalk4.default.bold(`pmate v${pkg.version}`),
@@ -23709,6 +23801,7 @@ var HELP_TEXT = [
23709
23801
  ` ${import_chalk4.default.gray(" rename --from <id> --to <id> --ns <namespace> [--base-url <url>] [--json]")}`,
23710
23802
  ` ${import_chalk4.default.gray(" move --from <id> --ns <namespace> --to-ns <namespace> [--to <id>] [--base-url <url>] [--json]")}`,
23711
23803
  ` ${import_chalk4.default.gray(" call <ns:objectId> [--payload <json>] [--file <path>] [--base-url <url>] [--hub-base-url <url>] [--from <id>] [--json]")}`,
23804
+ ` ${import_chalk4.default.gray(" --file reads JSON payload files, or streams binary files such as .wav to ASR agents; --payload becomes stream params for binary files")}`,
23712
23805
  ` ${import_chalk4.default.gray(" delete <ns:objectId> [--base-url <url>] [--json]")}`,
23713
23806
  ` ${import_chalk4.default.gray(" list defaults to all namespaces; create defaults to namespace: pmate; default base URL: https://agent-api.pmate.chat; call uses pmate:factory session and default hub: https://hub.pmate.chat")}`,
23714
23807
  ` ${import_chalk4.default.cyan("runner")} Manage runner registry entries via agent-api`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmate/cli",
3
- "version": "0.24.14",
3
+ "version": "0.24.15",
4
4
  "description": "CLI utilities for the pMate project",
5
5
  "license": "MIT",
6
6
  "bin": {