@pmate/cli 0.24.35 → 0.24.37

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 +223 -130
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -9503,8 +9503,8 @@ __export(index_exports, {
9503
9503
  parseCommandArgs: () => parseCommandArgs
9504
9504
  });
9505
9505
  module.exports = __toCommonJS(index_exports);
9506
- var import_node_fs23 = require("fs");
9507
- var import_node_path27 = __toESM(require("path"));
9506
+ var import_node_fs24 = require("fs");
9507
+ var import_node_path28 = __toESM(require("path"));
9508
9508
  var import_chalk4 = __toESM(require("chalk"));
9509
9509
 
9510
9510
  // src/cli.ts
@@ -14957,9 +14957,9 @@ ${indent}\`\`\``;
14957
14957
  static richTextToPlain(richText) {
14958
14958
  return richText.map((item) => item.plain_text ?? item.text?.content ?? "").join("").trim();
14959
14959
  }
14960
- static async requestJson(path28, init) {
14960
+ static async requestJson(path29, init) {
14961
14961
  const token = this.getToken();
14962
- const response = await fetch(`${this.baseUrl}${path28}`, {
14962
+ const response = await fetch(`${this.baseUrl}${path29}`, {
14963
14963
  method: init.method,
14964
14964
  headers: {
14965
14965
  Authorization: `Bearer ${token}`,
@@ -16076,6 +16076,9 @@ var QuizCommandHandler = class {
16076
16076
  };
16077
16077
 
16078
16078
  // src/commands/CollectCommandHandler.ts
16079
+ var import_node_fs13 = require("fs");
16080
+ var import_node_os7 = __toESM(require("os"));
16081
+ var import_node_path18 = __toESM(require("path"));
16079
16082
  var import_playwright = require("playwright");
16080
16083
 
16081
16084
  // src/collectStore.ts
@@ -16278,6 +16281,12 @@ var CollectCommandHandler = class {
16278
16281
  collectedAt: syncedAt
16279
16282
  }));
16280
16283
  const merged = mergeMessages(existing?.messages ?? [], incoming);
16284
+ const messagesWithArchivedImages = await archiveMessageImages(
16285
+ rootDir,
16286
+ target.sourceKey,
16287
+ threadKey,
16288
+ merged.messages
16289
+ );
16281
16290
  const stored = {
16282
16291
  source: target.sourceKey,
16283
16292
  endpoint: target.endpoint,
@@ -16287,8 +16296,8 @@ var CollectCommandHandler = class {
16287
16296
  unread: thread.unread,
16288
16297
  lastMessageAt: thread.time,
16289
16298
  lastSyncedAt: syncedAt,
16290
- messageCount: merged.messages.length,
16291
- messages: merged.messages
16299
+ messageCount: messagesWithArchivedImages.length,
16300
+ messages: messagesWithArchivedImages
16292
16301
  };
16293
16302
  await writeStoredThread(rootDir, stored);
16294
16303
  return {
@@ -16439,6 +16448,50 @@ var CollectCommandHandler = class {
16439
16448
  }
16440
16449
  }
16441
16450
  };
16451
+ async function archiveMessageImages(rootDir, sourceKey, threadKey, messages2) {
16452
+ const attachmentRoot = resolveLocalAttachmentRoot(sourceKey);
16453
+ if (!attachmentRoot) {
16454
+ return messages2;
16455
+ }
16456
+ return Promise.all(
16457
+ messages2.map(async (message) => ({
16458
+ ...message,
16459
+ images: await Promise.all(
16460
+ message.images.map(
16461
+ (imagePath) => archiveMessageImage(rootDir, attachmentRoot, threadKey, imagePath)
16462
+ )
16463
+ )
16464
+ }))
16465
+ );
16466
+ }
16467
+ async function archiveMessageImage(rootDir, attachmentRoot, threadKey, imagePath) {
16468
+ if (!imagePath || isExternalImageRef(imagePath) || imagePath.startsWith("attachments/")) {
16469
+ return imagePath;
16470
+ }
16471
+ const normalized = import_node_path18.default.posix.normalize(imagePath.replace(/\\/g, "/"));
16472
+ if (normalized.startsWith("../") || import_node_path18.default.posix.isAbsolute(normalized)) {
16473
+ return imagePath;
16474
+ }
16475
+ const sourcePath = import_node_path18.default.join(attachmentRoot, ...normalized.split("/"));
16476
+ const destinationRelativePath = import_node_path18.default.posix.join("attachments", threadKey, normalized);
16477
+ const destinationPath = import_node_path18.default.join(rootDir, ...destinationRelativePath.split("/"));
16478
+ try {
16479
+ await import_node_fs13.promises.mkdir(import_node_path18.default.dirname(destinationPath), { recursive: true });
16480
+ await import_node_fs13.promises.copyFile(sourcePath, destinationPath);
16481
+ return destinationRelativePath;
16482
+ } catch {
16483
+ return imagePath;
16484
+ }
16485
+ }
16486
+ function resolveLocalAttachmentRoot(sourceKey) {
16487
+ if (sourceKey !== "cc" && sourceKey !== "yelling") {
16488
+ return null;
16489
+ }
16490
+ return import_node_path18.default.join(import_node_os7.default.homedir(), "Library", "Application Support", sourceKey, "attachments.noindex");
16491
+ }
16492
+ function isExternalImageRef(imagePath) {
16493
+ return /^[a-z][a-z0-9+.-]*:/i.test(imagePath);
16494
+ }
16442
16495
  function normalizeText(value) {
16443
16496
  return value.replace(/\s+/g, " ").replace(/\u200B/g, "").trim();
16444
16497
  }
@@ -16663,7 +16716,7 @@ function pad2(value) {
16663
16716
  }
16664
16717
 
16665
16718
  // src/commands/ChatRoomCommandHandler.ts
16666
- var import_node_fs13 = require("fs");
16719
+ var import_node_fs14 = require("fs");
16667
16720
  var ChatRoomCommandHandler = class {
16668
16721
  async handle(args) {
16669
16722
  const sdk = await loadChatSdk();
@@ -16713,8 +16766,8 @@ var ChatRoomCommandHandler = class {
16713
16766
  const a = await this.connect(sdk, args.botA, args.app, args.hubUrl, args.authBaseUrl);
16714
16767
  const b = await this.connect(sdk, args.botB, args.app, args.hubUrl, args.authBaseUrl);
16715
16768
  try {
16716
- const botA = sdk.parsePmateBotKeyJson((0, import_node_fs13.readFileSync)(args.botA, "utf8"));
16717
- const botB = sdk.parsePmateBotKeyJson((0, import_node_fs13.readFileSync)(args.botB, "utf8"));
16769
+ const botA = sdk.parsePmateBotKeyJson((0, import_node_fs14.readFileSync)(args.botA, "utf8"));
16770
+ const botB = sdk.parsePmateBotKeyJson((0, import_node_fs14.readFileSync)(args.botB, "utf8"));
16718
16771
  await a.requestFriend({ to: botB.name, message: "smoke friend request" });
16719
16772
  await b.acceptFriend({ to: botA.name, message: "smoke friend accept" });
16720
16773
  await a.sendDm({ to: botB.name, text: "smoke dm from a" });
@@ -16733,7 +16786,7 @@ var ChatRoomCommandHandler = class {
16733
16786
  if (!botPath) {
16734
16787
  throw new Error("Missing required option: --bot");
16735
16788
  }
16736
- const botKey = sdk.parsePmateBotKeyJson((0, import_node_fs13.readFileSync)(botPath, "utf8"));
16789
+ const botKey = sdk.parsePmateBotKeyJson((0, import_node_fs14.readFileSync)(botPath, "utf8"));
16737
16790
  const client = sdk.createChatClient({ appId, botKey, hubUrl, authBaseUrl });
16738
16791
  await client.connect();
16739
16792
  return client;
@@ -16745,8 +16798,8 @@ async function loadChatSdk() {
16745
16798
  }
16746
16799
 
16747
16800
  // src/commands/AgentCommandHandler.ts
16748
- var import_node_fs14 = require("fs");
16749
- var import_node_path18 = __toESM(require("path"));
16801
+ var import_node_fs15 = require("fs");
16802
+ var import_node_path19 = __toESM(require("path"));
16750
16803
  init_AgentLlmClient();
16751
16804
  init_sessionStore();
16752
16805
 
@@ -16779,8 +16832,8 @@ function descriptorPathSegments(descriptor) {
16779
16832
  return ["chains", normalized.chain, "namespaces", normalized.ns, normalized.kind, normalized.name];
16780
16833
  }
16781
16834
  function buildPathUrl(baseUrl, pathSegments, query) {
16782
- const path28 = `/${pathSegments.map((segment) => encodeURIComponent(segment)).join("/")}`;
16783
- const url = new URL(path28, baseUrl);
16835
+ const path29 = `/${pathSegments.map((segment) => encodeURIComponent(segment)).join("/")}`;
16836
+ const url = new URL(path29, baseUrl);
16784
16837
  if (query) {
16785
16838
  for (const [key, value] of Object.entries(query)) {
16786
16839
  url.searchParams.set(key, String(value));
@@ -17237,11 +17290,11 @@ var AgentCommandHandler = class {
17237
17290
  }).token;
17238
17291
  }
17239
17292
  readJsonFile(filePath) {
17240
- const absolutePath = import_node_path18.default.resolve(process.cwd(), filePath);
17241
- if (!(0, import_node_fs14.existsSync)(absolutePath)) {
17293
+ const absolutePath = import_node_path19.default.resolve(process.cwd(), filePath);
17294
+ if (!(0, import_node_fs15.existsSync)(absolutePath)) {
17242
17295
  throw new Error(`JSON file not found: ${absolutePath}`);
17243
17296
  }
17244
- const raw = (0, import_node_fs14.readFileSync)(absolutePath, "utf8");
17297
+ const raw = (0, import_node_fs15.readFileSync)(absolutePath, "utf8");
17245
17298
  try {
17246
17299
  return JSON.parse(raw);
17247
17300
  } catch (error) {
@@ -17252,14 +17305,14 @@ var AgentCommandHandler = class {
17252
17305
  readJsonObjectFile(filePath) {
17253
17306
  const parsed = this.readJsonFile(filePath);
17254
17307
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
17255
- const absolutePath = import_node_path18.default.resolve(process.cwd(), filePath);
17308
+ const absolutePath = import_node_path19.default.resolve(process.cwd(), filePath);
17256
17309
  throw new Error(`Invalid JSON in ${absolutePath}: expected an object`);
17257
17310
  }
17258
17311
  return parsed;
17259
17312
  }
17260
17313
  tryReadJsonObjectFile(filePath) {
17261
17314
  const absolutePath = this.resolveExistingFile(filePath);
17262
- const raw = (0, import_node_fs14.readFileSync)(absolutePath, "utf8");
17315
+ const raw = (0, import_node_fs15.readFileSync)(absolutePath, "utf8");
17263
17316
  try {
17264
17317
  const parsed = JSON.parse(raw);
17265
17318
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
@@ -17271,8 +17324,8 @@ var AgentCommandHandler = class {
17271
17324
  }
17272
17325
  }
17273
17326
  resolveExistingFile(filePath) {
17274
- const absolutePath = import_node_path18.default.resolve(process.cwd(), filePath);
17275
- if (!(0, import_node_fs14.existsSync)(absolutePath)) {
17327
+ const absolutePath = import_node_path19.default.resolve(process.cwd(), filePath);
17328
+ if (!(0, import_node_fs15.existsSync)(absolutePath)) {
17276
17329
  throw new Error(`File not found: ${absolutePath}`);
17277
17330
  }
17278
17331
  return absolutePath;
@@ -17356,8 +17409,8 @@ var AgentCommandHandler = class {
17356
17409
  };
17357
17410
 
17358
17411
  // src/commands/RunnerCommandHandler.ts
17359
- var import_node_fs15 = require("fs");
17360
- var import_node_path19 = __toESM(require("path"));
17412
+ var import_node_fs16 = require("fs");
17413
+ var import_node_path20 = __toESM(require("path"));
17361
17414
  init_sessionStore();
17362
17415
  init_namespacedRef();
17363
17416
  var RunnerCommandHandler = class {
@@ -17452,11 +17505,11 @@ var RunnerCommandHandler = class {
17452
17505
  }).token;
17453
17506
  }
17454
17507
  readJsonFile(filePath) {
17455
- const absolutePath = import_node_path19.default.resolve(process.cwd(), filePath);
17456
- if (!(0, import_node_fs15.existsSync)(absolutePath)) {
17508
+ const absolutePath = import_node_path20.default.resolve(process.cwd(), filePath);
17509
+ if (!(0, import_node_fs16.existsSync)(absolutePath)) {
17457
17510
  throw new Error(`JSON file not found: ${absolutePath}`);
17458
17511
  }
17459
- const raw = (0, import_node_fs15.readFileSync)(absolutePath, "utf8");
17512
+ const raw = (0, import_node_fs16.readFileSync)(absolutePath, "utf8");
17460
17513
  try {
17461
17514
  return JSON.parse(raw);
17462
17515
  } catch (error) {
@@ -17575,8 +17628,8 @@ var NsCommandHandler = class {
17575
17628
  };
17576
17629
 
17577
17630
  // src/commands/StoreCommandHandler.ts
17578
- var import_node_fs16 = require("fs");
17579
- var import_node_path20 = __toESM(require("path"));
17631
+ var import_node_fs17 = require("fs");
17632
+ var import_node_path21 = __toESM(require("path"));
17580
17633
  var StoreCommandHandler = class {
17581
17634
  async handle(args) {
17582
17635
  if (args.scope === "namespace") {
@@ -17718,11 +17771,11 @@ var StoreCommandHandler = class {
17718
17771
  return payload.data ?? [];
17719
17772
  }
17720
17773
  readJsonFile(filePath) {
17721
- const absolutePath = import_node_path20.default.resolve(process.cwd(), filePath);
17722
- if (!(0, import_node_fs16.existsSync)(absolutePath)) {
17774
+ const absolutePath = import_node_path21.default.resolve(process.cwd(), filePath);
17775
+ if (!(0, import_node_fs17.existsSync)(absolutePath)) {
17723
17776
  throw new Error(`JSON file not found: ${absolutePath}`);
17724
17777
  }
17725
- const raw = (0, import_node_fs16.readFileSync)(absolutePath, "utf8");
17778
+ const raw = (0, import_node_fs17.readFileSync)(absolutePath, "utf8");
17726
17779
  try {
17727
17780
  return JSON.parse(raw);
17728
17781
  } catch (error) {
@@ -17774,14 +17827,14 @@ var StoreCommandHandler = class {
17774
17827
  };
17775
17828
 
17776
17829
  // src/commands/AppCommandHandler.ts
17777
- var import_node_fs18 = require("fs");
17778
- var import_node_path22 = __toESM(require("path"));
17830
+ var import_node_fs19 = require("fs");
17831
+ var import_node_path23 = __toESM(require("path"));
17779
17832
  init_sessionStore();
17780
17833
 
17781
17834
  // src/appIcon.ts
17782
- var import_node_fs17 = require("fs");
17783
- var import_node_os7 = __toESM(require("os"));
17784
- var import_node_path21 = __toESM(require("path"));
17835
+ var import_node_fs18 = require("fs");
17836
+ var import_node_os8 = __toESM(require("os"));
17837
+ var import_node_path22 = __toESM(require("path"));
17785
17838
  var import_sharp = __toESM(require("sharp"));
17786
17839
  init_namespacedRef();
17787
17840
  var ANDROID_ICON_SPECS = [
@@ -17886,13 +17939,13 @@ function createAppIconExportPlans(input) {
17886
17939
  if (!input.outDir) {
17887
17940
  throw new Error("App icon preset export requires --out-dir.");
17888
17941
  }
17889
- const outDir = import_node_path21.default.resolve(input.cwd, input.outDir);
17890
- (0, import_node_fs17.mkdirSync)(outDir, { recursive: true });
17942
+ const outDir = import_node_path22.default.resolve(input.cwd, input.outDir);
17943
+ (0, import_node_fs18.mkdirSync)(outDir, { recursive: true });
17891
17944
  return specs.map((spec) => ({
17892
17945
  width: spec.width,
17893
17946
  height: spec.height,
17894
17947
  format: "png",
17895
- outputPath: import_node_path21.default.join(
17948
+ outputPath: import_node_path22.default.join(
17896
17949
  outDir,
17897
17950
  `${namespace}-${objectId}-${spec.name}-${spec.width}x${spec.height}.png`
17898
17951
  )
@@ -17905,8 +17958,8 @@ function createAppIconExportPlans(input) {
17905
17958
  if (!input.output) {
17906
17959
  throw new Error("Single-size app icon export requires --output.");
17907
17960
  }
17908
- const resolvedOutput = import_node_path21.default.resolve(input.cwd, input.output);
17909
- (0, import_node_fs17.mkdirSync)(import_node_path21.default.dirname(resolvedOutput), { recursive: true });
17961
+ const resolvedOutput = import_node_path22.default.resolve(input.cwd, input.output);
17962
+ (0, import_node_fs18.mkdirSync)(import_node_path22.default.dirname(resolvedOutput), { recursive: true });
17910
17963
  return [
17911
17964
  {
17912
17965
  width: input.width,
@@ -17920,7 +17973,7 @@ async function exportAppIcon(icon, plans) {
17920
17973
  const svg = await resolveAppIconSvg(icon);
17921
17974
  for (const plan of plans) {
17922
17975
  const bytes = await renderAppIcon(svg, plan.width, plan.height, plan.format);
17923
- (0, import_node_fs17.writeFileSync)(plan.outputPath, bytes);
17976
+ (0, import_node_fs18.writeFileSync)(plan.outputPath, bytes);
17924
17977
  }
17925
17978
  }
17926
17979
  async function renderAppIconVariant(input) {
@@ -17928,9 +17981,9 @@ async function renderAppIconVariant(input) {
17928
17981
  const bytes = await renderAppIcon(svg, input.width, input.height, input.format);
17929
17982
  let outputPath;
17930
17983
  if (input.output) {
17931
- outputPath = import_node_path21.default.resolve(input.cwd, input.output);
17932
- (0, import_node_fs17.mkdirSync)(import_node_path21.default.dirname(outputPath), { recursive: true });
17933
- (0, import_node_fs17.writeFileSync)(outputPath, bytes);
17984
+ outputPath = import_node_path22.default.resolve(input.cwd, input.output);
17985
+ (0, import_node_fs18.mkdirSync)(import_node_path22.default.dirname(outputPath), { recursive: true });
17986
+ (0, import_node_fs18.writeFileSync)(outputPath, bytes);
17934
17987
  }
17935
17988
  if (input.name) {
17936
17989
  return {
@@ -17951,7 +18004,7 @@ async function renderAppIconVariant(input) {
17951
18004
  };
17952
18005
  }
17953
18006
  async function loadAppIconVariantFile(input) {
17954
- const absolutePath = import_node_path21.default.resolve(input.cwd, input.filePath);
18007
+ const absolutePath = import_node_path22.default.resolve(input.cwd, input.filePath);
17955
18008
  const format = inferVariantFormatFromPath(absolutePath);
17956
18009
  return {
17957
18010
  value: input.name ? await uploadAppIconVariantAsset({
@@ -17960,7 +18013,7 @@ async function loadAppIconVariantFile(input) {
17960
18013
  name: input.name,
17961
18014
  format,
17962
18015
  sourcePath: absolutePath
17963
- }) : createImageDataUrl((0, import_node_fs17.readFileSync)(absolutePath), format),
18016
+ }) : createImageDataUrl((0, import_node_fs18.readFileSync)(absolutePath), format),
17964
18017
  format,
17965
18018
  absolutePath
17966
18019
  };
@@ -18019,7 +18072,7 @@ function shouldAutoGenerateDefaultVariant(icon) {
18019
18072
  return looksLikeSvgMarkup(icon) || looksLikeSvgUrl(icon);
18020
18073
  }
18021
18074
  function inferVariantFormatFromPath(filePath) {
18022
- const ext = import_node_path21.default.extname(filePath).toLowerCase();
18075
+ const ext = import_node_path22.default.extname(filePath).toLowerCase();
18023
18076
  switch (ext) {
18024
18077
  case ".png":
18025
18078
  return "png";
@@ -18090,13 +18143,13 @@ async function uploadAppIconVariantAsset(input) {
18090
18143
  await AliyunService.uploadFile(sourcePath, DEFAULT_APP_ICON_VARIANT_BUCKET, objectKey);
18091
18144
  } finally {
18092
18145
  if (shouldCleanup) {
18093
- (0, import_node_fs17.rmSync)(import_node_path21.default.dirname(sourcePath), { recursive: true, force: true });
18146
+ (0, import_node_fs18.rmSync)(import_node_path22.default.dirname(sourcePath), { recursive: true, force: true });
18094
18147
  }
18095
18148
  }
18096
18149
  return `${DEFAULT_APP_ICON_VARIANT_PUBLIC_BASE_URL}/${objectKey}`;
18097
18150
  }
18098
18151
  function buildAppIconVariantObjectKey(input) {
18099
- return import_node_path21.default.posix.join(
18152
+ return import_node_path22.default.posix.join(
18100
18153
  "apps",
18101
18154
  `${resolveAppIconAssetStem(input.icon, input.appRef)}-${input.name}.${extensionForIconFormat(input.format)}`
18102
18155
  );
@@ -18105,8 +18158,8 @@ function resolveAppIconAssetStem(icon, appRef) {
18105
18158
  if (icon) {
18106
18159
  try {
18107
18160
  const url = new URL(icon);
18108
- const ext = import_node_path21.default.posix.extname(url.pathname);
18109
- const basename = import_node_path21.default.posix.basename(url.pathname, ext);
18161
+ const ext = import_node_path22.default.posix.extname(url.pathname);
18162
+ const basename = import_node_path22.default.posix.basename(url.pathname, ext);
18110
18163
  const normalized = sanitizeAppIconAssetStem(basename);
18111
18164
  if (normalized) {
18112
18165
  return normalized;
@@ -18135,9 +18188,9 @@ function writeTempAppIconVariantFile(objectKey, format, bytes) {
18135
18188
  if (!bytes) {
18136
18189
  throw new Error("App icon variant upload requires bytes or a source file.");
18137
18190
  }
18138
- const tempDir = (0, import_node_fs17.mkdtempSync)(import_node_path21.default.join(import_node_os7.default.tmpdir(), "pmate-app-icon-"));
18139
- const tempPath = import_node_path21.default.join(tempDir, import_node_path21.default.basename(objectKey) || `variant.${extensionForIconFormat(format)}`);
18140
- (0, import_node_fs17.writeFileSync)(tempPath, bytes);
18191
+ const tempDir = (0, import_node_fs18.mkdtempSync)(import_node_path22.default.join(import_node_os8.default.tmpdir(), "pmate-app-icon-"));
18192
+ const tempPath = import_node_path22.default.join(tempDir, import_node_path22.default.basename(objectKey) || `variant.${extensionForIconFormat(format)}`);
18193
+ (0, import_node_fs18.writeFileSync)(tempPath, bytes);
18141
18194
  return tempPath;
18142
18195
  }
18143
18196
 
@@ -18346,10 +18399,10 @@ var AppCommandHandler = class {
18346
18399
  }
18347
18400
  readJsonFile(filePath) {
18348
18401
  const absolutePath = this.resolveFilePath(filePath);
18349
- if (!(0, import_node_fs18.existsSync)(absolutePath)) {
18402
+ if (!(0, import_node_fs19.existsSync)(absolutePath)) {
18350
18403
  throw new Error(`JSON file not found: ${absolutePath}`);
18351
18404
  }
18352
- const raw = (0, import_node_fs18.readFileSync)(absolutePath, "utf8");
18405
+ const raw = (0, import_node_fs19.readFileSync)(absolutePath, "utf8");
18353
18406
  try {
18354
18407
  return JSON.parse(raw);
18355
18408
  } catch (error) {
@@ -18359,10 +18412,10 @@ var AppCommandHandler = class {
18359
18412
  }
18360
18413
  async preparePayload(filePath, appRef) {
18361
18414
  const absolutePath = this.resolveFilePath(filePath);
18362
- return prepareAppPayload(this.readJsonFile(filePath), import_node_path22.default.dirname(absolutePath), { appRef });
18415
+ return prepareAppPayload(this.readJsonFile(filePath), import_node_path23.default.dirname(absolutePath), { appRef });
18363
18416
  }
18364
18417
  resolveFilePath(filePath) {
18365
- return import_node_path22.default.resolve(process.cwd(), filePath);
18418
+ return import_node_path23.default.resolve(process.cwd(), filePath);
18366
18419
  }
18367
18420
  async request(baseUrl, token, method, pathname, body) {
18368
18421
  const response = await fetch(`${baseUrl}${pathname}`, {
@@ -18482,19 +18535,20 @@ function readNamespaceFromPayload(payload) {
18482
18535
  }
18483
18536
 
18484
18537
  // src/commands/ServiceCommandHandler.ts
18485
- var import_node_fs20 = require("fs");
18538
+ var import_node_fs21 = require("fs");
18486
18539
  var import_promises6 = require("fs/promises");
18487
- var import_node_path24 = __toESM(require("path"));
18540
+ var import_node_path25 = __toESM(require("path"));
18488
18541
  var import_node_child_process11 = require("child_process");
18489
18542
  var import_promises7 = require("readline/promises");
18490
18543
 
18491
18544
  // src/services/ServiceRuntimeRunner.ts
18492
- var import_node_fs19 = require("fs");
18493
- var import_node_os8 = __toESM(require("os"));
18494
- var import_node_path23 = __toESM(require("path"));
18545
+ var import_node_fs20 = require("fs");
18546
+ var import_node_os9 = __toESM(require("os"));
18547
+ var import_node_path24 = __toESM(require("path"));
18495
18548
  var import_node_child_process10 = require("child_process");
18496
18549
  var import_node_readline = require("readline");
18497
18550
  var import_chalk3 = __toESM(require("chalk"));
18551
+ var import_dotenv = require("dotenv");
18498
18552
 
18499
18553
  // src/services/ServiceRegistryClient.ts
18500
18554
  init_sessionStore();
@@ -18577,7 +18631,10 @@ var ServiceRegistryClient = class {
18577
18631
  {
18578
18632
  stage: options.stage,
18579
18633
  ...options.branch ? { branch: options.branch } : {},
18580
- ...options.includeSecretValue ? { includeSecretValue: true } : {}
18634
+ ...options.includeSecretValue ? { includeSecretValue: true } : {},
18635
+ ...options.includeHost === false ? { includeHost: false } : {},
18636
+ ...options.hostId ? { hostId: options.hostId } : {},
18637
+ ...options.hostTarget ? { hostTarget: options.hostTarget } : {}
18581
18638
  }
18582
18639
  );
18583
18640
  }
@@ -18617,6 +18674,9 @@ var ServiceRegistryClient = class {
18617
18674
  body: JSON.stringify({
18618
18675
  stage: options.stage,
18619
18676
  ...options.branch ? { branch: options.branch } : {},
18677
+ ...options.includeHost === false ? { includeHost: false } : {},
18678
+ ...options.hostId ? { hostId: options.hostId } : {},
18679
+ ...options.hostTarget ? { hostTarget: options.hostTarget } : {},
18620
18680
  format: options.format
18621
18681
  })
18622
18682
  });
@@ -18931,18 +18991,18 @@ var ServiceRuntimeRunner = class {
18931
18991
  }
18932
18992
  resolveRepoRoot(service, cwd) {
18933
18993
  if (cwd) {
18934
- return import_node_path23.default.resolve(process.cwd(), cwd);
18994
+ return import_node_path24.default.resolve(process.cwd(), cwd);
18935
18995
  }
18936
18996
  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();
18937
18997
  if (repository) {
18938
18998
  const repoName = repository.replace(/\/+$/, "").split("/").pop()?.replace(/\.git$/i, "");
18939
18999
  if (repoName) {
18940
19000
  const candidates = [
18941
- import_node_path23.default.join(import_node_os8.default.homedir(), "dev", "pmate", repoName),
18942
- import_node_path23.default.join(import_node_os8.default.homedir(), "dev", "pmate-envs", repoName)
19001
+ import_node_path24.default.join(import_node_os9.default.homedir(), "dev", "pmate", repoName),
19002
+ import_node_path24.default.join(import_node_os9.default.homedir(), "dev", "pmate-envs", repoName)
18943
19003
  ];
18944
19004
  for (const candidate of candidates) {
18945
- if ((0, import_node_fs19.existsSync)(candidate)) {
19005
+ if ((0, import_node_fs20.existsSync)(candidate)) {
18946
19006
  return candidate;
18947
19007
  }
18948
19008
  }
@@ -18956,12 +19016,12 @@ var ServiceRuntimeRunner = class {
18956
19016
  if (!dir) {
18957
19017
  throw new Error(`Missing service dir for ${service.id}`);
18958
19018
  }
18959
- return import_node_path23.default.resolve(repoRoot, dir);
19019
+ return import_node_path24.default.resolve(repoRoot, dir);
18960
19020
  }
18961
19021
  async deployVite(service, options) {
18962
19022
  const appDir = this.resolveLocalDir(service, options.cwd);
18963
- const packageJsonPath = import_node_path23.default.join(appDir, "package.json");
18964
- if (!(0, import_node_fs19.existsSync)(packageJsonPath)) {
19023
+ const packageJsonPath = import_node_path24.default.join(appDir, "package.json");
19024
+ if (!(0, import_node_fs20.existsSync)(packageJsonPath)) {
18965
19025
  throw new Error(`No package.json found at ${packageJsonPath}`);
18966
19026
  }
18967
19027
  const pkg2 = this.loadPackageJson(packageJsonPath);
@@ -18969,9 +19029,15 @@ var ServiceRuntimeRunner = class {
18969
19029
  if (!pkgName) {
18970
19030
  throw new Error(`Missing package name in ${packageJsonPath}`);
18971
19031
  }
18972
- await this.runCommand("pnpm", ["--filter", pkgName, "build"], this.resolveRepoRoot(service, options.cwd));
18973
- const distDir = import_node_path23.default.join(appDir, "dist");
18974
- if (!(0, import_node_fs19.existsSync)(distDir)) {
19032
+ const buildEnv = await this.buildLocalBuildEnv(service.id, options.envName ?? "prod");
19033
+ await this.runCommandWithEnv(
19034
+ "pnpm",
19035
+ ["--filter", pkgName, "build"],
19036
+ this.resolveRepoRoot(service, options.cwd),
19037
+ buildEnv
19038
+ );
19039
+ const distDir = import_node_path24.default.join(appDir, "dist");
19040
+ if (!(0, import_node_fs20.existsSync)(distDir)) {
18975
19041
  throw new Error(`No dist directory found at ${distDir}`);
18976
19042
  }
18977
19043
  const site = this.getSite(service);
@@ -18983,8 +19049,8 @@ var ServiceRuntimeRunner = class {
18983
19049
  }
18984
19050
  async deployStatic(service, options) {
18985
19051
  const appDir = this.resolveLocalDir(service, options.cwd);
18986
- const srcDir = import_node_path23.default.join(appDir, "src");
18987
- if (!(0, import_node_fs19.existsSync)(srcDir)) {
19052
+ const srcDir = import_node_path24.default.join(appDir, "src");
19053
+ if (!(0, import_node_fs20.existsSync)(srcDir)) {
18988
19054
  throw new Error(`No src directory found at ${srcDir}`);
18989
19055
  }
18990
19056
  const site = this.getSite(service);
@@ -18994,13 +19060,32 @@ var ServiceRuntimeRunner = class {
18994
19060
  }
18995
19061
  await AliyunService.uploadDirectory(srcDir, bucketName);
18996
19062
  }
19063
+ async buildLocalBuildEnv(serviceId, envName = "prod") {
19064
+ if (!this.envProvider) {
19065
+ return void 0;
19066
+ }
19067
+ let pulled;
19068
+ try {
19069
+ pulled = await this.envProvider(serviceId, {
19070
+ stage: this.envNameToStage(envName),
19071
+ format: "dotenv"
19072
+ });
19073
+ } catch (error) {
19074
+ if (error instanceof ServiceEnvNotFoundError) {
19075
+ ui.warn(`No env found for ${serviceId}; building without service env.`);
19076
+ return void 0;
19077
+ }
19078
+ throw error;
19079
+ }
19080
+ return pulled?.content ? (0, import_dotenv.parse)(pulled.content) : void 0;
19081
+ }
18997
19082
  async deployFc(service, options = {}) {
18998
19083
  const fc = this.getFc(service);
18999
19084
  this.validateFcConfig(service, fc);
19000
19085
  const repoRoot = this.resolveRepoRoot(service);
19001
19086
  const appDir = this.resolveLocalDir(service);
19002
- const packageJsonPath = import_node_path23.default.join(appDir, "package.json");
19003
- if (!(0, import_node_fs19.existsSync)(packageJsonPath)) {
19087
+ const packageJsonPath = import_node_path24.default.join(appDir, "package.json");
19088
+ if (!(0, import_node_fs20.existsSync)(packageJsonPath)) {
19004
19089
  throw new Error(`No package.json found at ${packageJsonPath}`);
19005
19090
  }
19006
19091
  const pkg2 = this.loadPackageJson(packageJsonPath);
@@ -19053,15 +19138,15 @@ var ServiceRuntimeRunner = class {
19053
19138
  const repoRoot = this.resolveRepoRoot(service, options.cwd);
19054
19139
  const appDir = this.resolveLocalDir(service, options.cwd);
19055
19140
  await this.ensurePnpmWorkspaceRoot(repoRoot);
19056
- const configPath = import_node_path23.default.join(appDir, fc.configFile ?? "s.yaml");
19057
- if (!(0, import_node_fs19.existsSync)(configPath)) {
19141
+ const configPath = import_node_path24.default.join(appDir, fc.configFile ?? "s.yaml");
19142
+ if (!(0, import_node_fs20.existsSync)(configPath)) {
19058
19143
  throw new Error(`Missing FC config file at ${configPath}`);
19059
19144
  }
19060
- const packageJsonPath = import_node_path23.default.join(appDir, "package.json");
19061
- if (!(0, import_node_fs19.existsSync)(packageJsonPath)) {
19145
+ const packageJsonPath = import_node_path24.default.join(appDir, "package.json");
19146
+ if (!(0, import_node_fs20.existsSync)(packageJsonPath)) {
19062
19147
  throw new Error(`No package.json found at ${packageJsonPath}`);
19063
19148
  }
19064
- const rawConfig = (0, import_node_fs19.readFileSync)(configPath, "utf8");
19149
+ const rawConfig = (0, import_node_fs20.readFileSync)(configPath, "utf8");
19065
19150
  if (!rawConfig.includes(fc.functionName)) {
19066
19151
  throw new Error(`FC config ${configPath} does not mention functionName ${fc.functionName}`);
19067
19152
  }
@@ -19137,7 +19222,7 @@ var ServiceRuntimeRunner = class {
19137
19222
  `pkg="${appDir}/package.json"`,
19138
19223
  `if [ -f "$pkg" ] && node -e 'const fs=require("node:fs"); const p=JSON.parse(fs.readFileSync(process.argv[1],"utf8")); process.exit(p?.scripts?.build ? 0 : 1);' "$pkg"; then (cd "${appDir}" && pnpm run build); fi`
19139
19224
  ].join("; ");
19140
- const envSyncCommand = await this.buildNodeEnvSyncCommand(service.id, appDir, options.envName);
19225
+ const envSyncCommand = await this.buildNodeEnvSyncCommand(service.id, appDir, options.envName, server);
19141
19226
  const command = [
19142
19227
  `cd "$HOME"`,
19143
19228
  `[ -d "${repoDir}/.git" ] || git clone "${gitUrl}" "${repoDir}"`,
@@ -19155,13 +19240,17 @@ var ServiceRuntimeRunner = class {
19155
19240
  ].join(" && ");
19156
19241
  await this.runRemoteCommand(server, command);
19157
19242
  }
19158
- async buildNodeEnvSyncCommand(serviceId, appDir, envName = "prod") {
19243
+ async buildNodeEnvSyncCommand(serviceId, appDir, envName = "prod", hostTarget) {
19159
19244
  if (!this.envProvider) {
19160
19245
  return void 0;
19161
19246
  }
19162
19247
  let pulled;
19163
19248
  try {
19164
- pulled = await this.envProvider(serviceId, { stage: this.envNameToStage(envName), format: "dotenv" });
19249
+ pulled = await this.envProvider(serviceId, {
19250
+ stage: this.envNameToStage(envName),
19251
+ format: "dotenv",
19252
+ ...hostTarget ? { hostTarget } : {}
19253
+ });
19165
19254
  } catch (error) {
19166
19255
  if (error instanceof ServiceEnvNotFoundError) {
19167
19256
  ui.warn(`No env found for ${serviceId}; skipping .env.local sync.`);
@@ -19202,7 +19291,7 @@ var ServiceRuntimeRunner = class {
19202
19291
  const gitUrl = this.withToken(repoUrl);
19203
19292
  const scriptPath = script.startsWith("/") || script.startsWith("./") ? script : `./${script}`;
19204
19293
  const envName = options.envName ?? "prod";
19205
- const envSyncCommand = await this.buildScriptEnvSyncCommand(service.id, envName);
19294
+ const envSyncCommand = await this.buildScriptEnvSyncCommand(service.id, envName, server);
19206
19295
  const command = [
19207
19296
  `cd "$HOME"`,
19208
19297
  `[ -d "${repoDir}/.git" ] || git clone "${gitUrl}" "${repoDir}"`,
@@ -19234,7 +19323,7 @@ var ServiceRuntimeRunner = class {
19234
19323
  const repoDir = this.getRepoDirName(repository);
19235
19324
  const scriptPath = script.startsWith("/") || script.startsWith("./") ? script : `./${script}`;
19236
19325
  const envName = options.envName ?? "prod";
19237
- const envSyncCommand = await this.buildScriptEnvSyncCommand(service.id, envName);
19326
+ const envSyncCommand = await this.buildScriptEnvSyncCommand(service.id, envName, server);
19238
19327
  const command = [
19239
19328
  `cd "$HOME"`,
19240
19329
  `cd "${repoDir}"`,
@@ -19245,13 +19334,17 @@ var ServiceRuntimeRunner = class {
19245
19334
  ].join(" && ");
19246
19335
  await this.runRemoteCommand(server, command);
19247
19336
  }
19248
- async buildScriptEnvSyncCommand(serviceId, envName) {
19337
+ async buildScriptEnvSyncCommand(serviceId, envName, hostTarget) {
19249
19338
  if (!this.envProvider) {
19250
19339
  return void 0;
19251
19340
  }
19252
19341
  let pulled;
19253
19342
  try {
19254
- pulled = await this.envProvider(serviceId, { stage: this.envNameToStage(envName), format: "dotenv" });
19343
+ pulled = await this.envProvider(serviceId, {
19344
+ stage: this.envNameToStage(envName),
19345
+ format: "dotenv",
19346
+ ...hostTarget ? { hostTarget } : {}
19347
+ });
19255
19348
  } catch (error) {
19256
19349
  if (error instanceof ServiceEnvNotFoundError) {
19257
19350
  ui.warn(`No env found for ${serviceId}; skipping PMate env file sync.`);
@@ -19314,7 +19407,7 @@ var ServiceRuntimeRunner = class {
19314
19407
  const serverAddress = await resolveServerAddress(server);
19315
19408
  const templateName = exposeType === "websocket" ? "nginx.ws.template" : "nginx.rest.template";
19316
19409
  const templatePath = this.resolveTemplatePath(templateName);
19317
- const template = (0, import_node_fs19.readFileSync)(templatePath, "utf8");
19410
+ const template = (0, import_node_fs20.readFileSync)(templatePath, "utf8");
19318
19411
  const host = `${subdomain}.${("domain" in network ? network.domain?.trim() : void 0) || "pmate.chat"}`;
19319
19412
  const rendered = template.replace(/\$\{\{PORT\}\}/g, String(port)).replace(/\$\{\{HOSTS\}\}/g, host).replace(/\$\{\{HOST\}\}/g, host);
19320
19413
  const remotePath = `/etc/nginx/sites-enabled/${subdomain}.conf`;
@@ -19346,11 +19439,11 @@ var ServiceRuntimeRunner = class {
19346
19439
  }
19347
19440
  if (config.ensurePackageJson) {
19348
19441
  const appDir = this.resolveLocalDir(service, options.cwd);
19349
- const packageJsonPath = import_node_path23.default.join(appDir, "package.json");
19350
- if (!(0, import_node_fs19.existsSync)(packageJsonPath)) {
19442
+ const packageJsonPath = import_node_path24.default.join(appDir, "package.json");
19443
+ if (!(0, import_node_fs20.existsSync)(packageJsonPath)) {
19351
19444
  throw new Error(`Missing package.json at ${packageJsonPath}`);
19352
19445
  }
19353
- const pkgStat = (0, import_node_fs19.statSync)(packageJsonPath);
19446
+ const pkgStat = (0, import_node_fs20.statSync)(packageJsonPath);
19354
19447
  if (!pkgStat.isFile()) {
19355
19448
  throw new Error(`package.json is not a file at ${packageJsonPath}`);
19356
19449
  }
@@ -19780,9 +19873,9 @@ var ServiceRuntimeRunner = class {
19780
19873
  return tokens;
19781
19874
  }
19782
19875
  readPathValue(source, pathExpr) {
19783
- const path28 = pathExpr.split(".").map((segment) => segment.trim()).filter(Boolean);
19876
+ const path29 = pathExpr.split(".").map((segment) => segment.trim()).filter(Boolean);
19784
19877
  let cursor = source;
19785
- for (const segment of path28) {
19878
+ for (const segment of path29) {
19786
19879
  if (!cursor || typeof cursor !== "object" || Array.isArray(cursor)) {
19787
19880
  return void 0;
19788
19881
  }
@@ -19825,12 +19918,12 @@ var ServiceRuntimeRunner = class {
19825
19918
  }
19826
19919
  resolveTemplatePath(templateName) {
19827
19920
  const candidates = [
19828
- import_node_path23.default.join(__dirname, "..", "templates", templateName),
19829
- import_node_path23.default.join(__dirname, "..", "src", "templates", templateName),
19830
- import_node_path23.default.join(__dirname, "templates", templateName)
19921
+ import_node_path24.default.join(__dirname, "..", "templates", templateName),
19922
+ import_node_path24.default.join(__dirname, "..", "src", "templates", templateName),
19923
+ import_node_path24.default.join(__dirname, "templates", templateName)
19831
19924
  ];
19832
19925
  for (const candidate of candidates) {
19833
- if ((0, import_node_fs19.existsSync)(candidate)) {
19926
+ if ((0, import_node_fs20.existsSync)(candidate)) {
19834
19927
  return candidate;
19835
19928
  }
19836
19929
  }
@@ -19862,7 +19955,7 @@ var ServiceRuntimeRunner = class {
19862
19955
  });
19863
19956
  }
19864
19957
  loadPackageJson(packageJsonPath) {
19865
- const raw = (0, import_node_fs19.readFileSync)(packageJsonPath, "utf8");
19958
+ const raw = (0, import_node_fs20.readFileSync)(packageJsonPath, "utf8");
19866
19959
  const parsed = JSON.parse(raw);
19867
19960
  if (!parsed || typeof parsed !== "object") {
19868
19961
  throw new Error(`Invalid package.json at ${packageJsonPath}`);
@@ -19871,7 +19964,7 @@ var ServiceRuntimeRunner = class {
19871
19964
  }
19872
19965
  writePackageJson(packageJsonPath, data) {
19873
19966
  const serialized = JSON.stringify(data, null, 2);
19874
- (0, import_node_fs19.writeFileSync)(packageJsonPath, `${serialized}
19967
+ (0, import_node_fs20.writeFileSync)(packageJsonPath, `${serialized}
19875
19968
  `, "utf8");
19876
19969
  }
19877
19970
  validateFcConfig(service, fc) {
@@ -19898,8 +19991,8 @@ var ServiceRuntimeRunner = class {
19898
19991
  }
19899
19992
  }
19900
19993
  async ensurePnpmWorkspaceRoot(repoRoot) {
19901
- const workspacePath = import_node_path23.default.join(repoRoot, "pnpm-workspace.yaml");
19902
- if (!(0, import_node_fs19.existsSync)(workspacePath)) {
19994
+ const workspacePath = import_node_path24.default.join(repoRoot, "pnpm-workspace.yaml");
19995
+ if (!(0, import_node_fs20.existsSync)(workspacePath)) {
19903
19996
  throw new Error(`Missing pnpm-workspace.yaml at ${workspacePath}`);
19904
19997
  }
19905
19998
  }
@@ -19973,16 +20066,16 @@ var ServiceRuntimeRunner = class {
19973
20066
  if (!privateKeyPath) {
19974
20067
  throw new Error("Missing ssl.prv in ~/.pmate/config.yaml.");
19975
20068
  }
19976
- if (!(0, import_node_fs19.existsSync)(certificatePath)) {
20069
+ if (!(0, import_node_fs20.existsSync)(certificatePath)) {
19977
20070
  throw new Error(`SSL certificate file not found: ${certificatePath}`);
19978
20071
  }
19979
- if (!(0, import_node_fs19.existsSync)(privateKeyPath)) {
20072
+ if (!(0, import_node_fs20.existsSync)(privateKeyPath)) {
19980
20073
  throw new Error(`SSL private key file not found: ${privateKeyPath}`);
19981
20074
  }
19982
20075
  return {
19983
20076
  certName: host,
19984
- certificate: (0, import_node_fs19.readFileSync)(certificatePath, "utf8"),
19985
- privateKey: (0, import_node_fs19.readFileSync)(privateKeyPath, "utf8")
20077
+ certificate: (0, import_node_fs20.readFileSync)(certificatePath, "utf8"),
20078
+ privateKey: (0, import_node_fs20.readFileSync)(privateKeyPath, "utf8")
19986
20079
  };
19987
20080
  }
19988
20081
  resolveFcProtocol(fc, certConfig) {
@@ -20376,7 +20469,7 @@ var ServiceCommandHandler = class {
20376
20469
  format: "dotenv"
20377
20470
  }
20378
20471
  );
20379
- const outputPath = import_node_path24.default.resolve(process.cwd(), args.output);
20472
+ const outputPath = import_node_path25.default.resolve(process.cwd(), args.output);
20380
20473
  await (0, import_promises6.writeFile)(outputPath, payload.content, "utf8");
20381
20474
  ui.success(`Wrote env file for ${args.appId} to ${outputPath}`);
20382
20475
  this.renderJson({ ...payload, output: outputPath }, args.json);
@@ -20598,11 +20691,11 @@ var ServiceCommandHandler = class {
20598
20691
  return (baseUrl || process.env.PMATE_APPS_API_BASE_URL || "https://apps-api.pmate.chat").replace(/\/+$/, "");
20599
20692
  }
20600
20693
  readJsonFile(filePath) {
20601
- const absolutePath = import_node_path24.default.resolve(process.cwd(), filePath);
20602
- if (!(0, import_node_fs20.existsSync)(absolutePath)) {
20694
+ const absolutePath = import_node_path25.default.resolve(process.cwd(), filePath);
20695
+ if (!(0, import_node_fs21.existsSync)(absolutePath)) {
20603
20696
  throw new Error(`JSON file not found: ${absolutePath}`);
20604
20697
  }
20605
- const raw = (0, import_node_fs20.readFileSync)(absolutePath, "utf8");
20698
+ const raw = (0, import_node_fs21.readFileSync)(absolutePath, "utf8");
20606
20699
  try {
20607
20700
  return JSON.parse(raw);
20608
20701
  } catch (error) {
@@ -21327,9 +21420,9 @@ var RoleCommandHandler = class {
21327
21420
  };
21328
21421
 
21329
21422
  // src/commands/AccountCommandHandler.ts
21330
- var import_node_fs21 = require("fs");
21423
+ var import_node_fs22 = require("fs");
21331
21424
  var import_node_crypto4 = require("crypto");
21332
- var import_node_path25 = __toESM(require("path"));
21425
+ var import_node_path26 = __toESM(require("path"));
21333
21426
  init_sessionStore();
21334
21427
  var AccountCommandHandler = class {
21335
21428
  async handle(args) {
@@ -21337,9 +21430,9 @@ var AccountCommandHandler = class {
21337
21430
  case "bot-keygen": {
21338
21431
  const keyFile = this.generateBotKeyFile(args.app, args.name);
21339
21432
  const outPath = args.out ? this.resolveFilePath(args.out) : this.resolveDefaultBotKeyPath(args.app, args.name);
21340
- (0, import_node_fs21.mkdirSync)(import_node_path25.default.dirname(outPath), { recursive: true });
21341
- (0, import_node_fs21.writeFileSync)(outPath, JSON.stringify(keyFile, null, 2), { mode: 384 });
21342
- (0, import_node_fs21.chmodSync)(outPath, 384);
21433
+ (0, import_node_fs22.mkdirSync)(import_node_path26.default.dirname(outPath), { recursive: true });
21434
+ (0, import_node_fs22.writeFileSync)(outPath, JSON.stringify(keyFile, null, 2), { mode: 384 });
21435
+ (0, import_node_fs22.chmodSync)(outPath, 384);
21343
21436
  if (!args.json) {
21344
21437
  ui.success(`Bot key saved to ${outPath}`);
21345
21438
  }
@@ -21789,10 +21882,10 @@ var AccountCommandHandler = class {
21789
21882
  throw new Error("Missing visible apps input");
21790
21883
  }
21791
21884
  const absolutePath = this.resolveFilePath(args.filePath);
21792
- if (!(0, import_node_fs21.existsSync)(absolutePath)) {
21885
+ if (!(0, import_node_fs22.existsSync)(absolutePath)) {
21793
21886
  throw new Error(`JSON file not found: ${absolutePath}`);
21794
21887
  }
21795
- const raw = (0, import_node_fs21.readFileSync)(absolutePath, "utf8");
21888
+ const raw = (0, import_node_fs22.readFileSync)(absolutePath, "utf8");
21796
21889
  let parsed;
21797
21890
  try {
21798
21891
  parsed = JSON.parse(raw);
@@ -21806,10 +21899,10 @@ var AccountCommandHandler = class {
21806
21899
  return parsed;
21807
21900
  }
21808
21901
  resolveFilePath(filePath) {
21809
- return import_node_path25.default.resolve(process.cwd(), filePath);
21902
+ return import_node_path26.default.resolve(process.cwd(), filePath);
21810
21903
  }
21811
21904
  resolveDefaultBotKeyPath(app, name) {
21812
- return import_node_path25.default.join(this.homeDir(), ".pmate", "bots", app, `${name}.bot-key.json`);
21905
+ return import_node_path26.default.join(this.homeDir(), ".pmate", "bots", app, `${name}.bot-key.json`);
21813
21906
  }
21814
21907
  homeDir() {
21815
21908
  return process.env.HOME || process.env.USERPROFILE || process.cwd();
@@ -21832,10 +21925,10 @@ var AccountCommandHandler = class {
21832
21925
  throw new Error("Missing bot key file");
21833
21926
  }
21834
21927
  const absolutePath = this.resolveFilePath(filePath);
21835
- if (!(0, import_node_fs21.existsSync)(absolutePath)) {
21928
+ if (!(0, import_node_fs22.existsSync)(absolutePath)) {
21836
21929
  throw new Error(`Bot key file not found: ${absolutePath}`);
21837
21930
  }
21838
- const parsed = JSON.parse((0, import_node_fs21.readFileSync)(absolutePath, "utf8"));
21931
+ const parsed = JSON.parse((0, import_node_fs22.readFileSync)(absolutePath, "utf8"));
21839
21932
  if (parsed.type !== "pmate-bot-key" || parsed.version !== 1 || parsed.algorithm !== "ed25519" || !parsed.publicKey || !parsed.privateKey) {
21840
21933
  throw new Error(`Invalid PMate bot key file: ${absolutePath}`);
21841
21934
  }
@@ -21887,8 +21980,8 @@ function encodePathSegment(value) {
21887
21980
  }
21888
21981
 
21889
21982
  // src/commands/OrgCommandHandler.ts
21890
- var import_node_fs22 = require("fs");
21891
- var import_node_path26 = __toESM(require("path"));
21983
+ var import_node_fs23 = require("fs");
21984
+ var import_node_path27 = __toESM(require("path"));
21892
21985
  init_sessionStore();
21893
21986
  var OrgCommandHandler = class {
21894
21987
  async handle(args) {
@@ -22059,11 +22152,11 @@ var OrgCommandHandler = class {
22059
22152
  if (!filePath) {
22060
22153
  throw new Error(`Missing ${itemLabel} input`);
22061
22154
  }
22062
- const absolutePath = import_node_path26.default.resolve(process.cwd(), filePath);
22063
- if (!(0, import_node_fs22.existsSync)(absolutePath)) {
22155
+ const absolutePath = import_node_path27.default.resolve(process.cwd(), filePath);
22156
+ if (!(0, import_node_fs23.existsSync)(absolutePath)) {
22064
22157
  throw new Error(`JSON file not found: ${absolutePath}`);
22065
22158
  }
22066
- const raw = (0, import_node_fs22.readFileSync)(absolutePath, "utf8");
22159
+ const raw = (0, import_node_fs23.readFileSync)(absolutePath, "utf8");
22067
22160
  let parsed;
22068
22161
  try {
22069
22162
  parsed = JSON.parse(raw);
@@ -25139,7 +25232,7 @@ function requireValue12(tokens, option) {
25139
25232
 
25140
25233
  // src/index.ts
25141
25234
  var pkg = JSON.parse(
25142
- (0, import_node_fs23.readFileSync)(import_node_path27.default.resolve(__dirname, "..", "package.json"), "utf8")
25235
+ (0, import_node_fs24.readFileSync)(import_node_path28.default.resolve(__dirname, "..", "package.json"), "utf8")
25143
25236
  );
25144
25237
  var HELP_TEXT = [
25145
25238
  import_chalk4.default.bold(`pmate v${pkg.version}`),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmate/cli",
3
- "version": "0.24.35",
3
+ "version": "0.24.37",
4
4
  "description": "CLI utilities for the pMate project",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -56,8 +56,8 @@
56
56
  "yaml": "^2.8.2"
57
57
  },
58
58
  "devDependencies": {
59
- "@pmate/agent-sdk": "^1.1.14",
60
- "@pmate/meta": "^1.1.13",
59
+ "@pmate/agent-sdk": "^1.1.16",
60
+ "@pmate/meta": "^1.1.15",
61
61
  "@pmate/utils": "^1.1.4",
62
62
  "@types/node": "^25.0.3",
63
63
  "@types/pngjs": "^6.0.5",
@@ -69,7 +69,7 @@
69
69
  },
70
70
  "pnpm": {
71
71
  "overrides": {
72
- "@pmate/meta": "^1.1.13",
72
+ "@pmate/meta": "^1.1.15",
73
73
  "@pmate/utils": "^1.1.4"
74
74
  }
75
75
  }