openmates 0.18.0-alpha.7 → 0.18.0-alpha.9

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.
@@ -8437,7 +8437,7 @@ var OpenMatesClient = class _OpenMatesClient {
8437
8437
  if (!userId) {
8438
8438
  throw new Error("Could not resolve current user id for local connected-account connector.");
8439
8439
  }
8440
- const { createHash: createHash15 } = await import("crypto");
8440
+ const { createHash: createHash16 } = await import("crypto");
8441
8441
  const accountId = randomUUID6();
8442
8442
  const masterKey = this.getMasterKeyBytes();
8443
8443
  const encryptLocalConnectorValue = async (value) => {
@@ -8446,9 +8446,9 @@ var OpenMatesClient = class _OpenMatesClient {
8446
8446
  };
8447
8447
  const payload = {
8448
8448
  id: accountId,
8449
- hashed_user_id: createHash15("sha256").update(userId).digest("hex"),
8449
+ hashed_user_id: createHash16("sha256").update(userId).digest("hex"),
8450
8450
  encrypted_provider_type: await encryptLocalConnectorValue(input.provider_id),
8451
- provider_type_hash: createHash15("sha256").update(input.provider_id).digest("hex"),
8451
+ provider_type_hash: createHash16("sha256").update(input.provider_id).digest("hex"),
8452
8452
  encrypted_account_label: await encryptLocalConnectorValue(input.label),
8453
8453
  encrypted_capabilities: await encryptLocalConnectorValue(input.capabilities),
8454
8454
  encrypted_app_permissions: await encryptLocalConnectorValue({
@@ -9947,8 +9947,8 @@ var OpenMatesClient = class _OpenMatesClient {
9947
9947
  );
9948
9948
  }
9949
9949
  const embedId = String(embed.embed_id ?? embed.id ?? "");
9950
- const { createHash: createHash15 } = await import("crypto");
9951
- const hashedEmbedId = createHash15("sha256").update(embedId).digest("hex");
9950
+ const { createHash: createHash16 } = await import("crypto");
9951
+ const hashedEmbedId = createHash16("sha256").update(embedId).digest("hex");
9952
9952
  const embedKeyBytes = await this.resolveEmbedKey(
9953
9953
  cache,
9954
9954
  masterKey,
@@ -10056,7 +10056,7 @@ var OpenMatesClient = class _OpenMatesClient {
10056
10056
  async resolveEmbedKey(cache, masterKey, embed, embedId, hashedEmbedId, visited = /* @__PURE__ */ new Set()) {
10057
10057
  if (visited.has(embedId)) return null;
10058
10058
  visited.add(embedId);
10059
- const { createHash: createHash15 } = await import("crypto");
10059
+ const { createHash: createHash16 } = await import("crypto");
10060
10060
  const masterKeyEntry = cache.embedKeys.find(
10061
10061
  (ek) => ek.hashed_embed_id === hashedEmbedId && String(ek.key_type) === "master"
10062
10062
  );
@@ -10073,7 +10073,7 @@ var OpenMatesClient = class _OpenMatesClient {
10073
10073
  if (chatKeyEntry && typeof chatKeyEntry.encrypted_embed_key === "string") {
10074
10074
  const hashedChatId = String(chatKeyEntry.hashed_chat_id ?? "");
10075
10075
  const owningChat = cache.chats.find((c) => {
10076
- const chatHash = createHash15("sha256").update(String(c.details.id ?? "")).digest("hex");
10076
+ const chatHash = createHash16("sha256").update(String(c.details.id ?? "")).digest("hex");
10077
10077
  return chatHash === hashedChatId;
10078
10078
  });
10079
10079
  if (owningChat) {
@@ -10102,7 +10102,7 @@ var OpenMatesClient = class _OpenMatesClient {
10102
10102
  const parentFullId = String(
10103
10103
  parentEmbed2.embed_id ?? parentEmbed2.id ?? ""
10104
10104
  );
10105
- const parentHashedId = createHash15("sha256").update(parentFullId).digest("hex");
10105
+ const parentHashedId = createHash16("sha256").update(parentFullId).digest("hex");
10106
10106
  const parentKey = await this.resolveEmbedKey(
10107
10107
  cache,
10108
10108
  masterKey,
@@ -12841,6 +12841,7 @@ var OpenMatesClient = class _OpenMatesClient {
12841
12841
  if (Number.isSafeInteger(context.limit) && context.limit !== void 0 && context.limit > 0) {
12842
12842
  params.set("limit", String(context.limit));
12843
12843
  }
12844
+ if (context.newestFirst) params.set("newest_first", "true");
12844
12845
  const query = params.toString();
12845
12846
  const response = await this.http.get(
12846
12847
  `/v1/user-tasks/${encodeURIComponent(taskId)}/activity${query ? `?${query}` : ""}`,
@@ -14136,7 +14137,7 @@ Required: ${schema.required.join(", ")}`
14136
14137
  const session = this.requireSession();
14137
14138
  const masterKey = base64ToBytes(session.masterKeyExportedB64);
14138
14139
  const cache = await this.ensureSynced();
14139
- const { createHash: createHash15 } = await import("crypto");
14140
+ const { createHash: createHash16 } = await import("crypto");
14140
14141
  const embed = cache.embeds.find(
14141
14142
  (e) => String(e.embed_id ?? "").startsWith(embedIdOrShort) || String(e.id ?? "").startsWith(embedIdOrShort)
14142
14143
  );
@@ -14144,7 +14145,7 @@ Required: ${schema.required.join(", ")}`
14144
14145
  throw new Error(`Embed '${embedIdOrShort}' not found in local cache.`);
14145
14146
  }
14146
14147
  const embedId = String(embed.embed_id ?? embed.id ?? "");
14147
- const hashedEmbedId = createHash15("sha256").update(embedId).digest("hex");
14148
+ const hashedEmbedId = createHash16("sha256").update(embedId).digest("hex");
14148
14149
  const embedKeyBytes = await this.resolveEmbedKey(
14149
14150
  cache,
14150
14151
  masterKey,
@@ -14252,8 +14253,8 @@ Required: ${schema.required.join(", ")}`
14252
14253
  if (!embed) {
14253
14254
  throw new Error(`Embed '${embedId}' not found in local cache. Run 'openmates chats list' to sync first.`);
14254
14255
  }
14255
- const { createHash: createHash15 } = await import("crypto");
14256
- const hashedEmbedId = createHash15("sha256").update(embedId).digest("hex");
14256
+ const { createHash: createHash16 } = await import("crypto");
14257
+ const hashedEmbedId = createHash16("sha256").update(embedId).digest("hex");
14257
14258
  const embedKey = await this.resolveEmbedKey(
14258
14259
  cache,
14259
14260
  masterKey,
@@ -14369,8 +14370,8 @@ Required: ${schema.required.join(", ")}`
14369
14370
  if (!embed) {
14370
14371
  throw new Error(`Embed '${embedId}' not found in local cache. Run 'openmates chats list' to sync first.`);
14371
14372
  }
14372
- const { createHash: createHash15 } = await import("crypto");
14373
- const hashedEmbedId = createHash15("sha256").update(embedId).digest("hex");
14373
+ const { createHash: createHash16 } = await import("crypto");
14374
+ const hashedEmbedId = createHash16("sha256").update(embedId).digest("hex");
14374
14375
  const embedKey = await this.resolveEmbedKey(
14375
14376
  cache,
14376
14377
  masterKey,
@@ -14837,9 +14838,9 @@ Required: ${schema.required.join(", ")}`
14837
14838
  chats.splice(0, chats.length, ...reconciledChats);
14838
14839
  if (totalChatCount === 0) totalChatCount = chats.length;
14839
14840
  if (reconciliation.deleted_chat_ids?.length) {
14840
- const { createHash: createHash15 } = await import("crypto");
14841
+ const { createHash: createHash16 } = await import("crypto");
14841
14842
  const deletedHashes = new Set(
14842
- reconciliation.deleted_chat_ids.map((id) => createHash15("sha256").update(id).digest("hex"))
14843
+ reconciliation.deleted_chat_ids.map((id) => createHash16("sha256").update(id).digest("hex"))
14843
14844
  );
14844
14845
  const keptEmbeds = embeds.filter((embed) => !deletedHashes.has(String(embed.hashed_chat_id ?? "")));
14845
14846
  const keptKeys = embedKeys.filter((key) => !deletedHashes.has(String(key.hashed_chat_id ?? "")));
@@ -20224,12 +20225,12 @@ var ACCOUNT_EXPORT_FORBIDDEN_VALUE_PATTERNS = [
20224
20225
  ];
20225
20226
  async function writeAccountExportArchive(bundle, flags = {}) {
20226
20227
  const { mkdir: mkdir2, writeFile: writeFile2 } = await import("fs/promises");
20227
- const { join: join12, dirname: dirname11 } = await import("path");
20228
+ const { join: join13, dirname: dirname11 } = await import("path");
20228
20229
  const exportId = safeArchiveSegment(String(bundle.export.export_id ?? `export-${Date.now()}`));
20229
20230
  const archiveFormat = flags.format === "directory" ? "directory" : "zip";
20230
20231
  const password = typeof flags.password === "string" && flags.password.length > 0 ? flags.password : null;
20231
20232
  if (password && archiveFormat !== "zip") throw new Error("Password-protected account export is only supported for zip format.");
20232
- const outputPath = typeof flags.output === "string" ? flags.output : join12(process.cwd(), archiveFormat === "zip" ? `openmates-account-export-${exportId}${password ? ".zip.enc" : ".zip"}` : `openmates-account-export-${exportId}`);
20233
+ const outputPath = typeof flags.output === "string" ? flags.output : join13(process.cwd(), archiveFormat === "zip" ? `openmates-account-export-${exportId}${password ? ".zip.enc" : ".zip"}` : `openmates-account-export-${exportId}`);
20233
20234
  const zip = archiveFormat === "zip" ? new JSZip3() : null;
20234
20235
  const writtenFiles = [];
20235
20236
  async function writeArchiveText(relativePath, content) {
@@ -20240,7 +20241,7 @@ async function writeAccountExportArchive(bundle, flags = {}) {
20240
20241
  return;
20241
20242
  }
20242
20243
  const stagingDir = outputPath;
20243
- const fullPath = join12(stagingDir, relativePath);
20244
+ const fullPath = join13(stagingDir, relativePath);
20244
20245
  await mkdir2(dirname11(fullPath), { recursive: true });
20245
20246
  await writeFile2(fullPath, content, "utf-8");
20246
20247
  writtenFiles.push(relativePath);
@@ -24391,10 +24392,115 @@ var OpenMatesBenchmark = class {
24391
24392
  // src/cli.ts
24392
24393
  import { createInterface as createInterface5 } from "readline/promises";
24393
24394
  import { stdin as stdin3, stdout as stdout2 } from "process";
24394
- import { existsSync as existsSync13, readFileSync as readFileSync12, realpathSync as realpathSync2, writeFileSync as writeFileSync10 } from "fs";
24395
+
24396
+ // src/taskActivityHistory.ts
24397
+ async function readActivityHistory(options) {
24398
+ const { query } = options;
24399
+ const maxEntries = options.maxEntries ?? Infinity;
24400
+ if (options.maxEntries !== void 0 && (!Number.isSafeInteger(maxEntries) || maxEntries < 1 || maxEntries > 200)) {
24401
+ throw new Error("--max-entries must be an integer from 1 to 200");
24402
+ }
24403
+ if (query !== void 0 && !query.trim()) throw new Error("Activity search requires a non-empty --query");
24404
+ const pageSize = options.pageSize ?? 100;
24405
+ if (!Number.isSafeInteger(pageSize) || pageSize < 1 || pageSize > 200) throw new Error("--limit must be from 1 to 200");
24406
+ const entries = [];
24407
+ const seen = /* @__PURE__ */ new Set();
24408
+ let cursor = options.cursor;
24409
+ let matched = 0;
24410
+ do {
24411
+ const page = await options.page(cursor, query === void 0 ? Math.min(pageSize, maxEntries - entries.length) : pageSize);
24412
+ for (const entry of page.entries) {
24413
+ if (query === void 0 || (entry.message || "").toLocaleLowerCase().includes(query.toLocaleLowerCase())) {
24414
+ matched++;
24415
+ if (entries.length < maxEntries) entries.push(entry);
24416
+ }
24417
+ }
24418
+ cursor = page.next_cursor || void 0;
24419
+ if (cursor && seen.has(cursor)) throw new Error("Activity pagination repeated a cursor");
24420
+ if (cursor) seen.add(cursor);
24421
+ } while (cursor && (query !== void 0 || entries.length < maxEntries));
24422
+ return { entries, next_cursor: cursor || null, truncated: Boolean(cursor) || matched > entries.length, matched };
24423
+ }
24424
+
24425
+ // src/taskActivityDelivery.ts
24426
+ import { createHash as createHash12 } from "crypto";
24427
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync6, readdirSync as readdirSync2, renameSync as renameSync2, writeFileSync as writeFileSync4, rmSync as rmSync3, existsSync as existsSync7 } from "fs";
24428
+ import { join as join4 } from "path";
24429
+ import lockfile2 from "proper-lockfile";
24430
+ function activityDeliveryStore(scope, stateDir2 = resolveStateDir()) {
24431
+ const directory = join4(stateDir2, "task-activity-delivery", createHash12("sha256").update(scope).digest("hex"));
24432
+ mkdirSync4(directory, { recursive: true, mode: 448 });
24433
+ const pendingDirectory = join4(directory, "pending");
24434
+ const acknowledgedDirectory = join4(directory, "acknowledged");
24435
+ mkdirSync4(pendingDirectory, { recursive: true, mode: 448 });
24436
+ mkdirSync4(acknowledgedDirectory, { recursive: true, mode: 448 });
24437
+ const save = (path2, record) => {
24438
+ const temporary = `${path2}.${process.pid}.tmp`;
24439
+ writeFileSync4(temporary, JSON.stringify(record), { mode: 384 });
24440
+ renameSync2(temporary, path2);
24441
+ };
24442
+ const send = async (path2, record, create) => {
24443
+ if (!record.acknowledged) {
24444
+ const acknowledged = await create(record.input);
24445
+ if (acknowledged.entry_id !== record.input.entry_id) throw new Error("Activity acknowledgement identity mismatch");
24446
+ record.acknowledged = acknowledged;
24447
+ save(join4(acknowledgedDirectory, `${record.input.entry_id}.json`), record);
24448
+ rmSync3(path2, { force: true });
24449
+ }
24450
+ return record.acknowledged;
24451
+ };
24452
+ return {
24453
+ async deliver(id, build, create) {
24454
+ if (!/^[a-f0-9]{64}$/.test(id)) throw new Error("--delivery-id must be a SHA-256 hex identifier");
24455
+ const release2 = await lockfile2.lock(directory, { retries: { retries: 3, minTimeout: 100, maxTimeout: 500 }, stale: 12e4 });
24456
+ try {
24457
+ const acknowledgedPath = join4(acknowledgedDirectory, `${id}.json`);
24458
+ const path2 = existsSync7(acknowledgedPath) ? acknowledgedPath : join4(pendingDirectory, `${id}.json`);
24459
+ let record;
24460
+ try {
24461
+ record = JSON.parse(readFileSync6(path2, "utf8"));
24462
+ } catch (error) {
24463
+ if (error.code !== "ENOENT") throw error;
24464
+ record = { input: await build() };
24465
+ save(path2, record);
24466
+ }
24467
+ return await send(path2, record, create);
24468
+ } finally {
24469
+ await release2();
24470
+ }
24471
+ },
24472
+ async flush(create) {
24473
+ const release2 = await lockfile2.lock(directory, { retries: 0, stale: 12e4 });
24474
+ try {
24475
+ const names = readdirSync2(pendingDirectory).filter((name) => /^[a-f0-9]{64}\.json$/.test(name));
24476
+ let pending = names.length;
24477
+ let attempted = 0;
24478
+ for (const name of names) {
24479
+ const path2 = join4(pendingDirectory, name);
24480
+ const record = JSON.parse(readFileSync6(path2, "utf8"));
24481
+ if (record.acknowledged) continue;
24482
+ if (attempted >= 3) break;
24483
+ attempted++;
24484
+ try {
24485
+ await send(path2, record, create);
24486
+ pending--;
24487
+ } catch {
24488
+ break;
24489
+ }
24490
+ }
24491
+ return { pending, attempted };
24492
+ } finally {
24493
+ await release2();
24494
+ }
24495
+ }
24496
+ };
24497
+ }
24498
+
24499
+ // src/cli.ts
24500
+ import { existsSync as existsSync14, readFileSync as readFileSync13, realpathSync as realpathSync2, writeFileSync as writeFileSync11 } from "fs";
24395
24501
  import { fileURLToPath as fileURLToPath3 } from "url";
24396
24502
  import { basename as basename4, dirname as dirname10 } from "path";
24397
- import { createHash as createHash14, randomBytes as randomBytes9, randomUUID as randomUUID15 } from "crypto";
24503
+ import { createHash as createHash15, randomBytes as randomBytes9, randomUUID as randomUUID15 } from "crypto";
24398
24504
  import { arch as arch2, platform as platform3 } from "os";
24399
24505
  import { parse as parseYaml } from "yaml";
24400
24506
  import WebSocket2 from "ws";
@@ -26573,12 +26679,12 @@ function formatTs(ts) {
26573
26679
 
26574
26680
  // src/server.ts
26575
26681
  import { execFileSync as execFileSync4, execSync, spawn as nodeSpawn, spawnSync } from "child_process";
26576
- import { createHash as createHash12, randomBytes as randomBytes8, randomUUID as randomUUID11 } from "crypto";
26577
- import { appendFileSync, chmodSync as chmodSync5, closeSync as closeSync2, copyFileSync as copyFileSync2, cpSync, existsSync as existsSync9, mkdirSync as mkdirSync6, mkdtempSync, openSync as openSync2, readFileSync as readFileSync7, readSync, readdirSync as readdirSync4, rmSync as rmSync6, writeFileSync as writeFileSync5 } from "fs";
26682
+ import { createHash as createHash13, randomBytes as randomBytes8, randomUUID as randomUUID11 } from "crypto";
26683
+ import { appendFileSync, chmodSync as chmodSync5, closeSync as closeSync2, copyFileSync as copyFileSync2, cpSync, existsSync as existsSync10, mkdirSync as mkdirSync7, mkdtempSync, openSync as openSync2, readFileSync as readFileSync8, readSync, readdirSync as readdirSync5, rmSync as rmSync7, writeFileSync as writeFileSync6 } from "fs";
26578
26684
  import { createInterface as createInterface3 } from "readline";
26579
26685
  import { createInterface as createPromptInterface } from "readline/promises";
26580
26686
  import { homedir as homedir6 } from "os";
26581
- import { dirname as dirname6, join as join7, resolve as resolve6 } from "path";
26687
+ import { dirname as dirname6, join as join8, resolve as resolve6 } from "path";
26582
26688
 
26583
26689
  // src/branding.ts
26584
26690
  var OPENMATES_WORDMARK = "OPENMATES";
@@ -26614,33 +26720,33 @@ function renderSupportStartReminder() {
26614
26720
  import { execFileSync as execFileSync2 } from "child_process";
26615
26721
  import {
26616
26722
  copyFileSync,
26617
- existsSync as existsSync7,
26618
- mkdirSync as mkdirSync4,
26619
- readdirSync as readdirSync2,
26620
- rmSync as rmSync3,
26723
+ existsSync as existsSync8,
26724
+ mkdirSync as mkdirSync5,
26725
+ readdirSync as readdirSync3,
26726
+ rmSync as rmSync4,
26621
26727
  symlinkSync
26622
26728
  } from "fs";
26623
26729
  import { createRequire as createRequire3 } from "module";
26624
- import { dirname as dirname3, join as join4, resolve as resolve4 } from "path";
26625
- var UI_PACKAGE_RELATIVE_PATH = join4("frontend", "packages", "ui");
26626
- var GENERATED_LOCALES_RELATIVE_PATH = join4(UI_PACKAGE_RELATIVE_PATH, "src", "i18n", "locales");
26627
- var BUILD_TRANSLATIONS_SCRIPT_RELATIVE_PATH = join4(UI_PACKAGE_RELATIVE_PATH, "scripts", "build-translations.js");
26730
+ import { dirname as dirname3, join as join5, resolve as resolve4 } from "path";
26731
+ var UI_PACKAGE_RELATIVE_PATH = join5("frontend", "packages", "ui");
26732
+ var GENERATED_LOCALES_RELATIVE_PATH = join5(UI_PACKAGE_RELATIVE_PATH, "src", "i18n", "locales");
26733
+ var BUILD_TRANSLATIONS_SCRIPT_RELATIVE_PATH = join5(UI_PACKAGE_RELATIVE_PATH, "scripts", "build-translations.js");
26628
26734
  var REQUIRED_LOCALE_JSON = "en.json";
26629
26735
  function sourceInstallLocalesPath(rootPath) {
26630
- return join4(rootPath, GENERATED_LOCALES_RELATIVE_PATH);
26736
+ return join5(rootPath, GENERATED_LOCALES_RELATIVE_PATH);
26631
26737
  }
26632
26738
  function ensureSourceInstallTranslations(installPath, sourcePath) {
26633
26739
  const localeDir = sourceInstallLocalesPath(installPath);
26634
- const requiredLocalePath = join4(localeDir, REQUIRED_LOCALE_JSON);
26635
- if (existsSync7(requiredLocalePath)) {
26740
+ const requiredLocalePath = join5(localeDir, REQUIRED_LOCALE_JSON);
26741
+ if (existsSync8(requiredLocalePath)) {
26636
26742
  return { status: "already_present", localeDir, copiedFiles: 0 };
26637
26743
  }
26638
26744
  const copiedFiles = copyGeneratedLocaleJson(sourcePath, installPath);
26639
- if (existsSync7(requiredLocalePath)) {
26745
+ if (existsSync8(requiredLocalePath)) {
26640
26746
  return { status: "copied", localeDir, copiedFiles };
26641
26747
  }
26642
26748
  runBuildTranslationsScript(installPath);
26643
- if (!existsSync7(requiredLocalePath)) {
26749
+ if (!existsSync8(requiredLocalePath)) {
26644
26750
  throw new Error(`Generated locale JSON was not created at ${requiredLocalePath}.`);
26645
26751
  }
26646
26752
  return { status: "built", localeDir, copiedFiles };
@@ -26651,31 +26757,31 @@ function copyGeneratedLocaleJson(sourcePath, installPath) {
26651
26757
  const targetRoot = resolve4(installPath);
26652
26758
  if (sourceRoot === targetRoot) return 0;
26653
26759
  const sourceLocaleDir = sourceInstallLocalesPath(sourceRoot);
26654
- if (!existsSync7(join4(sourceLocaleDir, REQUIRED_LOCALE_JSON))) return 0;
26760
+ if (!existsSync8(join5(sourceLocaleDir, REQUIRED_LOCALE_JSON))) return 0;
26655
26761
  const targetLocaleDir = sourceInstallLocalesPath(targetRoot);
26656
- mkdirSync4(targetLocaleDir, { recursive: true });
26762
+ mkdirSync5(targetLocaleDir, { recursive: true });
26657
26763
  let copiedFiles = 0;
26658
- for (const entry of readdirSync2(sourceLocaleDir, { withFileTypes: true })) {
26764
+ for (const entry of readdirSync3(sourceLocaleDir, { withFileTypes: true })) {
26659
26765
  if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
26660
- copyFileSync(join4(sourceLocaleDir, entry.name), join4(targetLocaleDir, entry.name));
26766
+ copyFileSync(join5(sourceLocaleDir, entry.name), join5(targetLocaleDir, entry.name));
26661
26767
  copiedFiles += 1;
26662
26768
  }
26663
26769
  return copiedFiles;
26664
26770
  }
26665
26771
  function runBuildTranslationsScript(installPath) {
26666
- const uiPackageDir = join4(installPath, UI_PACKAGE_RELATIVE_PATH);
26667
- const buildScript = join4(installPath, BUILD_TRANSLATIONS_SCRIPT_RELATIVE_PATH);
26668
- if (!existsSync7(buildScript)) {
26772
+ const uiPackageDir = join5(installPath, UI_PACKAGE_RELATIVE_PATH);
26773
+ const buildScript = join5(installPath, BUILD_TRANSLATIONS_SCRIPT_RELATIVE_PATH);
26774
+ if (!existsSync8(buildScript)) {
26669
26775
  throw new Error(`Translation build script not found at ${buildScript}.`);
26670
26776
  }
26671
26777
  const requireFromCli = createRequire3(import.meta.url);
26672
26778
  const yamlPackageDir = dirname3(requireFromCli.resolve("yaml/package.json"));
26673
- const nodeModulesDir = join4(uiPackageDir, "node_modules");
26674
- const yamlLink = join4(nodeModulesDir, "yaml");
26675
- const hadNodeModulesDir = existsSync7(nodeModulesDir);
26676
- const hadYamlPackage = existsSync7(yamlLink);
26779
+ const nodeModulesDir = join5(uiPackageDir, "node_modules");
26780
+ const yamlLink = join5(nodeModulesDir, "yaml");
26781
+ const hadNodeModulesDir = existsSync8(nodeModulesDir);
26782
+ const hadYamlPackage = existsSync8(yamlLink);
26677
26783
  if (!hadYamlPackage) {
26678
- mkdirSync4(nodeModulesDir, { recursive: true });
26784
+ mkdirSync5(nodeModulesDir, { recursive: true });
26679
26785
  symlinkSync(yamlPackageDir, yamlLink, process.platform === "win32" ? "junction" : "dir");
26680
26786
  }
26681
26787
  try {
@@ -26684,15 +26790,15 @@ function runBuildTranslationsScript(installPath) {
26684
26790
  stdio: "inherit"
26685
26791
  });
26686
26792
  } finally {
26687
- if (!hadYamlPackage) rmSync3(yamlLink, { recursive: true, force: true });
26688
- if (!hadNodeModulesDir && existsSync7(nodeModulesDir) && readdirSync2(nodeModulesDir).length === 0) {
26689
- rmSync3(nodeModulesDir, { recursive: true, force: true });
26793
+ if (!hadYamlPackage) rmSync4(yamlLink, { recursive: true, force: true });
26794
+ if (!hadNodeModulesDir && existsSync8(nodeModulesDir) && readdirSync3(nodeModulesDir).length === 0) {
26795
+ rmSync4(nodeModulesDir, { recursive: true, force: true });
26690
26796
  }
26691
26797
  }
26692
26798
  }
26693
26799
 
26694
26800
  // src/serverPlanning.ts
26695
- import { dirname as dirname4, join as join5, resolve as resolve5 } from "path";
26801
+ import { dirname as dirname4, join as join6, resolve as resolve5 } from "path";
26696
26802
  var CORE_WORKER_SERVICES = [
26697
26803
  "task-worker",
26698
26804
  "user-init-worker",
@@ -26902,10 +27008,10 @@ function parseServerRole(value) {
26902
27008
  throw new Error(`Unsupported server role '${value}'. Use core, upload, or preview.`);
26903
27009
  }
26904
27010
  function defaultOpenMatesCloudOverlayPath(openMatesPath) {
26905
- return resolve5(join5(dirname4(resolve5(openMatesPath)), OPENMATESCLOUD_OVERLAY_DIR));
27011
+ return resolve5(join6(dirname4(resolve5(openMatesPath)), OPENMATESCLOUD_OVERLAY_DIR));
26906
27012
  }
26907
27013
  function defaultOpenMatesCloudComposeFile(overlayPath) {
26908
- return resolve5(join5(overlayPath, OPENMATESCLOUD_COMPOSE_FILE));
27014
+ return resolve5(join6(overlayPath, OPENMATESCLOUD_COMPOSE_FILE));
26909
27015
  }
26910
27016
  function planOpenMatesCloudOverlay(input) {
26911
27017
  const deploymentMode = input.deploymentMode ?? "self_host";
@@ -27287,12 +27393,12 @@ function shouldAutoInstallRuntimeMonitoringServices(env) {
27287
27393
 
27288
27394
  // src/serverBackupArchive.ts
27289
27395
  import { execFileSync as execFileSync3 } from "child_process";
27290
- import { chmodSync as chmodSync3, lstatSync, readdirSync as readdirSync3, renameSync as renameSync2, rmSync as rmSync4 } from "fs";
27396
+ import { chmodSync as chmodSync3, lstatSync, readdirSync as readdirSync4, renameSync as renameSync3, rmSync as rmSync5 } from "fs";
27291
27397
  import { randomUUID as randomUUID8 } from "crypto";
27292
27398
  function assertRegularBackupTree(path2) {
27293
27399
  const stat2 = lstatSync(path2);
27294
27400
  if (stat2.isDirectory()) {
27295
- for (const entry of readdirSync3(path2)) assertRegularBackupTree(`${path2}/${entry}`);
27401
+ for (const entry of readdirSync4(path2)) assertRegularBackupTree(`${path2}/${entry}`);
27296
27402
  return;
27297
27403
  }
27298
27404
  if (!stat2.isFile() || stat2.nlink !== 1) {
@@ -27306,11 +27412,11 @@ function publishServerBackupArchive(sourceDir, archivePath, options = {}) {
27306
27412
  try {
27307
27413
  execFileSync3(options.tarCommand ?? "tar", ["-czf", temporaryArchivePath, "-C", sourceDir, "."], { stdio: "pipe" });
27308
27414
  chmodSync3(temporaryArchivePath, 384);
27309
- renameSync2(temporaryArchivePath, archivePath);
27415
+ renameSync3(temporaryArchivePath, archivePath);
27310
27416
  chmodSync3(archivePath, 384);
27311
27417
  } finally {
27312
27418
  process.umask(previousUmask);
27313
- rmSync4(temporaryArchivePath, { force: true });
27419
+ rmSync5(temporaryArchivePath, { force: true });
27314
27420
  }
27315
27421
  }
27316
27422
 
@@ -27908,16 +28014,16 @@ function signRuntimeWebhookPayload(payload, secret, timestamp, eventId) {
27908
28014
 
27909
28015
  // src/serverUpdateState.ts
27910
28016
  import { randomBytes as randomBytes7 } from "crypto";
27911
- import { chmodSync as chmodSync4, closeSync, existsSync as existsSync8, mkdirSync as mkdirSync5, openSync, readFileSync as readFileSync6, renameSync as renameSync3, rmSync as rmSync5, writeFileSync as writeFileSync4 } from "fs";
27912
- import { dirname as dirname5, join as join6 } from "path";
28017
+ import { chmodSync as chmodSync4, closeSync, existsSync as existsSync9, mkdirSync as mkdirSync6, openSync, readFileSync as readFileSync7, renameSync as renameSync4, rmSync as rmSync6, writeFileSync as writeFileSync5 } from "fs";
28018
+ import { dirname as dirname5, join as join7 } from "path";
27913
28019
  function serverUpdateStatusFile(installPath, role) {
27914
- return join6(installPath, ".openmates", `${role}-update-status.json`);
28020
+ return join7(installPath, ".openmates", `${role}-update-status.json`);
27915
28021
  }
27916
28022
  function readServerUpdateStatus(installPath, role) {
27917
28023
  const filePath = serverUpdateStatusFile(installPath, role);
27918
- if (!existsSync8(filePath)) return {};
28024
+ if (!existsSync9(filePath)) return {};
27919
28025
  try {
27920
- const parsed = JSON.parse(readFileSync6(filePath, "utf-8"));
28026
+ const parsed = JSON.parse(readFileSync7(filePath, "utf-8"));
27921
28027
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
27922
28028
  return { statusReadError: "invalid_update_status" };
27923
28029
  }
@@ -27928,23 +28034,23 @@ function readServerUpdateStatus(installPath, role) {
27928
28034
  }
27929
28035
  function writeServerUpdateStatus(installPath, role, status) {
27930
28036
  const filePath = serverUpdateStatusFile(installPath, role);
27931
- mkdirSync5(dirname5(filePath), { recursive: true, mode: 448 });
28037
+ mkdirSync6(dirname5(filePath), { recursive: true, mode: 448 });
27932
28038
  const temporaryPath = `${filePath}.${process.pid}.${randomBytes7(4).toString("hex")}.tmp`;
27933
- writeFileSync4(temporaryPath, `${JSON.stringify({ role, updated_at: (/* @__PURE__ */ new Date()).toISOString(), ...status }, null, 2)}
28039
+ writeFileSync5(temporaryPath, `${JSON.stringify({ role, updated_at: (/* @__PURE__ */ new Date()).toISOString(), ...status }, null, 2)}
27934
28040
  `, { mode: 384 });
27935
- renameSync3(temporaryPath, filePath);
28041
+ renameSync4(temporaryPath, filePath);
27936
28042
  chmodSync4(filePath, 384);
27937
28043
  }
27938
28044
  function acquireServerUpdateLock(installPath) {
27939
- const stateDir2 = join6(installPath, ".openmates");
27940
- const lockPath = join6(stateDir2, "server-update.lock");
27941
- mkdirSync5(stateDir2, { recursive: true, mode: 448 });
28045
+ const stateDir2 = join7(installPath, ".openmates");
28046
+ const lockPath = join7(stateDir2, "server-update.lock");
28047
+ mkdirSync6(stateDir2, { recursive: true, mode: 448 });
27942
28048
  let descriptor;
27943
28049
  try {
27944
28050
  descriptor = openSync(lockPath, "wx", 384);
27945
28051
  } catch (error) {
27946
28052
  if (error.code !== "EEXIST") throw error;
27947
- const lockOwner = readFileSync6(lockPath, "utf8").trim();
28053
+ const lockOwner = readFileSync7(lockPath, "utf8").trim();
27948
28054
  const lockPid = Number.parseInt(lockOwner.split(":", 1)[0] ?? "", 10);
27949
28055
  let stale = false;
27950
28056
  try {
@@ -27956,11 +28062,11 @@ function acquireServerUpdateLock(installPath) {
27956
28062
  throw new Error(stale ? "A stale OpenMates server update lock exists for this installation; verify no update is running, then remove .openmates/server-update.lock explicitly." : "Another OpenMates server update is already running for this installation.");
27957
28063
  }
27958
28064
  const ownershipToken = `${process.pid}:${randomBytes7(16).toString("hex")}`;
27959
- writeFileSync4(descriptor, ownershipToken);
28065
+ writeFileSync5(descriptor, ownershipToken);
27960
28066
  return () => {
27961
28067
  closeSync(descriptor);
27962
- if (existsSync8(lockPath) && readFileSync6(lockPath, "utf8").trim() === ownershipToken) {
27963
- rmSync5(lockPath);
28068
+ if (existsSync9(lockPath) && readFileSync7(lockPath, "utf8").trim() === ownershipToken) {
28069
+ rmSync6(lockPath);
27964
28070
  }
27965
28071
  };
27966
28072
  }
@@ -28132,22 +28238,22 @@ function containsBoundedWebResult(value) {
28132
28238
  }
28133
28239
 
28134
28240
  // src/server.ts
28135
- var SOURCE_COMPOSE_FILE = join7("backend", "core", "docker-compose.yml");
28241
+ var SOURCE_COMPOSE_FILE = join8("backend", "core", "docker-compose.yml");
28136
28242
  var ROLE_IMAGE_COMPOSE_FILES = {
28137
- core: join7("backend", "core", "docker-compose.selfhost.yml"),
28138
- upload: join7("backend", "upload", "docker-compose.yml"),
28139
- preview: join7("backend", "preview", "docker-compose.preview.yml")
28243
+ core: join8("backend", "core", "docker-compose.selfhost.yml"),
28244
+ upload: join8("backend", "upload", "docker-compose.yml"),
28245
+ preview: join8("backend", "preview", "docker-compose.preview.yml")
28140
28246
  };
28141
28247
  var ROLE_TEMPLATE_FILES = {
28142
- core: join7("core", "docker-compose.selfhost.yml"),
28143
- upload: join7("upload", "docker-compose.yml"),
28144
- preview: join7("preview", "docker-compose.preview.yml")
28248
+ core: join8("core", "docker-compose.selfhost.yml"),
28249
+ upload: join8("upload", "docker-compose.yml"),
28250
+ preview: join8("preview", "docker-compose.preview.yml")
28145
28251
  };
28146
- var CORE_NO_WEBAPP_TEMPLATE_FILE = join7("core", "docker-compose.no-webapp.yml");
28147
- var CORE_PROMTAIL_CONFIG_FILE = join7("backend", "core", "monitoring", "promtail", "promtail-config.yaml");
28148
- var CORE_ALERTMANAGER_CONFIG_FILE = join7("backend", "core", "monitoring", "alertmanager", "alertmanager.yml");
28149
- var COMPOSE_OVERRIDE2 = join7("backend", "core", "docker-compose.override.yml");
28150
- var DEFAULT_INSTALL_PATH = join7(homedir6(), "openmates");
28252
+ var CORE_NO_WEBAPP_TEMPLATE_FILE = join8("core", "docker-compose.no-webapp.yml");
28253
+ var CORE_PROMTAIL_CONFIG_FILE = join8("backend", "core", "monitoring", "promtail", "promtail-config.yaml");
28254
+ var CORE_ALERTMANAGER_CONFIG_FILE = join8("backend", "core", "monitoring", "alertmanager", "alertmanager.yml");
28255
+ var COMPOSE_OVERRIDE2 = join8("backend", "core", "docker-compose.override.yml");
28256
+ var DEFAULT_INSTALL_PATH = join8(homedir6(), "openmates");
28151
28257
  var REPO_URL = "https://github.com/glowingkitty/OpenMates.git";
28152
28258
  var ROLE_PROVENANCE_SERVICE = {
28153
28259
  core: "api",
@@ -28237,8 +28343,8 @@ scrape_configs:
28237
28343
  - labels:
28238
28344
  level: log_level
28239
28345
  `;
28240
- var BACKEND_CONFIG_FILE = join7("backend", "config", "backend_config.yml");
28241
- var IMAGE_RUNTIME_CONFIG_FILE = join7("config", "backend_config.yml");
28346
+ var BACKEND_CONFIG_FILE = join8("backend", "config", "backend_config.yml");
28347
+ var IMAGE_RUNTIME_CONFIG_FILE = join8("config", "backend_config.yml");
28242
28348
  var LOCAL_AI_MODELS_FILE = "local-ai-models.yml";
28243
28349
  var OFF_BY_DEFAULT_FEATURES = /* @__PURE__ */ new Map([
28244
28350
  ["embed:code:application", "Application previews are still unstable"],
@@ -28374,9 +28480,9 @@ function runInteractive(cmd, args, cwd) {
28374
28480
  });
28375
28481
  }
28376
28482
  function beginEngineeringRuntimeOperation(installPath, operationType, services) {
28377
- const manager = join7(installPath, "scripts", "engineering_control_plane.py");
28378
- const sharedConfig = join7(homedir6(), ".config", "openmates", "engineering-control-plane.env");
28379
- if (!existsSync9(manager) || !existsSync9(sharedConfig)) return null;
28483
+ const manager = join8(installPath, "scripts", "engineering_control_plane.py");
28484
+ const sharedConfig = join8(homedir6(), ".config", "openmates", "engineering-control-plane.env");
28485
+ if (!existsSync10(manager) || !existsSync10(sharedConfig)) return null;
28380
28486
  const requestedBy = process.env.OPENCODE_SESSION_ID || `openmates-cli:${process.pid}`;
28381
28487
  const args = [
28382
28488
  manager,
@@ -28400,7 +28506,7 @@ function beginEngineeringRuntimeOperation(installPath, operationType, services)
28400
28506
  return parsed.operation_key;
28401
28507
  }
28402
28508
  function finishEngineeringRuntimeOperation(installPath, operationKey, status) {
28403
- const manager = join7(installPath, "scripts", "engineering_control_plane.py");
28509
+ const manager = join8(installPath, "scripts", "engineering_control_plane.py");
28404
28510
  execFileSync4(
28405
28511
  "python3",
28406
28512
  [manager, "operation", "update", "--operation-key", operationKey, "--status", status],
@@ -28429,8 +28535,8 @@ function loadConfigForInstallPath(installPath) {
28429
28535
  }
28430
28536
  function getInstallMode(installPath, config = loadConfigForInstallPath(installPath)) {
28431
28537
  if (config?.installMode) return config.installMode;
28432
- if (existsSync9(join7(installPath, SOURCE_COMPOSE_FILE))) return "source";
28433
- if (Object.values(ROLE_IMAGE_COMPOSE_FILES).some((composeFile) => existsSync9(join7(installPath, composeFile)))) return "image";
28538
+ if (existsSync10(join8(installPath, SOURCE_COMPOSE_FILE))) return "source";
28539
+ if (Object.values(ROLE_IMAGE_COMPOSE_FILES).some((composeFile) => existsSync10(join8(installPath, composeFile)))) return "image";
28434
28540
  return "source";
28435
28541
  }
28436
28542
  function getServerRole(flags, config) {
@@ -28561,26 +28667,26 @@ function composeArgs(installPath, withOverrides, installMode = getInstallMode(in
28561
28667
  withOverrides,
28562
28668
  installMode,
28563
28669
  role,
28564
- overrideExists: existsSync9(join7(installPath, COMPOSE_OVERRIDE2)),
28670
+ overrideExists: existsSync10(join8(installPath, COMPOSE_OVERRIDE2)),
28565
28671
  deploymentMode,
28566
28672
  overlayPath,
28567
28673
  overlayComposeFile,
28568
- overlayExists: deploymentMode === "official_cloud" && existsSync9(resolvedOverlayPath) && existsSync9(overlayComposeFile)
28674
+ overlayExists: deploymentMode === "official_cloud" && existsSync10(resolvedOverlayPath) && existsSync10(overlayComposeFile)
28569
28675
  });
28570
28676
  }
28571
28677
  function ensureGitWorkDirEnv(installPath) {
28572
- const envPath = join7(installPath, ".env");
28573
- if (!existsSync9(envPath)) return;
28574
- const content = readFileSync7(envPath, "utf-8");
28678
+ const envPath = join8(installPath, ".env");
28679
+ if (!existsSync10(envPath)) return;
28680
+ const content = readFileSync8(envPath, "utf-8");
28575
28681
  const lineRegex = /^GIT_WORK_DIR=.*$/m;
28576
28682
  const value = `GIT_WORK_DIR=${installPath}`;
28577
28683
  if (lineRegex.test(content)) {
28578
28684
  const next = content.replace(lineRegex, value);
28579
- if (next !== content) writeFileSync5(envPath, next);
28685
+ if (next !== content) writeFileSync6(envPath, next);
28580
28686
  return;
28581
28687
  }
28582
28688
  const separator2 = content.endsWith("\n") ? "" : "\n";
28583
- writeFileSync5(envPath, `${content}${separator2}${value}
28689
+ writeFileSync6(envPath, `${content}${separator2}${value}
28584
28690
  `);
28585
28691
  }
28586
28692
  function requireDocker() {
@@ -28601,7 +28707,7 @@ function requireGit() {
28601
28707
  }
28602
28708
  function getPackageVersion() {
28603
28709
  try {
28604
- const packageJson = JSON.parse(readFileSync7(new URL("../package.json", import.meta.url), "utf-8"));
28710
+ const packageJson = JSON.parse(readFileSync8(new URL("../package.json", import.meta.url), "utf-8"));
28605
28711
  return packageJson.version ?? "";
28606
28712
  } catch {
28607
28713
  return "";
@@ -28694,20 +28800,20 @@ async function fetchText(url) {
28694
28800
  return response.text();
28695
28801
  }
28696
28802
  function packagedTemplatePath(role) {
28697
- return join7(dirname6(new URL(import.meta.url).pathname), "..", "templates", ROLE_TEMPLATE_FILES[role]);
28803
+ return join8(dirname6(new URL(import.meta.url).pathname), "..", "templates", ROLE_TEMPLATE_FILES[role]);
28698
28804
  }
28699
28805
  function packagedNoWebappTemplatePath() {
28700
- return join7(dirname6(new URL(import.meta.url).pathname), "..", "templates", CORE_NO_WEBAPP_TEMPLATE_FILE);
28806
+ return join8(dirname6(new URL(import.meta.url).pathname), "..", "templates", CORE_NO_WEBAPP_TEMPLATE_FILE);
28701
28807
  }
28702
28808
  function packagedCaddyTemplatePath(role) {
28703
- return join7(dirname6(new URL(import.meta.url).pathname), "..", "templates", "caddy", role, "Caddyfile");
28809
+ return join8(dirname6(new URL(import.meta.url).pathname), "..", "templates", "caddy", role, "Caddyfile");
28704
28810
  }
28705
28811
  function packagedCoreAlertmanagerTemplatePath() {
28706
- return join7(dirname6(new URL(import.meta.url).pathname), "..", "templates", "core", "monitoring", "alertmanager", "alertmanager.yml");
28812
+ return join8(dirname6(new URL(import.meta.url).pathname), "..", "templates", "core", "monitoring", "alertmanager", "alertmanager.yml");
28707
28813
  }
28708
28814
  function readOfficialCloudNoWebappComposeTemplate() {
28709
28815
  const packaged = packagedNoWebappTemplatePath();
28710
- if (existsSync9(packaged)) return readFileSync7(packaged, "utf-8");
28816
+ if (existsSync10(packaged)) return readFileSync8(packaged, "utf-8");
28711
28817
  return [
28712
28818
  "# backend/core/docker-compose.no-webapp.yml",
28713
28819
  "#",
@@ -28722,51 +28828,51 @@ function readOfficialCloudNoWebappComposeTemplate() {
28722
28828
  }
28723
28829
  function ensureOfficialCloudNoWebappComposeFile(installPath, deploymentMode, role) {
28724
28830
  if (deploymentMode !== "official_cloud" || role !== "core") return;
28725
- const filePath = join7(installPath, OFFICIAL_CLOUD_NO_WEBAPP_COMPOSE_FILE);
28726
- if (existsSync9(filePath)) return;
28727
- mkdirSync6(dirname6(filePath), { recursive: true });
28728
- writeFileSync5(filePath, readOfficialCloudNoWebappComposeTemplate());
28831
+ const filePath = join8(installPath, OFFICIAL_CLOUD_NO_WEBAPP_COMPOSE_FILE);
28832
+ if (existsSync10(filePath)) return;
28833
+ mkdirSync7(dirname6(filePath), { recursive: true });
28834
+ writeFileSync6(filePath, readOfficialCloudNoWebappComposeTemplate());
28729
28835
  }
28730
28836
  function fileHash(path2) {
28731
- if (!existsSync9(path2)) return null;
28732
- return createHash12("sha256").update(readFileSync7(path2)).digest("hex");
28837
+ if (!existsSync10(path2)) return null;
28838
+ return createHash13("sha256").update(readFileSync8(path2)).digest("hex");
28733
28839
  }
28734
28840
  async function loadSelfHostComposeTemplate(templateRef, role) {
28735
28841
  const templateDir = process.env.OPENMATES_SELFHOST_TEMPLATE_DIR;
28736
28842
  if (templateDir) {
28737
- return readFileSync7(join7(resolve6(templateDir), ROLE_TEMPLATE_FILES[role]), "utf-8");
28843
+ return readFileSync8(join8(resolve6(templateDir), ROLE_TEMPLATE_FILES[role]), "utf-8");
28738
28844
  }
28739
28845
  const overrideUrl = process.env.OPENMATES_SELFHOST_COMPOSE_URL;
28740
28846
  if (overrideUrl) {
28741
28847
  return fetchText(overrideUrl);
28742
28848
  }
28743
28849
  const packaged = packagedTemplatePath(role);
28744
- if (existsSync9(packaged)) return readFileSync7(packaged, "utf-8");
28850
+ if (existsSync10(packaged)) return readFileSync8(packaged, "utf-8");
28745
28851
  return fetchText(`https://raw.githubusercontent.com/glowingkitty/OpenMates/${templateRef}/${ROLE_IMAGE_COMPOSE_FILES[role]}`);
28746
28852
  }
28747
28853
  async function writeImageModeRuntimeFiles(installPath, imageTag, role) {
28748
- const roleDir = join7(installPath, "backend", role === "core" ? "core" : role);
28749
- const vaultConfigDir = join7(roleDir, "vault", "config");
28750
- mkdirSync6(vaultConfigDir, { recursive: true });
28751
- mkdirSync6(join7(installPath, "config", "providers"), { recursive: true });
28752
- writeFileSync5(join7(installPath, ROLE_IMAGE_COMPOSE_FILES[role]), await loadSelfHostComposeTemplate(templateRefForImageTag(imageTag, getPackageVersion()), role));
28854
+ const roleDir = join8(installPath, "backend", role === "core" ? "core" : role);
28855
+ const vaultConfigDir = join8(roleDir, "vault", "config");
28856
+ mkdirSync7(vaultConfigDir, { recursive: true });
28857
+ mkdirSync7(join8(installPath, "config", "providers"), { recursive: true });
28858
+ writeFileSync6(join8(installPath, ROLE_IMAGE_COMPOSE_FILES[role]), await loadSelfHostComposeTemplate(templateRefForImageTag(imageTag, getPackageVersion()), role));
28753
28859
  if (role === "core") {
28754
- writeFileSync5(join7(installPath, OFFICIAL_CLOUD_NO_WEBAPP_COMPOSE_FILE), readOfficialCloudNoWebappComposeTemplate());
28860
+ writeFileSync6(join8(installPath, OFFICIAL_CLOUD_NO_WEBAPP_COMPOSE_FILE), readOfficialCloudNoWebappComposeTemplate());
28755
28861
  }
28756
28862
  if (role === "core") {
28757
- const promtailConfigPath = join7(installPath, CORE_PROMTAIL_CONFIG_FILE);
28758
- mkdirSync6(dirname6(promtailConfigPath), { recursive: true });
28759
- writeFileSync5(promtailConfigPath, SELFHOST_PROMTAIL_CONFIG_TEMPLATE);
28863
+ const promtailConfigPath = join8(installPath, CORE_PROMTAIL_CONFIG_FILE);
28864
+ mkdirSync7(dirname6(promtailConfigPath), { recursive: true });
28865
+ writeFileSync6(promtailConfigPath, SELFHOST_PROMTAIL_CONFIG_TEMPLATE);
28760
28866
  const alertmanagerTemplatePath = packagedCoreAlertmanagerTemplatePath();
28761
- if (!existsSync9(alertmanagerTemplatePath)) throw new Error(`Packaged Alertmanager config not found: ${alertmanagerTemplatePath}`);
28762
- const alertmanagerConfigPath = join7(installPath, CORE_ALERTMANAGER_CONFIG_FILE);
28763
- mkdirSync6(dirname6(alertmanagerConfigPath), { recursive: true });
28867
+ if (!existsSync10(alertmanagerTemplatePath)) throw new Error(`Packaged Alertmanager config not found: ${alertmanagerTemplatePath}`);
28868
+ const alertmanagerConfigPath = join8(installPath, CORE_ALERTMANAGER_CONFIG_FILE);
28869
+ mkdirSync7(dirname6(alertmanagerConfigPath), { recursive: true });
28764
28870
  copyFileSync2(alertmanagerTemplatePath, alertmanagerConfigPath);
28765
28871
  }
28766
- writeFileSync5(join7(vaultConfigDir, "vault.hcl"), VAULT_CONFIG_TEMPLATE);
28872
+ writeFileSync6(join8(vaultConfigDir, "vault.hcl"), VAULT_CONFIG_TEMPLATE);
28767
28873
  ensureImageRuntimeConfig(installPath);
28768
- const envPath = join7(installPath, ".env");
28769
- let envContent = existsSync9(envPath) ? readFileSync7(envPath, "utf-8") : MINIMAL_ENV_TEMPLATE;
28874
+ const envPath = join8(installPath, ".env");
28875
+ let envContent = existsSync10(envPath) ? readFileSync8(envPath, "utf-8") : MINIMAL_ENV_TEMPLATE;
28770
28876
  envContent = setEnvIfEmpty(envContent, "DATABASE_ADMIN_PASSWORD", randomHex(12));
28771
28877
  envContent = setEnvIfEmpty(envContent, "DATABASE_PASSWORD", randomHex(12));
28772
28878
  envContent = setEnvIfEmpty(envContent, "DIRECTUS_TOKEN", randomHex(32));
@@ -28778,13 +28884,13 @@ async function writeImageModeRuntimeFiles(installPath, imageTag, role) {
28778
28884
  envContent = setEnvVar(envContent, "OPENMATES_IMAGE_TAG", imageTag);
28779
28885
  envContent = setEnvVar(envContent, "OPENMATES_IMAGE_REGISTRY", DEFAULT_IMAGE_REGISTRY);
28780
28886
  envContent = setEnvVar(envContent, "GIT_WORK_DIR", installPath);
28781
- writeFileSync5(envPath, envContent.endsWith("\n") ? envContent : `${envContent}
28887
+ writeFileSync6(envPath, envContent.endsWith("\n") ? envContent : `${envContent}
28782
28888
  `);
28783
28889
  }
28784
28890
  function getImageTagFromEnv(installPath, config) {
28785
- const envPath = join7(installPath, ".env");
28786
- if (existsSync9(envPath)) {
28787
- const envTag = getEnvVar(readFileSync7(envPath, "utf-8"), "OPENMATES_IMAGE_TAG");
28891
+ const envPath = join8(installPath, ".env");
28892
+ if (existsSync10(envPath)) {
28893
+ const envTag = getEnvVar(readFileSync8(envPath, "utf-8"), "OPENMATES_IMAGE_TAG");
28788
28894
  if (envTag) return envTag;
28789
28895
  }
28790
28896
  return config?.imageTag ?? "";
@@ -28817,8 +28923,8 @@ async function waitForServerHealth(installPath, role = "core", options = {}) {
28817
28923
  }
28818
28924
  throw new Error(`Updated ${role} server did not pass health checks in time. Tried ${healthUrl}.`);
28819
28925
  }
28820
- const envPath = join7(installPath, ".env");
28821
- const envContent = existsSync9(envPath) ? readFileSync7(envPath, "utf-8") : "";
28926
+ const envPath = join8(installPath, ".env");
28927
+ const envContent = existsSync10(envPath) ? readFileSync8(envPath, "utf-8") : "";
28822
28928
  const urls = deriveSelfHostCliUrls(envContent);
28823
28929
  const apiHealthUrl = `${trailingSlashTrimmed(urls.apiUrl)}/health`;
28824
28930
  const appUrl = trailingSlashTrimmed(urls.appUrl);
@@ -28841,9 +28947,9 @@ function defaultCloneBranchForVersion(version) {
28841
28947
  return /-(alpha|beta|rc)(\.|\d|$)/.test(version) ? DEV_BRANCH : null;
28842
28948
  }
28843
28949
  function hasLlmCredentials(envPath) {
28844
- if (!existsSync9(envPath)) return false;
28950
+ if (!existsSync10(envPath)) return false;
28845
28951
  if (hasLocalAiModels(dirname6(envPath))) return true;
28846
- const content = readFileSync7(envPath, "utf-8");
28952
+ const content = readFileSync8(envPath, "utf-8");
28847
28953
  for (const line of content.split("\n")) {
28848
28954
  const trimmed = line.trim();
28849
28955
  if (trimmed.startsWith("#") || !trimmed) continue;
@@ -28858,8 +28964,8 @@ function hasLlmCredentials(envPath) {
28858
28964
  return false;
28859
28965
  }
28860
28966
  function warnIfMissingLlmCredentials(installPath) {
28861
- const envPath = join7(installPath, ".env");
28862
- if (!existsSync9(envPath)) {
28967
+ const envPath = join8(installPath, ".env");
28968
+ if (!existsSync10(envPath)) {
28863
28969
  console.error(
28864
28970
  "No .env file found. Run 'openmates server install' first, or create .env from .env.example."
28865
28971
  );
@@ -28884,22 +28990,22 @@ function printJson(data) {
28884
28990
  console.log(JSON.stringify(data, null, 2));
28885
28991
  }
28886
28992
  function localModelsOverlayPath(installPath, installMode = getInstallMode(installPath)) {
28887
- if (installMode === "source") return join7(installPath, "backend", "providers", LOCAL_AI_MODELS_FILE);
28888
- return join7(installPath, "config", "providers", LOCAL_AI_MODELS_FILE);
28993
+ if (installMode === "source") return join8(installPath, "backend", "providers", LOCAL_AI_MODELS_FILE);
28994
+ return join8(installPath, "config", "providers", LOCAL_AI_MODELS_FILE);
28889
28995
  }
28890
28996
  function imageBackendConfigPath(installPath) {
28891
- return join7(installPath, IMAGE_RUNTIME_CONFIG_FILE);
28997
+ return join8(installPath, IMAGE_RUNTIME_CONFIG_FILE);
28892
28998
  }
28893
28999
  function ensureImageRuntimeConfig(installPath) {
28894
29000
  const configPath = imageBackendConfigPath(installPath);
28895
- if (existsSync9(configPath)) return;
28896
- mkdirSync6(dirname6(configPath), { recursive: true });
28897
- writeFileSync5(configPath, renderFeatureOverrides({ enabled: [], disabled: [] }));
29001
+ if (existsSync10(configPath)) return;
29002
+ mkdirSync7(dirname6(configPath), { recursive: true });
29003
+ writeFileSync6(configPath, renderFeatureOverrides({ enabled: [], disabled: [] }));
28898
29004
  }
28899
29005
  function readLocalModelOverlay(path2) {
28900
- if (!existsSync9(path2)) return { providers: [] };
29006
+ if (!existsSync10(path2)) return { providers: [] };
28901
29007
  try {
28902
- const parsed = JSON.parse(readFileSync7(path2, "utf-8"));
29008
+ const parsed = JSON.parse(readFileSync8(path2, "utf-8"));
28903
29009
  return { providers: Array.isArray(parsed.providers) ? parsed.providers : [] };
28904
29010
  } catch (error) {
28905
29011
  throw new Error(
@@ -28908,15 +29014,15 @@ function readLocalModelOverlay(path2) {
28908
29014
  }
28909
29015
  }
28910
29016
  function writeLocalModelOverlay(path2, overlay) {
28911
- mkdirSync6(dirname6(path2), { recursive: true });
28912
- writeFileSync5(path2, `${JSON.stringify(overlay, null, 2)}
29017
+ mkdirSync7(dirname6(path2), { recursive: true });
29018
+ writeFileSync6(path2, `${JSON.stringify(overlay, null, 2)}
28913
29019
  `);
28914
29020
  }
28915
29021
  function hasLocalAiModels(installPath) {
28916
- const imagePath = join7(installPath, "config", "providers", LOCAL_AI_MODELS_FILE);
28917
- const sourcePath = join7(installPath, "backend", "providers", LOCAL_AI_MODELS_FILE);
29022
+ const imagePath = join8(installPath, "config", "providers", LOCAL_AI_MODELS_FILE);
29023
+ const sourcePath = join8(installPath, "backend", "providers", LOCAL_AI_MODELS_FILE);
28918
29024
  return [imagePath, sourcePath].some((path2) => {
28919
- if (!existsSync9(path2)) return false;
29025
+ if (!existsSync10(path2)) return false;
28920
29026
  try {
28921
29027
  return readLocalModelOverlay(path2).providers.some((provider) => provider.models.length > 0);
28922
29028
  } catch {
@@ -28957,10 +29063,10 @@ function nowStamp() {
28957
29063
  return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
28958
29064
  }
28959
29065
  function backupRoot(installPath) {
28960
- return join7(installPath, "backups");
29066
+ return join8(installPath, "backups");
28961
29067
  }
28962
29068
  function roleBackupDir(installPath, role) {
28963
- return join7(backupRoot(installPath), role);
29069
+ return join8(backupRoot(installPath), role);
28964
29070
  }
28965
29071
  function persistQuickServerTestOutcome(installPath, role, outcome) {
28966
29072
  const current = readServerUpdateStatus(installPath, role);
@@ -29109,15 +29215,15 @@ function sourceUpdateMetadata(installPath) {
29109
29215
  };
29110
29216
  }
29111
29217
  function copyIfExists(source, destination) {
29112
- if (!existsSync9(source)) return;
29113
- mkdirSync6(dirname6(destination), { recursive: true });
29218
+ if (!existsSync10(source)) return;
29219
+ mkdirSync7(dirname6(destination), { recursive: true });
29114
29220
  cpSync(source, destination, { recursive: true, force: true });
29115
29221
  }
29116
29222
  function readEnvMap(installPath) {
29117
- const envPath = join7(installPath, ".env");
29118
- if (!existsSync9(envPath)) return {};
29223
+ const envPath = join8(installPath, ".env");
29224
+ if (!existsSync10(envPath)) return {};
29119
29225
  const values = {};
29120
- for (const line of readFileSync7(envPath, "utf-8").split("\n")) {
29226
+ for (const line of readFileSync8(envPath, "utf-8").split("\n")) {
29121
29227
  const trimmed = line.trim();
29122
29228
  if (!trimmed || trimmed.startsWith("#")) continue;
29123
29229
  const eqIdx = trimmed.indexOf("=");
@@ -29127,22 +29233,22 @@ function readEnvMap(installPath) {
29127
29233
  return values;
29128
29234
  }
29129
29235
  function envPathForInstall(installPath) {
29130
- return join7(installPath, ".env");
29236
+ return join8(installPath, ".env");
29131
29237
  }
29132
29238
  function readEnvContent(installPath) {
29133
29239
  const envPath = envPathForInstall(installPath);
29134
- return existsSync9(envPath) ? readFileSync7(envPath, "utf-8") : "";
29240
+ return existsSync10(envPath) ? readFileSync8(envPath, "utf-8") : "";
29135
29241
  }
29136
29242
  function pruneEnvBackups(installPath) {
29137
- const backups = readdirSync4(installPath, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.startsWith(ENV_BACKUP_PREFIX)).map((entry) => entry.name).sort();
29243
+ const backups = readdirSync5(installPath, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.startsWith(ENV_BACKUP_PREFIX)).map((entry) => entry.name).sort();
29138
29244
  for (const backup of backups.slice(0, Math.max(0, backups.length - ENV_BACKUP_RETENTION_COUNT))) {
29139
- rmSync6(join7(installPath, backup), { force: true });
29245
+ rmSync7(join8(installPath, backup), { force: true });
29140
29246
  }
29141
29247
  }
29142
29248
  function backupEnvFile(installPath) {
29143
29249
  const envPath = envPathForInstall(installPath);
29144
- if (!existsSync9(envPath)) return null;
29145
- const backupPath = join7(installPath, `${ENV_BACKUP_PREFIX}${nowStamp()}`);
29250
+ if (!existsSync10(envPath)) return null;
29251
+ const backupPath = join8(installPath, `${ENV_BACKUP_PREFIX}${nowStamp()}`);
29146
29252
  copyFileSync2(envPath, backupPath);
29147
29253
  chmodSync5(backupPath, 384);
29148
29254
  pruneEnvBackups(installPath);
@@ -29150,8 +29256,8 @@ function backupEnvFile(installPath) {
29150
29256
  }
29151
29257
  function writeEnvContent(installPath, content) {
29152
29258
  const envPath = envPathForInstall(installPath);
29153
- mkdirSync6(dirname6(envPath), { recursive: true });
29154
- writeFileSync5(envPath, content, { mode: 384 });
29259
+ mkdirSync7(dirname6(envPath), { recursive: true });
29260
+ writeFileSync6(envPath, content, { mode: 384 });
29155
29261
  chmodSync5(envPath, 384);
29156
29262
  }
29157
29263
  function writeDeploymentModeEnv(installPath, deploymentMode, overlayPath) {
@@ -29166,7 +29272,7 @@ function writeDeploymentModeEnv(installPath, deploymentMode, overlayPath) {
29166
29272
  }
29167
29273
  const resolvedOverlayPath = resolve6(overlayPath ?? defaultOpenMatesCloudOverlayPath(installPath));
29168
29274
  const overlayComposeFile = defaultOpenMatesCloudComposeFile(resolvedOverlayPath);
29169
- if (!existsSync9(resolvedOverlayPath) || !existsSync9(overlayComposeFile)) {
29275
+ if (!existsSync10(resolvedOverlayPath) || !existsSync10(overlayComposeFile)) {
29170
29276
  throw new Error(
29171
29277
  `OpenMatesCloud official-cloud mode requires an overlay checkout with ${overlayComposeFile}. Pass --openmatescloud-path <dir> or create the sibling OpenMatesCloud repository.`
29172
29278
  );
@@ -29363,7 +29469,7 @@ function formatSecretPreflight(preflight) {
29363
29469
  return parts.join("; ");
29364
29470
  }
29365
29471
  function hashFile(path2) {
29366
- const hash = createHash12("sha256");
29472
+ const hash = createHash13("sha256");
29367
29473
  const fd = openSync2(path2, "r");
29368
29474
  const buffer = Buffer.allocUnsafe(CHECKSUM_BUFFER_BYTES);
29369
29475
  try {
@@ -29380,8 +29486,8 @@ function hashFile(path2) {
29380
29486
  function writeChecksums(rootDir) {
29381
29487
  const lines = [];
29382
29488
  const walk = (dir) => {
29383
- for (const entry of readdirSync4(dir, { withFileTypes: true })) {
29384
- const path2 = join7(dir, entry.name);
29489
+ for (const entry of readdirSync5(dir, { withFileTypes: true })) {
29490
+ const path2 = join8(dir, entry.name);
29385
29491
  if (entry.isDirectory()) {
29386
29492
  walk(path2);
29387
29493
  continue;
@@ -29392,13 +29498,13 @@ function writeChecksums(rootDir) {
29392
29498
  }
29393
29499
  };
29394
29500
  walk(rootDir);
29395
- writeFileSync5(join7(rootDir, "checksums.sha256"), `${lines.sort().join("\n")}
29501
+ writeFileSync6(join8(rootDir, "checksums.sha256"), `${lines.sort().join("\n")}
29396
29502
  `);
29397
29503
  }
29398
29504
  function verifyChecksums(rootDir) {
29399
- const checksumsPath = join7(rootDir, "checksums.sha256");
29400
- if (!existsSync9(checksumsPath)) throw new Error("Backup archive is missing checksums.sha256.");
29401
- for (const line of readFileSync7(checksumsPath, "utf-8").split("\n")) {
29505
+ const checksumsPath = join8(rootDir, "checksums.sha256");
29506
+ if (!existsSync10(checksumsPath)) throw new Error("Backup archive is missing checksums.sha256.");
29507
+ for (const line of readFileSync8(checksumsPath, "utf-8").split("\n")) {
29402
29508
  const trimmed = line.trim();
29403
29509
  if (!trimmed) continue;
29404
29510
  const match = trimmed.match(/^([a-f0-9]{64}) {2}(.+)$/);
@@ -29407,8 +29513,8 @@ function verifyChecksums(rootDir) {
29407
29513
  if (relative3.startsWith("/") || relative3.split(/[\\/]/).includes("..")) {
29408
29514
  throw new Error(`Unsafe checksum path in backup archive: ${relative3}`);
29409
29515
  }
29410
- const filePath = join7(rootDir, relative3);
29411
- if (!existsSync9(filePath)) throw new Error(`Backup archive is missing checksummed file: ${relative3}`);
29516
+ const filePath = join8(rootDir, relative3);
29517
+ if (!existsSync10(filePath)) throw new Error(`Backup archive is missing checksummed file: ${relative3}`);
29412
29518
  const actual = hashFile(filePath);
29413
29519
  if (actual !== match[1]) throw new Error(`Backup checksum mismatch for ${relative3}.`);
29414
29520
  }
@@ -29416,28 +29522,28 @@ function verifyChecksums(rootDir) {
29416
29522
  function createServerBackup(installPath, role, options = {}) {
29417
29523
  const plan = planBackup({ role, includeObservability: options.includeObservability });
29418
29524
  const backupDir = roleBackupDir(installPath, role);
29419
- mkdirSync6(backupDir, { recursive: true, mode: 448 });
29420
- const archivePath = options.output ? resolve6(options.output) : join7(backupDir, options.preUpdate ? `latest-pre-update-${role}.tar.gz` : `openmates-${role}-${nowStamp()}.tar.gz`);
29421
- mkdirSync6(dirname6(archivePath), { recursive: true, mode: 448 });
29422
- const tempDir = mkdtempSync(join7(backupDir, ".tmp-"));
29525
+ mkdirSync7(backupDir, { recursive: true, mode: 448 });
29526
+ const archivePath = options.output ? resolve6(options.output) : join8(backupDir, options.preUpdate ? `latest-pre-update-${role}.tar.gz` : `openmates-${role}-${nowStamp()}.tar.gz`);
29527
+ mkdirSync7(dirname6(archivePath), { recursive: true, mode: 448 });
29528
+ const tempDir = mkdtempSync(join8(backupDir, ".tmp-"));
29423
29529
  const env = readEnvMap(installPath);
29424
29530
  const manifest = {
29425
29531
  role,
29426
29532
  backup_format_version: BACKUP_FORMAT_VERSION,
29427
29533
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
29428
29534
  cli_version: getPackageVersion(),
29429
- image_tag: getEnvVar(existsSync9(join7(installPath, ".env")) ? readFileSync7(join7(installPath, ".env"), "utf-8") : "", "OPENMATES_IMAGE_TAG"),
29535
+ image_tag: getEnvVar(existsSync10(join8(installPath, ".env")) ? readFileSync8(join8(installPath, ".env"), "utf-8") : "", "OPENMATES_IMAGE_TAG"),
29430
29536
  recovery_scope: role === "core" ? "database-and-runtime-only" : "runtime-only",
29431
29537
  include_observability: false,
29432
- contents: plan.contents.filter((content) => content !== "runtime-env" || existsSync9(join7(installPath, ".env"))).filter((content) => content !== "runtime-config" || existsSync9(join7(installPath, "config")))
29538
+ contents: plan.contents.filter((content) => content !== "runtime-env" || existsSync10(join8(installPath, ".env"))).filter((content) => content !== "runtime-config" || existsSync10(join8(installPath, "config")))
29433
29539
  };
29434
29540
  try {
29435
- copyIfExists(join7(installPath, ".env"), join7(tempDir, "runtime", ".env"));
29436
- copyIfExists(join7(installPath, "config"), join7(tempDir, "runtime", "config"));
29541
+ copyIfExists(join8(installPath, ".env"), join8(tempDir, "runtime", ".env"));
29542
+ copyIfExists(join8(installPath, "config"), join8(tempDir, "runtime", "config"));
29437
29543
  if (role === "core") {
29438
29544
  const databaseUser = env.DATABASE_USERNAME || "directus";
29439
29545
  const databaseName = env.DATABASE_NAME || "directus";
29440
- const dumpFile = openSync2(join7(tempDir, "postgres.sql"), "w");
29546
+ const dumpFile = openSync2(join8(tempDir, "postgres.sql"), "w");
29441
29547
  try {
29442
29548
  const result = spawnSync(
29443
29549
  "docker",
@@ -29452,35 +29558,35 @@ function createServerBackup(installPath, role, options = {}) {
29452
29558
  closeSync2(dumpFile);
29453
29559
  }
29454
29560
  }
29455
- writeFileSync5(join7(tempDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
29561
+ writeFileSync6(join8(tempDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
29456
29562
  `, { mode: 384 });
29457
29563
  writeChecksums(tempDir);
29458
29564
  publishServerBackupArchive(tempDir, archivePath);
29459
29565
  return archivePath;
29460
29566
  } finally {
29461
- rmSync6(tempDir, { recursive: true, force: true });
29567
+ rmSync7(tempDir, { recursive: true, force: true });
29462
29568
  }
29463
29569
  }
29464
29570
  function restoreServerBackup(installPath, role, file) {
29465
29571
  const archivePath = resolve6(file);
29466
- if (!existsSync9(archivePath)) throw new Error(`Backup file not found: ${archivePath}`);
29467
- mkdirSync6(roleBackupDir(installPath, role), { recursive: true, mode: 448 });
29468
- const tempDir = mkdtempSync(join7(roleBackupDir(installPath, role), ".restore-"));
29572
+ if (!existsSync10(archivePath)) throw new Error(`Backup file not found: ${archivePath}`);
29573
+ mkdirSync7(roleBackupDir(installPath, role), { recursive: true, mode: 448 });
29574
+ const tempDir = mkdtempSync(join8(roleBackupDir(installPath, role), ".restore-"));
29469
29575
  const env = readEnvMap(installPath);
29470
29576
  try {
29471
29577
  execSync(`tar -xzf ${shellQuote(archivePath)} -C ${shellQuote(tempDir)}`, { stdio: "pipe" });
29472
29578
  verifyChecksums(tempDir);
29473
- const manifestPath = join7(tempDir, "manifest.json");
29474
- if (!existsSync9(manifestPath)) throw new Error("Backup archive is missing manifest.json.");
29475
- const manifest = JSON.parse(readFileSync7(manifestPath, "utf-8"));
29579
+ const manifestPath = join8(tempDir, "manifest.json");
29580
+ if (!existsSync10(manifestPath)) throw new Error("Backup archive is missing manifest.json.");
29581
+ const manifest = JSON.parse(readFileSync8(manifestPath, "utf-8"));
29476
29582
  if (manifest.role !== role) throw new Error(`Backup role '${manifest.role}' does not match requested role '${role}'.`);
29477
29583
  if (role === "core" && manifest.backup_format_version === BACKUP_FORMAT_VERSION && manifest.recovery_scope !== "full-core") {
29478
29584
  throw new Error("This backup records database and runtime state only; refusing unsafe full core restore.");
29479
29585
  }
29480
- copyIfExists(join7(tempDir, "runtime", ".env"), join7(installPath, ".env"));
29481
- copyIfExists(join7(tempDir, "runtime", "config"), join7(installPath, "config"));
29482
- const postgresDump = join7(tempDir, "postgres.sql");
29483
- if (role === "core" && existsSync9(postgresDump)) {
29586
+ copyIfExists(join8(tempDir, "runtime", ".env"), join8(installPath, ".env"));
29587
+ copyIfExists(join8(tempDir, "runtime", "config"), join8(installPath, "config"));
29588
+ const postgresDump = join8(tempDir, "postgres.sql");
29589
+ if (role === "core" && existsSync10(postgresDump)) {
29484
29590
  const databaseUser = env.DATABASE_USERNAME || "directus";
29485
29591
  const databaseName = env.DATABASE_NAME || "directus";
29486
29592
  const dumpFile = openSync2(postgresDump, "r");
@@ -29497,7 +29603,7 @@ function restoreServerBackup(installPath, role, file) {
29497
29603
  }
29498
29604
  }
29499
29605
  } finally {
29500
- rmSync6(tempDir, { recursive: true, force: true });
29606
+ rmSync7(tempDir, { recursive: true, force: true });
29501
29607
  }
29502
29608
  }
29503
29609
  function restoreStopServices(installPath, withOverrides, installMode, role) {
@@ -29766,11 +29872,11 @@ async function serverRegister(flags) {
29766
29872
  const installPath = resolveServerPath(
29767
29873
  typeof flags.path === "string" ? flags : { ...flags, path: process.cwd() }
29768
29874
  );
29769
- const envPath = join7(installPath, ".env");
29770
- if (!existsSync9(join7(installPath, SOURCE_COMPOSE_FILE))) {
29771
- throw new Error(`Source Compose file not found: ${join7(installPath, SOURCE_COMPOSE_FILE)}`);
29875
+ const envPath = join8(installPath, ".env");
29876
+ if (!existsSync10(join8(installPath, SOURCE_COMPOSE_FILE))) {
29877
+ throw new Error(`Source Compose file not found: ${join8(installPath, SOURCE_COMPOSE_FILE)}`);
29772
29878
  }
29773
- if (!existsSync9(envPath)) {
29879
+ if (!existsSync10(envPath)) {
29774
29880
  throw new Error(`Runtime env file not found: ${envPath}`);
29775
29881
  }
29776
29882
  const gitRoot = resolve6(exec("git rev-parse --show-toplevel", installPath));
@@ -29792,7 +29898,7 @@ async function serverRegister(flags) {
29792
29898
  }
29793
29899
  const overlayPath = getOpenMatesCloudOverlayPath(flags, null) ?? readEnvMap(installPath).OPENMATES_CLOUD_OVERLAY_PATH ?? defaultOpenMatesCloudOverlayPath(installPath);
29794
29900
  const overlayComposeFile = defaultOpenMatesCloudComposeFile(overlayPath);
29795
- if (deploymentMode === "official_cloud" && (!existsSync9(overlayPath) || !existsSync9(overlayComposeFile))) {
29901
+ if (deploymentMode === "official_cloud" && (!existsSync10(overlayPath) || !existsSync10(overlayComposeFile))) {
29796
29902
  throw new Error(`OpenMatesCloud overlay path is required for official-cloud mode: ${overlayPath}`);
29797
29903
  }
29798
29904
  const runtimePlan = planServerRuntime({
@@ -29802,7 +29908,7 @@ async function serverRegister(flags) {
29802
29908
  includeWebapp: deploymentMode !== "official_cloud"
29803
29909
  });
29804
29910
  const defaultServices = hasServiceFilter(flags) ? selectedComposeServices(role, flags) : runtimePlan.defaultServices;
29805
- const cliUrls = deriveSelfHostCliUrls(readFileSync7(envPath, "utf-8"));
29911
+ const cliUrls = deriveSelfHostCliUrls(readFileSync8(envPath, "utf-8"));
29806
29912
  const config = {
29807
29913
  installPath,
29808
29914
  installedAt: existing?.installPath === installPath ? existing.installedAt : Date.now(),
@@ -29844,27 +29950,27 @@ async function serverInstall(flags) {
29844
29950
  withAlerts: flags["with-alerts"] === true,
29845
29951
  includeWebapp: deploymentMode !== "official_cloud"
29846
29952
  });
29847
- if (existsSync9(join7(installPath, SOURCE_COMPOSE_FILE)) || Object.values(ROLE_IMAGE_COMPOSE_FILES).some((composeFile) => existsSync9(join7(installPath, composeFile)))) {
29953
+ if (existsSync10(join8(installPath, SOURCE_COMPOSE_FILE)) || Object.values(ROLE_IMAGE_COMPOSE_FILES).some((composeFile) => existsSync10(join8(installPath, composeFile)))) {
29848
29954
  console.error(`OpenMates already exists at ${installPath}.`);
29849
29955
  console.error("Use 'openmates server update' to update, or choose a different --path.");
29850
29956
  process.exit(1);
29851
29957
  }
29852
29958
  if (!fromSource) {
29853
29959
  requireDocker();
29854
- mkdirSync6(installPath, { recursive: true });
29960
+ mkdirSync7(installPath, { recursive: true });
29855
29961
  if (typeof flags["env-path"] === "string") {
29856
29962
  const envSource = resolve6(flags["env-path"]);
29857
- if (!existsSync9(envSource)) {
29963
+ if (!existsSync10(envSource)) {
29858
29964
  throw new Error(`Env file not found: ${envSource}`);
29859
29965
  }
29860
- copyFileSync2(envSource, join7(installPath, ".env"));
29966
+ copyFileSync2(envSource, join8(installPath, ".env"));
29861
29967
  console.error(`Copied ${envSource} to ${installPath}/.env`);
29862
29968
  }
29863
29969
  const imageTag = typeof flags["image-tag"] === "string" ? flags["image-tag"] : getDefaultImageTag();
29864
29970
  console.error(`Preparing OpenMates image-mode install at ${installPath}...`);
29865
29971
  await writeImageModeRuntimeFiles(installPath, imageTag, role);
29866
29972
  const overlay2 = writeDeploymentModeEnv(installPath, deploymentMode, requestedOverlayPath);
29867
- const cliUrls2 = deriveSelfHostCliUrls(readFileSync7(join7(installPath, ".env"), "utf-8"));
29973
+ const cliUrls2 = deriveSelfHostCliUrls(readFileSync8(join8(installPath, ".env"), "utf-8"));
29868
29974
  try {
29869
29975
  exec("docker network create openmates", installPath);
29870
29976
  } catch {
@@ -29891,7 +29997,7 @@ async function serverInstall(flags) {
29891
29997
  if (flags.json === true) {
29892
29998
  printJson({ command: "install", status: "success", path: installPath, mode: "image", imageTag });
29893
29999
  } else {
29894
- const firstInvite = getEnvVar(readFileSync7(join7(installPath, ".env"), "utf-8"), "SELF_HOST_FIRST_INVITE_CODE");
30000
+ const firstInvite = getEnvVar(readFileSync8(join8(installPath, ".env"), "utf-8"), "SELF_HOST_FIRST_INVITE_CODE");
29895
30001
  console.log(`
29896
30002
  OpenMates installed at ${installPath}`);
29897
30003
  console.log(`Mode: image (${DEFAULT_IMAGE_REGISTRY}, tag ${imageTag})`);
@@ -29929,10 +30035,10 @@ CLI default API: ${cliUrls2.apiUrl}`);
29929
30035
  }
29930
30036
  if (typeof flags["env-path"] === "string") {
29931
30037
  const envSource = resolve6(flags["env-path"]);
29932
- if (!existsSync9(envSource)) {
30038
+ if (!existsSync10(envSource)) {
29933
30039
  throw new Error(`Env file not found: ${envSource}`);
29934
30040
  }
29935
- copyFileSync2(envSource, join7(installPath, ".env"));
30041
+ copyFileSync2(envSource, join8(installPath, ".env"));
29936
30042
  console.error(`Copied ${envSource} to ${installPath}/.env`);
29937
30043
  }
29938
30044
  const translationResult = ensureSourceInstallTranslations(installPath, sourcePath);
@@ -29951,9 +30057,9 @@ CLI default API: ${cliUrls2.apiUrl}`);
29951
30057
  console.error("Setup script failed. Check the output above for details.");
29952
30058
  process.exit(setupCode);
29953
30059
  }
29954
- const envPath = join7(installPath, ".env");
30060
+ const envPath = join8(installPath, ".env");
29955
30061
  const overlay = writeDeploymentModeEnv(installPath, deploymentMode, requestedOverlayPath);
29956
- const cliUrls = deriveSelfHostCliUrls(existsSync9(envPath) ? readFileSync7(envPath, "utf-8") : "");
30062
+ const cliUrls = deriveSelfHostCliUrls(existsSync10(envPath) ? readFileSync8(envPath, "utf-8") : "");
29957
30063
  saveServerConfig({
29958
30064
  installPath,
29959
30065
  installedAt: Date.now(),
@@ -29994,15 +30100,15 @@ async function installContinuousUpdateService(flags) {
29994
30100
  const channel = typeof flags.channel === "string" ? flags.channel : config?.imageChannel ?? "main";
29995
30101
  const window = typeof flags.window === "string" ? flags.window : "02:00-04:00 UTC";
29996
30102
  const plan = planContinuousUpdateService({ role, channel, window });
29997
- const servicePath = join7("/etc", "systemd", "system", plan.serviceName);
29998
- const timerPath = join7("/etc", "systemd", "system", plan.timerName);
30103
+ const servicePath = join8("/etc", "systemd", "system", plan.serviceName);
30104
+ const timerPath = join8("/etc", "systemd", "system", plan.timerName);
29999
30105
  if (flags["dry-run"] === true || flags.json === true) {
30000
30106
  printJson({ command: "update install-service", status: "planned", role, servicePath, timerPath, unit: plan.unit, timer: plan.timer });
30001
30107
  return;
30002
30108
  }
30003
30109
  try {
30004
- writeFileSync5(servicePath, plan.unit, { mode: 420 });
30005
- writeFileSync5(timerPath, plan.timer, { mode: 420 });
30110
+ writeFileSync6(servicePath, plan.unit, { mode: 420 });
30111
+ writeFileSync6(timerPath, plan.timer, { mode: 420 });
30006
30112
  execSync("systemctl daemon-reload", { stdio: "pipe" });
30007
30113
  execSync(`systemctl enable --now ${shellQuote(plan.timerName)}`, { stdio: "pipe" });
30008
30114
  } catch (error) {
@@ -30013,13 +30119,13 @@ async function installContinuousUpdateService(flags) {
30013
30119
  console.log(`Installed ${plan.timerName}.`);
30014
30120
  }
30015
30121
  function runRuntimeVerification(installPath, role, config) {
30016
- const envText = existsSync9(join7(installPath, ".env")) ? readFileSync7(join7(installPath, ".env"), "utf-8") : "";
30122
+ const envText = existsSync10(join8(installPath, ".env")) ? readFileSync8(join8(installPath, ".env"), "utf-8") : "";
30017
30123
  const mode = resolveRuntimeDeploymentMode({
30018
30124
  envText,
30019
- overlayExists: existsSync9(config?.openMatesCloudOverlayPath ?? defaultOpenMatesCloudOverlayPath(installPath))
30125
+ overlayExists: existsSync10(config?.openMatesCloudOverlayPath ?? defaultOpenMatesCloudOverlayPath(installPath))
30020
30126
  });
30021
- const backupPath = join7(roleBackupDir(installPath, role), `latest-pre-update-${role}.tar.gz`);
30022
- const plan = planRuntimeVerification({ role, deploymentMode: mode.effectiveMode, hasVerifiedBackup: existsSync9(backupPath) });
30127
+ const backupPath = join8(roleBackupDir(installPath, role), `latest-pre-update-${role}.tar.gz`);
30128
+ const plan = planRuntimeVerification({ role, deploymentMode: mode.effectiveMode, hasVerifiedBackup: existsSync10(backupPath) });
30023
30129
  const verifierService = { core: "api", upload: "app-uploads", preview: "preview" }[role];
30024
30130
  const installMode = getInstallMode(installPath, config);
30025
30131
  const withOverrides = config?.composeProfile === "full";
@@ -30226,10 +30332,10 @@ async function installRuntimeMonitoringServices(installPath, role) {
30226
30332
  [operationalPlan.watchdogTimerName, operationalPlan.watchdogTimer]
30227
30333
  ] : []
30228
30334
  ].filter((entry) => Boolean(entry[0] && entry[1]));
30229
- const reportStatePath = join7(installPath, ".openmates", "runtime-health", `${role}-operational-report.json`);
30230
- const reportMetricsDir = join7(installPath, ".openmates", "runtime-health", "metrics");
30231
- const startedMetricPath = join7(reportMetricsDir, "operational-report-started.prom");
30232
- const successMetricPath = join7(reportMetricsDir, "operational-report.prom");
30335
+ const reportStatePath = join8(installPath, ".openmates", "runtime-health", `${role}-operational-report.json`);
30336
+ const reportMetricsDir = join8(installPath, ".openmates", "runtime-health", "metrics");
30337
+ const startedMetricPath = join8(reportMetricsDir, "operational-report-started.prom");
30338
+ const successMetricPath = join8(reportMetricsDir, "operational-report.prom");
30233
30339
  const operationalUnitNames = [
30234
30340
  operationalPlan.digestServiceName,
30235
30341
  operationalPlan.digestTimerName,
@@ -30237,18 +30343,18 @@ async function installRuntimeMonitoringServices(installPath, role) {
30237
30343
  operationalPlan.watchdogTimerName
30238
30344
  ];
30239
30345
  if (operationalPlan.scheduleEnabled) {
30240
- mkdirSync6(dirname6(reportStatePath), { recursive: true, mode: 448 });
30241
- mkdirSync6(reportMetricsDir, { recursive: true, mode: 448 });
30242
- if (!existsSync9(reportStatePath)) {
30243
- writeFileSync5(
30346
+ mkdirSync7(dirname6(reportStatePath), { recursive: true, mode: 448 });
30347
+ mkdirSync7(reportMetricsDir, { recursive: true, mode: 448 });
30348
+ if (!existsSync10(reportStatePath)) {
30349
+ writeFileSync6(
30244
30350
  reportStatePath,
30245
30351
  `${JSON.stringify({ incidentOpen: false, monitoringStartedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)}
30246
30352
  `,
30247
30353
  { mode: 384 }
30248
30354
  );
30249
30355
  }
30250
- if (!existsSync9(startedMetricPath)) {
30251
- writeFileSync5(
30356
+ if (!existsSync10(startedMetricPath)) {
30357
+ writeFileSync6(
30252
30358
  startedMetricPath,
30253
30359
  `operational_report_monitoring_started_timestamp_seconds{environment="${operationalPlan.environment}"} ${Math.floor(Date.now() / 1e3)}
30254
30360
  `,
@@ -30256,17 +30362,17 @@ async function installRuntimeMonitoringServices(installPath, role) {
30256
30362
  );
30257
30363
  }
30258
30364
  } else {
30259
- const installedOperationalUnits = operationalUnitNames.filter((name) => existsSync9(join7("/etc", "systemd", "system", name)));
30365
+ const installedOperationalUnits = operationalUnitNames.filter((name) => existsSync10(join8("/etc", "systemd", "system", name)));
30260
30366
  const installedOperationalTimers = installedOperationalUnits.filter((name) => name.endsWith(".timer"));
30261
30367
  if (installedOperationalTimers.length) {
30262
30368
  execFileSync4("systemctl", ["disable", "--now", ...installedOperationalTimers], { stdio: "pipe" });
30263
30369
  }
30264
- for (const name of installedOperationalUnits) rmSync6(join7("/etc", "systemd", "system", name));
30370
+ for (const name of installedOperationalUnits) rmSync7(join8("/etc", "systemd", "system", name));
30265
30371
  for (const path2 of [reportStatePath, startedMetricPath, successMetricPath]) {
30266
- if (existsSync9(path2)) rmSync6(path2);
30372
+ if (existsSync10(path2)) rmSync7(path2);
30267
30373
  }
30268
30374
  }
30269
- for (const [name, content] of files) writeFileSync5(join7("/etc", "systemd", "system", name), content, { mode: 420 });
30375
+ for (const [name, content] of files) writeFileSync6(join8("/etc", "systemd", "system", name), content, { mode: 420 });
30270
30376
  execSync("systemctl daemon-reload", { stdio: "pipe" });
30271
30377
  const timers = files.filter(([name]) => name.endsWith(".timer")).map(([name]) => name);
30272
30378
  execSync(`systemctl enable --now ${timers.map(shellQuote).join(" ")}`, { stdio: "pipe" });
@@ -30288,10 +30394,10 @@ async function serverUpdate(client, rest, flags) {
30288
30394
  const filePath = serverUpdateStatusFile(installPath2, role2);
30289
30395
  const status = readServerUpdateStatus(installPath2, role2);
30290
30396
  if (flags.json === true) {
30291
- printJson(existsSync9(filePath) ? status : { role: role2, status: "unknown" });
30397
+ printJson(existsSync10(filePath) ? status : { role: role2, status: "unknown" });
30292
30398
  return;
30293
30399
  }
30294
- if (!existsSync9(filePath)) {
30400
+ if (!existsSync10(filePath)) {
30295
30401
  console.log(`No update status recorded for ${role2}.`);
30296
30402
  return;
30297
30403
  }
@@ -30477,7 +30583,7 @@ async function serverUpdate(client, rest, flags) {
30477
30583
  try {
30478
30584
  await autoInstallRuntimeMonitoringServices(installPath, role);
30479
30585
  } catch (error) {
30480
- const restoreCommand = safetyPlan.backupName ? `openmates server restore --role ${role} --file ${join7(roleBackupDir(installPath, role), safetyPlan.backupName)}` : null;
30586
+ const restoreCommand = safetyPlan.backupName ? `openmates server restore --role ${role} --file ${join8(roleBackupDir(installPath, role), safetyPlan.backupName)}` : null;
30481
30587
  writeServerUpdateStatus(installPath, role, {
30482
30588
  status: "degraded",
30483
30589
  targetImageTag: target.tag,
@@ -30803,11 +30909,11 @@ async function serverMonitoring(rest, flags) {
30803
30909
  const state2 = await readOperationalReportState(installPath, role);
30804
30910
  const nextState2 = accepted ? { ...state2, incidentOpen: false, incidentOpenedAt: void 0, lastAcceptedReportAt: (/* @__PURE__ */ new Date()).toISOString() } : state2;
30805
30911
  await writeOperationalReportState(installPath, role, nextState2);
30806
- const metricsDir = join7(installPath, ".openmates", "runtime-health", "metrics");
30807
- mkdirSync6(metricsDir, { recursive: true, mode: 448 });
30912
+ const metricsDir = join8(installPath, ".openmates", "runtime-health", "metrics");
30913
+ mkdirSync7(metricsDir, { recursive: true, mode: 448 });
30808
30914
  if (accepted) {
30809
- writeFileSync5(
30810
- join7(metricsDir, "operational-report.prom"),
30915
+ writeFileSync6(
30916
+ join8(metricsDir, "operational-report.prom"),
30811
30917
  `operational_report_last_success_timestamp_seconds{environment="${output2.receipts[0]?.environment ?? environment}"} ${Math.floor(Date.now() / 1e3)}
30812
30918
  `,
30813
30919
  { mode: 384 }
@@ -30825,11 +30931,11 @@ async function serverMonitoring(rest, flags) {
30825
30931
  destinationSource: receipt.destination_source,
30826
30932
  fallbackUsed: receipt.fallback_used
30827
30933
  }));
30828
- const receiptDir = join7(installPath, ".openmates", "runtime-health", "receipts");
30829
- mkdirSync6(receiptDir, { recursive: true, mode: 448 });
30934
+ const receiptDir = join8(installPath, ".openmates", "runtime-health", "receipts");
30935
+ mkdirSync7(receiptDir, { recursive: true, mode: 448 });
30830
30936
  const receiptMonth = (/* @__PURE__ */ new Date()).toISOString().slice(0, 7);
30831
30937
  for (const receipt of redactedReceipts) {
30832
- appendFileSync(join7(receiptDir, `${receiptMonth}.jsonl`), `${JSON.stringify(receipt)}
30938
+ appendFileSync(join8(receiptDir, `${receiptMonth}.jsonl`), `${JSON.stringify(receipt)}
30833
30939
  `, { mode: 384 });
30834
30940
  }
30835
30941
  const displayed = { command: "monitoring digest", reportId: output2.report_id, reportSha256: output2.report_sha256, deliveryState: output2.delivery_state, receipts: redactedReceipts };
@@ -31033,14 +31139,14 @@ async function serverFeatures(rest, flags) {
31033
31139
  const installPath = resolveServerPath(flags);
31034
31140
  const installMode = getInstallMode(installPath);
31035
31141
  if (installMode === "image") ensureImageRuntimeConfig(installPath);
31036
- const configPath = installMode === "image" ? imageBackendConfigPath(installPath) : join7(installPath, BACKEND_CONFIG_FILE);
31037
- if (!existsSync9(configPath)) {
31142
+ const configPath = installMode === "image" ? imageBackendConfigPath(installPath) : join8(installPath, BACKEND_CONFIG_FILE);
31143
+ if (!existsSync10(configPath)) {
31038
31144
  throw new Error(`Backend config not found at ${configPath}. Run 'openmates server install' first or pass --path <dir>.`);
31039
31145
  }
31040
- const content = readFileSync7(configPath, "utf-8");
31146
+ const content = readFileSync8(configPath, "utf-8");
31041
31147
  const overrides = parseFeatureOverrides(content);
31042
31148
  const writeOverrides = (nextOverrides) => {
31043
- writeFileSync5(configPath, updateFeatureOverridesContent(content, nextOverrides));
31149
+ writeFileSync6(configPath, updateFeatureOverridesContent(content, nextOverrides));
31044
31150
  console.log(`Updated ${configPath}`);
31045
31151
  console.log("Restart the server for feature changes to take effect: openmates server restart");
31046
31152
  };
@@ -31273,7 +31379,7 @@ async function serverBackup(rest, flags) {
31273
31379
  const role = getServerRole(flags, config);
31274
31380
  if (action === "list") {
31275
31381
  const dir = roleBackupDir(installPath, role);
31276
- const files = existsSync9(dir) ? readdirSync4(dir).filter((item) => item.endsWith(".tar.gz")).sort() : [];
31382
+ const files = existsSync10(dir) ? readdirSync5(dir).filter((item) => item.endsWith(".tar.gz")).sort() : [];
31277
31383
  if (flags.json === true) {
31278
31384
  printJson({ role, backupDir: dir, files });
31279
31385
  return;
@@ -31283,7 +31389,7 @@ async function serverBackup(rest, flags) {
31283
31389
  console.log(" none");
31284
31390
  return;
31285
31391
  }
31286
- for (const file of files) console.log(` ${join7(dir, file)}`);
31392
+ for (const file of files) console.log(` ${join8(dir, file)}`);
31287
31393
  return;
31288
31394
  }
31289
31395
  requireDocker();
@@ -31368,7 +31474,7 @@ async function serverUninstall(flags) {
31368
31474
  } catch {
31369
31475
  }
31370
31476
  try {
31371
- rmSync6(installPath, { recursive: true, force: true });
31477
+ rmSync7(installPath, { recursive: true, force: true });
31372
31478
  console.error(` Removed installation directory: ${installPath}`);
31373
31479
  } catch (e) {
31374
31480
  console.error(` Could not remove ${installPath}: ${e instanceof Error ? e.message : e}`);
@@ -31443,7 +31549,7 @@ async function serverCaddy(rest, flags) {
31443
31549
  const role = getServerRole(flags, config);
31444
31550
  const appliedPath = typeof flags.config === "string" ? flags.config : "/etc/caddy/Caddyfile";
31445
31551
  const templatePath = packagedCaddyTemplatePath(role);
31446
- if (!existsSync9(templatePath)) throw new Error(`Packaged Caddy template not found: ${templatePath}`);
31552
+ if (!existsSync10(templatePath)) throw new Error(`Packaged Caddy template not found: ${templatePath}`);
31447
31553
  const plan = planCaddyCommand({ role, action, appliedPath });
31448
31554
  const payload = {
31449
31555
  ...plan,
@@ -31462,7 +31568,7 @@ async function serverCaddy(rest, flags) {
31462
31568
  return;
31463
31569
  }
31464
31570
  if (action === "diff") {
31465
- if (!existsSync9(appliedPath)) throw new Error(`Applied Caddyfile not found: ${appliedPath}`);
31571
+ if (!existsSync10(appliedPath)) throw new Error(`Applied Caddyfile not found: ${appliedPath}`);
31466
31572
  try {
31467
31573
  execSync(`diff -u ${shellQuote(appliedPath)} ${shellQuote(templatePath)}`, { stdio: "inherit" });
31468
31574
  } catch (error) {
@@ -31483,9 +31589,9 @@ WARNING: This will replace ${appliedPath} with the packaged ${role} Caddyfile.`)
31483
31589
  }
31484
31590
  }
31485
31591
  const backupPath = `${appliedPath}.openmates-backup-${nowStamp()}`;
31486
- const hadExistingCaddyfile = existsSync9(appliedPath);
31592
+ const hadExistingCaddyfile = existsSync10(appliedPath);
31487
31593
  try {
31488
- mkdirSync6(dirname6(appliedPath), { recursive: true });
31594
+ mkdirSync7(dirname6(appliedPath), { recursive: true });
31489
31595
  if (hadExistingCaddyfile) copyFileSync2(appliedPath, backupPath);
31490
31596
  copyFileSync2(templatePath, appliedPath);
31491
31597
  execSync("systemctl reload caddy", { stdio: "inherit" });
@@ -50610,6 +50716,12 @@ Only output the final Markdown table. Do NOT include explanations, notes, or any
50610
50716
  }
50611
50717
  },
50612
50718
  calendar: {
50719
+ list_calendars: {
50720
+ text: "List Calendars",
50721
+ description: {
50722
+ text: "List calendars, timezones, and access roles in a connected account."
50723
+ }
50724
+ },
50613
50725
  get_events: {
50614
50726
  text: "Search",
50615
50727
  description: {
@@ -56799,6 +56911,9 @@ Only output the final Markdown table. Do NOT include explanations, notes, or any
56799
56911
  generating_title: {
56800
56912
  text: "Processing..."
56801
56913
  },
56914
+ selecting_mate_and_model: {
56915
+ text: "Selecting mate & AI model..."
56916
+ },
56802
56917
  selecting_mate: {
56803
56918
  text: "Selecting optimal mate..."
56804
56919
  },
@@ -70616,10 +70731,10 @@ function buildAssistantFeedbackDecision(rating) {
70616
70731
  }
70617
70732
 
70618
70733
  // src/benchmark.ts
70619
- import { createHash as createHash13, randomUUID as randomUUID12 } from "crypto";
70620
- import { existsSync as existsSync10, mkdtempSync as mkdtempSync2, readFileSync as readFileSync8, readdirSync as readdirSync5, writeFileSync as writeFileSync6 } from "fs";
70734
+ import { createHash as createHash14, randomUUID as randomUUID12 } from "crypto";
70735
+ import { existsSync as existsSync11, mkdtempSync as mkdtempSync2, readFileSync as readFileSync9, readdirSync as readdirSync6, writeFileSync as writeFileSync7 } from "fs";
70621
70736
  import { tmpdir } from "os";
70622
- import { dirname as dirname7, join as join8, resolve as resolve8 } from "path";
70737
+ import { dirname as dirname7, join as join9, resolve as resolve8 } from "path";
70623
70738
  import { fileURLToPath } from "url";
70624
70739
  var DEFAULT_JUDGE_MODEL = "google/gemini-3-flash-preview";
70625
70740
  var DEFAULT_PROMPT_BUDGET_MODEL = "google/gemini-3.5-flash";
@@ -71505,7 +71620,7 @@ async function buildPromptWithAttachments(client, benchmarkCase, model, imagePat
71505
71620
  ${attachment.messageSuffix}`, embeds: attachment.embeds };
71506
71621
  }
71507
71622
  async function prepareImageAttachment(client, imagePath) {
71508
- if (!existsSync10(imagePath)) throw new Error(`Benchmark image not found: ${imagePath}`);
71623
+ if (!existsSync11(imagePath)) throw new Error(`Benchmark image not found: ${imagePath}`);
71509
71624
  const processed = processFiles([imagePath], null);
71510
71625
  if (processed.blocked.length > 0 || processed.errors.length > 0 || processed.embeds.length === 0) {
71511
71626
  const reason = [...processed.blocked, ...processed.errors].map((entry) => entry.error).join("; ") || "no image embed produced";
@@ -71785,10 +71900,10 @@ function loadProviderPricing() {
71785
71900
  const providersDir = findProvidersDir();
71786
71901
  const pricing = /* @__PURE__ */ new Map();
71787
71902
  if (!providersDir) return pricing;
71788
- for (const fileName of readdirSync5(providersDir)) {
71903
+ for (const fileName of readdirSync6(providersDir)) {
71789
71904
  if (!fileName.endsWith(".yml")) continue;
71790
- const filePath = join8(providersDir, fileName);
71791
- const text = readFileSync8(filePath, "utf-8");
71905
+ const filePath = join9(providersDir, fileName);
71906
+ const text = readFileSync9(filePath, "utf-8");
71792
71907
  const provider = parseProviderId(text) ?? fileName.replace(/\.yml$/, "");
71793
71908
  for (const modelPricing of parseModelPricing(text, provider)) {
71794
71909
  pricing.set(`${modelPricing.provider}/${modelPricing.modelId}`, modelPricing);
@@ -71842,10 +71957,10 @@ function findProvidersDir() {
71842
71957
  const currentFile = fileURLToPath(import.meta.url);
71843
71958
  let current = dirname7(currentFile);
71844
71959
  for (let index = 0; index < 8; index += 1) {
71845
- const candidate = join8(current, "backend", "providers");
71846
- if (existsSync10(candidate)) return candidate;
71847
- const parentCandidate = join8(current, "..", "..", "backend", "providers");
71848
- if (existsSync10(parentCandidate)) return resolve8(parentCandidate);
71960
+ const candidate = join9(current, "backend", "providers");
71961
+ if (existsSync11(candidate)) return candidate;
71962
+ const parentCandidate = join9(current, "..", "..", "backend", "providers");
71963
+ if (existsSync11(parentCandidate)) return resolve8(parentCandidate);
71849
71964
  const next = dirname7(current);
71850
71965
  if (next === current) break;
71851
71966
  current = next;
@@ -72050,21 +72165,21 @@ function hashPromptBudgetCorpus(cases) {
72050
72165
  return stableHash(cases.map((benchmarkCase) => ({ id: benchmarkCase.id, turns: benchmarkCase.turns })));
72051
72166
  }
72052
72167
  function stableHash(value) {
72053
- return createHash13("sha256").update(JSON.stringify(value)).digest("hex");
72168
+ return createHash14("sha256").update(JSON.stringify(value)).digest("hex");
72054
72169
  }
72055
72170
  function defaultImageFixturePath() {
72056
- const fixtureDir = join8(dirname7(fileURLToPath(import.meta.url)), "..", "fixtures");
72057
- const fixturePath = join8(fixtureDir, "brandenburger-tor.png");
72058
- if (existsSync10(fixturePath)) return fixturePath;
72059
- const tempDir = mkdtempSync2(join8(tmpdir(), "openmates-benchmark-"));
72060
- const tempPath = join8(tempDir, "brandenburger-tor.svg");
72061
- writeFileSync6(tempPath, FIXTURE_IMAGE_SVG, "utf-8");
72171
+ const fixtureDir = join9(dirname7(fileURLToPath(import.meta.url)), "..", "fixtures");
72172
+ const fixturePath = join9(fixtureDir, "brandenburger-tor.png");
72173
+ if (existsSync11(fixturePath)) return fixturePath;
72174
+ const tempDir = mkdtempSync2(join9(tmpdir(), "openmates-benchmark-"));
72175
+ const tempPath = join9(tempDir, "brandenburger-tor.svg");
72176
+ writeFileSync7(tempPath, FIXTURE_IMAGE_SVG, "utf-8");
72062
72177
  return tempPath;
72063
72178
  }
72064
72179
  function writeBenchmarkResult(result, flags, output) {
72065
72180
  const json = `${JSON.stringify(result, null, 2)}
72066
72181
  `;
72067
- if (output) writeFileSync6(output, json, "utf-8");
72182
+ if (output) writeFileSync7(output, json, "utf-8");
72068
72183
  if (flags.json === true || output) {
72069
72184
  process.stdout.write(json);
72070
72185
  return;
@@ -72088,7 +72203,7 @@ function writeBenchmarkResult(result, flags, output) {
72088
72203
  function writePromptBudgetResult(result, flags, output) {
72089
72204
  const json = `${JSON.stringify(result, null, 2)}
72090
72205
  `;
72091
- if (output) writeFileSync6(output, json, "utf-8");
72206
+ if (output) writeFileSync7(output, json, "utf-8");
72092
72207
  if (flags.json === true || output) {
72093
72208
  process.stdout.write(json);
72094
72209
  return;
@@ -72114,7 +72229,7 @@ function writePromptBudgetResult(result, flags, output) {
72114
72229
  function writePromptBudgetComparison(result, flags, output) {
72115
72230
  const json = `${JSON.stringify(result, null, 2)}
72116
72231
  `;
72117
- if (output) writeFileSync6(output, json, "utf-8");
72232
+ if (output) writeFileSync7(output, json, "utf-8");
72118
72233
  if (flags.json === true || output) {
72119
72234
  process.stdout.write(json);
72120
72235
  return;
@@ -72164,7 +72279,7 @@ function comparePromptBudgetArtifacts(flags) {
72164
72279
  };
72165
72280
  }
72166
72281
  function readPromptBudgetResult(path2) {
72167
- const parsed = JSON.parse(readFileSync8(path2, "utf-8"));
72282
+ const parsed = JSON.parse(readFileSync9(path2, "utf-8"));
72168
72283
  if (!parsed || typeof parsed !== "object") throw new Error(`Invalid prompt-budget artifact: ${path2}`);
72169
72284
  return parsed;
72170
72285
  }
@@ -73565,19 +73680,19 @@ import {
73565
73680
  chmodSync as chmodSync6,
73566
73681
  closeSync as closeSync3,
73567
73682
  constants,
73568
- existsSync as existsSync11,
73683
+ existsSync as existsSync12,
73569
73684
  fstatSync,
73570
- mkdirSync as mkdirSync7,
73685
+ mkdirSync as mkdirSync8,
73571
73686
  openSync as openSync3,
73572
- readFileSync as readFileSync9,
73573
- readdirSync as readdirSync6,
73687
+ readFileSync as readFileSync10,
73688
+ readdirSync as readdirSync7,
73574
73689
  readSync as readSync2,
73575
73690
  realpathSync,
73576
73691
  statSync as statSync2,
73577
- writeFileSync as writeFileSync7
73692
+ writeFileSync as writeFileSync8
73578
73693
  } from "fs";
73579
73694
  import { spawn as spawn2, spawnSync as spawnSync2 } from "child_process";
73580
- import { join as join9, resolve as resolve9, relative as relative2 } from "path";
73695
+ import { join as join10, resolve as resolve9, relative as relative2 } from "path";
73581
73696
 
73582
73697
  // src/projectFileRisk.ts
73583
73698
  var SECRET_OR_ENVIRONMENT_PATTERNS = [
@@ -73700,7 +73815,7 @@ function resolveRemoteAccessRoots(pathFlag, cwd = process.cwd()) {
73700
73815
  const roots = [];
73701
73816
  for (const value of requested) {
73702
73817
  const candidate = resolve9(cwd, value);
73703
- if (!existsSync11(candidate) || !statSync2(candidate).isDirectory()) {
73818
+ if (!existsSync12(candidate) || !statSync2(candidate).isDirectory()) {
73704
73819
  throw new Error(`Remote source path does not exist or is not a directory: ${candidate}`);
73705
73820
  }
73706
73821
  const canonical = realpathSync(candidate);
@@ -73714,7 +73829,7 @@ function discoverRemoteAccessRepositories(roots) {
73714
73829
  const visit = (directory, approvedRoot) => {
73715
73830
  let entries;
73716
73831
  try {
73717
- entries = readdirSync6(directory, { withFileTypes: true });
73832
+ entries = readdirSync7(directory, { withFileTypes: true });
73718
73833
  } catch (error) {
73719
73834
  const code = error.code;
73720
73835
  if (code === "EACCES" || code === "EPERM") {
@@ -73728,7 +73843,7 @@ function discoverRemoteAccessRepositories(roots) {
73728
73843
  }
73729
73844
  for (const entry of entries) {
73730
73845
  if (entry.name === ".git" || entry.isSymbolicLink() || !entry.isDirectory()) continue;
73731
- visit(join9(directory, entry.name), approvedRoot);
73846
+ visit(join10(directory, entry.name), approvedRoot);
73732
73847
  }
73733
73848
  };
73734
73849
  for (const root of roots) visit(root, root);
@@ -73738,8 +73853,8 @@ function discoverRemoteAccessRepositories(roots) {
73738
73853
  };
73739
73854
  }
73740
73855
  function remoteAccessSourceType(rootPath) {
73741
- const gitMarker = join9(rootPath, ".git");
73742
- return existsSync11(gitMarker) ? "local_git_repository" : "local_folder";
73856
+ const gitMarker = join10(rootPath, ".git");
73857
+ return existsSync12(gitMarker) ? "local_git_repository" : "local_folder";
73743
73858
  }
73744
73859
  function listRemoteAccessDirectory(options) {
73745
73860
  const root = realpathSync(options.sourceRoot);
@@ -73752,9 +73867,9 @@ function listRemoteAccessDirectory(options) {
73752
73867
  const entries = [];
73753
73868
  let omitted = 0;
73754
73869
  let excluded = 0;
73755
- for (const entry of readdirSync6(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
73756
- const entryPath = relative2(root, join9(directory, entry.name)).replace(/\\/g, "/");
73757
- if (entry.name === ".git" || entry.isSymbolicLink() || isGitIgnoredPath(root, entryPath) || classifyProjectFileRisk(entryPath, options.userProtectedPatterns ?? []).isHighRisk || entry.isFile() && isBinaryFile(join9(directory, entry.name))) {
73870
+ for (const entry of readdirSync7(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
73871
+ const entryPath = relative2(root, join10(directory, entry.name)).replace(/\\/g, "/");
73872
+ if (entry.name === ".git" || entry.isSymbolicLink() || isGitIgnoredPath(root, entryPath) || classifyProjectFileRisk(entryPath, options.userProtectedPatterns ?? []).isHighRisk || entry.isFile() && isBinaryFile(join10(directory, entry.name))) {
73758
73873
  excluded += 1;
73759
73874
  continue;
73760
73875
  }
@@ -73982,7 +74097,7 @@ function remoteAccessOperationErrorCode(error) {
73982
74097
  return "operation_failed";
73983
74098
  }
73984
74099
  function isGitIgnoredPath(sourceRoot, relativePath) {
73985
- if (!existsSync11(join9(sourceRoot, ".git"))) return false;
74100
+ if (!existsSync12(join10(sourceRoot, ".git"))) return false;
73986
74101
  const result = spawnSync2("git", ["check-ignore", "--quiet", "--", relativePath], {
73987
74102
  cwd: sourceRoot,
73988
74103
  stdio: "ignore"
@@ -74012,13 +74127,13 @@ function waitForAbort2(signal, timeoutMs) {
74012
74127
  }
74013
74128
  function resolveRemoteCachePath(sourceId, homeDirectory = homedir7()) {
74014
74129
  assertSafeSourceId(sourceId);
74015
- return join9(homeDirectory, ".openmates", "remote-cache", sourceId);
74130
+ return join10(homeDirectory, ".openmates", "remote-cache", sourceId);
74016
74131
  }
74017
74132
  function startRemoteAccessSource(input) {
74018
74133
  assertSafeSourceId(input.sourceId);
74019
74134
  const homeDirectory = input.homeDirectory ?? homedir7();
74020
74135
  const requestedRootPath = resolve9(input.rootPath);
74021
- if (!existsSync11(requestedRootPath) || !statSync2(requestedRootPath).isDirectory()) {
74136
+ if (!existsSync12(requestedRootPath) || !statSync2(requestedRootPath).isDirectory()) {
74022
74137
  throw new Error(`Remote source path does not exist or is not a directory: ${requestedRootPath}`);
74023
74138
  }
74024
74139
  const rootPath = realpathSync(requestedRootPath);
@@ -74036,14 +74151,14 @@ function startRemoteAccessSource(input) {
74036
74151
  };
74037
74152
  const sources = listRemoteAccessSources(homeDirectory).filter((entry) => entry.sourceId !== input.sourceId);
74038
74153
  saveRemoteAccessSources([...sources, source], homeDirectory);
74039
- mkdirSync7(source.cachePath, { recursive: true, mode: 448 });
74154
+ mkdirSync8(source.cachePath, { recursive: true, mode: 448 });
74040
74155
  return source;
74041
74156
  }
74042
74157
  function listRemoteAccessSources(homeDirectory = homedir7()) {
74043
74158
  const filePath = remoteAccessStorePath(homeDirectory);
74044
- if (!existsSync11(filePath)) return [];
74159
+ if (!existsSync12(filePath)) return [];
74045
74160
  try {
74046
- const parsed = JSON.parse(readFileSync9(filePath, "utf-8"));
74161
+ const parsed = JSON.parse(readFileSync10(filePath, "utf-8"));
74047
74162
  if (!Array.isArray(parsed.sources)) {
74048
74163
  throw new Error("Remote source store is missing the sources array");
74049
74164
  }
@@ -74100,13 +74215,13 @@ function searchRemoteSourceWithoutRg(query, sourceRoot, maxResults, userProtecte
74100
74215
  const directory = directories.pop();
74101
74216
  let entries;
74102
74217
  try {
74103
- entries = readdirSync6(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
74218
+ entries = readdirSync7(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
74104
74219
  } catch {
74105
74220
  excluded += 1;
74106
74221
  continue;
74107
74222
  }
74108
74223
  for (const entry of entries) {
74109
- const absolutePath = join9(directory, entry.name);
74224
+ const absolutePath = join10(directory, entry.name);
74110
74225
  const relativePath = relative2(root, absolutePath).replace(/\\/g, "/");
74111
74226
  if (entry.name === ".git" || entry.isSymbolicLink() || isGitIgnoredPath(root, relativePath) || classifyProjectFileRisk(relativePath, userProtectedPatterns).isHighRisk) {
74112
74227
  excluded += 1;
@@ -74275,7 +74390,7 @@ function assertInsideRoot(sourceRoot, path2) {
74275
74390
  }
74276
74391
  function openedDescriptorPath(descriptor, requestedPath) {
74277
74392
  const procPath = `/proc/self/fd/${descriptor}`;
74278
- if (existsSync11(procPath)) return realpathSync(procPath);
74393
+ if (existsSync12(procPath)) return realpathSync(procPath);
74279
74394
  return realpathSync(requestedPath);
74280
74395
  }
74281
74396
  function isBinaryFile(path2) {
@@ -74307,14 +74422,14 @@ function normalizeBound(value, maximum, label) {
74307
74422
  return result;
74308
74423
  }
74309
74424
  function remoteAccessStorePath(homeDirectory) {
74310
- return join9(homeDirectory, ".openmates", "remote-sources.json");
74425
+ return join10(homeDirectory, ".openmates", "remote-sources.json");
74311
74426
  }
74312
74427
  function saveRemoteAccessSources(sources, homeDirectory) {
74313
74428
  const filePath = remoteAccessStorePath(homeDirectory);
74314
- const stateDir2 = join9(homeDirectory, ".openmates");
74315
- mkdirSync7(stateDir2, { recursive: true, mode: 448 });
74429
+ const stateDir2 = join10(homeDirectory, ".openmates");
74430
+ mkdirSync8(stateDir2, { recursive: true, mode: 448 });
74316
74431
  chmodSync6(stateDir2, 448);
74317
- writeFileSync7(filePath, `${JSON.stringify({ sources }, null, 2)}
74432
+ writeFileSync8(filePath, `${JSON.stringify({ sources }, null, 2)}
74318
74433
  `, { mode: 384 });
74319
74434
  chmodSync6(filePath, 384);
74320
74435
  }
@@ -74522,13 +74637,13 @@ function remoteErrorMessage(code) {
74522
74637
 
74523
74638
  // src/selfUpdate.ts
74524
74639
  import { spawnSync as spawnSync3 } from "child_process";
74525
- import { readFileSync as readFileSync10, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8, renameSync as renameSync4 } from "fs";
74640
+ import { readFileSync as readFileSync11, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9, renameSync as renameSync5 } from "fs";
74526
74641
  import { homedir as homedir8 } from "os";
74527
- import { dirname as dirname8, basename as basename3, join as join10 } from "path";
74642
+ import { dirname as dirname8, basename as basename3, join as join11 } from "path";
74528
74643
  import { fileURLToPath as fileURLToPath2 } from "url";
74529
74644
  var PACKAGE_NAME = "openmates";
74530
74645
  function channelFile() {
74531
- return join10(homedir8(), ".openmates", "updates.json");
74646
+ return join11(homedir8(), ".openmates", "updates.json");
74532
74647
  }
74533
74648
  function parseChannel(value) {
74534
74649
  if (value === "dev") return "dev";
@@ -74537,7 +74652,7 @@ function parseChannel(value) {
74537
74652
  }
74538
74653
  function savedChannel() {
74539
74654
  try {
74540
- return parseChannel(JSON.parse(readFileSync10(channelFile(), "utf8")).channel);
74655
+ return parseChannel(JSON.parse(readFileSync11(channelFile(), "utf8")).channel);
74541
74656
  } catch (error) {
74542
74657
  if (error.code === "ENOENT") {
74543
74658
  return getCliPackageVersion().includes("-") ? "dev" : "stable";
@@ -74548,10 +74663,10 @@ function savedChannel() {
74548
74663
  function persistSelfUpdateChannel(plan) {
74549
74664
  if (plan.dryRun || !plan.persistChannel) return;
74550
74665
  const path2 = channelFile();
74551
- mkdirSync8(dirname8(path2), { recursive: true, mode: 448 });
74666
+ mkdirSync9(dirname8(path2), { recursive: true, mode: 448 });
74552
74667
  const temporary = `${path2}.${process.pid}.tmp`;
74553
- writeFileSync8(temporary, JSON.stringify({ channel: plan.channel }) + "\n", { mode: 384 });
74554
- renameSync4(temporary, path2);
74668
+ writeFileSync9(temporary, JSON.stringify({ channel: plan.channel }) + "\n", { mode: 384 });
74669
+ renameSync5(temporary, path2);
74555
74670
  }
74556
74671
  function installedNpmPrefix(moduleUrl = import.meta.url, platform4 = process.platform) {
74557
74672
  const packageRoot = dirname8(dirname8(fileURLToPath2(moduleUrl)));
@@ -74583,7 +74698,7 @@ function compareVersions(left, right) {
74583
74698
  var SAFE_TARGET_RE = /^[a-zA-Z0-9._@+~:-]+$/;
74584
74699
  function getCliPackageVersion() {
74585
74700
  try {
74586
- const packageJson = JSON.parse(readFileSync10(new URL("../package.json", import.meta.url), "utf-8"));
74701
+ const packageJson = JSON.parse(readFileSync11(new URL("../package.json", import.meta.url), "utf-8"));
74587
74702
  return packageJson.version ?? "unknown";
74588
74703
  } catch {
74589
74704
  return "unknown";
@@ -74707,7 +74822,7 @@ function commandName(name) {
74707
74822
  }
74708
74823
 
74709
74824
  // src/workRecovery.ts
74710
- import { mkdirSync as mkdirSync9, renameSync as renameSync5, writeFileSync as writeFileSync9 } from "fs";
74825
+ import { mkdirSync as mkdirSync10, renameSync as renameSync6, writeFileSync as writeFileSync10 } from "fs";
74711
74826
  import { dirname as dirname9 } from "path";
74712
74827
  import { stringify } from "yaml";
74713
74828
  async function projectPlanAssumption(plan, masterKey, assumption) {
@@ -74887,18 +75002,18 @@ function collectMismatchPaths(left, right, path2, mismatches) {
74887
75002
  }
74888
75003
  function writeWorkRecoveryAtomically(path2, document) {
74889
75004
  validateWorkRecoveryDocument(document);
74890
- mkdirSync9(dirname9(path2), { recursive: true, mode: 448 });
75005
+ mkdirSync10(dirname9(path2), { recursive: true, mode: 448 });
74891
75006
  const temporaryPath = `${path2}.tmp`;
74892
- writeFileSync9(temporaryPath, stringify(document, { sortMapEntries: true, lineWidth: 0 }), { encoding: "utf8", mode: 384 });
74893
- renameSync5(temporaryPath, path2);
75007
+ writeFileSync10(temporaryPath, stringify(document, { sortMapEntries: true, lineWidth: 0 }), { encoding: "utf8", mode: 384 });
75008
+ renameSync6(temporaryPath, path2);
74894
75009
  }
74895
75010
 
74896
75011
  // src/revolutBusinessCertificate.ts
74897
75012
  import { execFileSync as execFileSync5 } from "child_process";
74898
75013
  import { createSign, randomUUID as randomUUID14 } from "crypto";
74899
- import { chmodSync as chmodSync7, existsSync as existsSync12, mkdirSync as mkdirSync10, readFileSync as readFileSync11 } from "fs";
75014
+ import { chmodSync as chmodSync7, existsSync as existsSync13, mkdirSync as mkdirSync11, readFileSync as readFileSync12 } from "fs";
74900
75015
  import { homedir as homedir9 } from "os";
74901
- import { join as join11, resolve as resolve10 } from "path";
75016
+ import { join as join12, resolve as resolve10 } from "path";
74902
75017
  var REVOLUT_BUSINESS_CERTIFICATE_DOCS_URL = "https://developer.revolut.com/docs/guides/manage-accounts/get-started/make-your-first-api-request#generate-a-private-and-a-public-certificate";
74903
75018
  var REVOLUT_BUSINESS_DEFAULT_SANDBOX_REDIRECT_URI = "https://app.dev.openmates.org/oauth/revolut-business/callback";
74904
75019
  var REVOLUT_BUSINESS_DEFAULT_PRODUCTION_REDIRECT_URI = "https://openmates.org/oauth/revolut-business/callback";
@@ -74908,7 +75023,7 @@ var REVOLUT_BUSINESS_AUDIENCE = "https://revolut.com";
74908
75023
  var CERTIFICATE_DAYS = "1825";
74909
75024
  var RSA_BITS = "2048";
74910
75025
  function defaultRevolutBusinessCertificateDir(environment) {
74911
- return join11(homedir9(), ".openmates", "revolut-business", environment);
75026
+ return join12(homedir9(), ".openmates", "revolut-business", environment);
74912
75027
  }
74913
75028
  function defaultRevolutBusinessRedirectUri(environment) {
74914
75029
  return environment === "sandbox" ? REVOLUT_BUSINESS_DEFAULT_SANDBOX_REDIRECT_URI : REVOLUT_BUSINESS_DEFAULT_PRODUCTION_REDIRECT_URI;
@@ -74931,7 +75046,7 @@ async function exchangeRevolutBusinessAuthorizationCode(options) {
74931
75046
  if (!clientId) throw new Error("Missing Revolut Business client ID.");
74932
75047
  const code = extractRevolutBusinessAuthorizationCode(options.codeOrRedirectUrl);
74933
75048
  if (!code) throw new Error("Missing Revolut Business authorization code.");
74934
- const privateKeyPem = options.privateKeyPem ?? readFileSync11(options.privateKeyPath ?? join11(defaultRevolutBusinessCertificateDir(environment), "privatecert.pem"), "utf8");
75049
+ const privateKeyPem = options.privateKeyPem ?? readFileSync12(options.privateKeyPath ?? join12(defaultRevolutBusinessCertificateDir(environment), "privatecert.pem"), "utf8");
74935
75050
  const redirectUri = (options.redirectUri ?? defaultRevolutBusinessRedirectUri(environment)).trim();
74936
75051
  const clientAssertion = generateRevolutBusinessClientAssertion({ clientId, privateKeyPem, redirectUri });
74937
75052
  const response = await fetch(environment === "sandbox" ? "https://sandbox-b2b.revolut.com/api/1.0/auth/token" : "https://b2b.revolut.com/api/1.0/auth/token", {
@@ -74984,11 +75099,11 @@ function generateRevolutBusinessCertificate(options = {}) {
74984
75099
  const redirectUri = (options.redirectUri ?? defaultRevolutBusinessRedirectUri(environment)).trim();
74985
75100
  if (!title) throw new Error("Revolut certificate title must not be empty.");
74986
75101
  if (!redirectUri.startsWith("https://")) throw new Error("Revolut OAuth redirect URI must start with https://.");
74987
- mkdirSync10(outputDir, { recursive: true, mode: 448 });
75102
+ mkdirSync11(outputDir, { recursive: true, mode: 448 });
74988
75103
  chmodSync7(outputDir, 448);
74989
- const privateKeyPath = join11(outputDir, "privatecert.pem");
74990
- const publicCertificatePath = join11(outputDir, "publiccert.cer");
74991
- if (!options.overwrite && (existsSync12(privateKeyPath) || existsSync12(publicCertificatePath))) {
75104
+ const privateKeyPath = join12(outputDir, "privatecert.pem");
75105
+ const publicCertificatePath = join12(outputDir, "publiccert.cer");
75106
+ if (!options.overwrite && (existsSync13(privateKeyPath) || existsSync13(publicCertificatePath))) {
74992
75107
  throw new Error(`Revolut certificate files already exist in ${outputDir}. Re-run with --overwrite to replace them.`);
74993
75108
  }
74994
75109
  try {
@@ -75022,7 +75137,7 @@ function generateRevolutBusinessCertificate(options = {}) {
75022
75137
  outputDir,
75023
75138
  privateKeyPath,
75024
75139
  publicCertificatePath,
75025
- publicCertificatePem: readFileSync11(publicCertificatePath, "utf8").trim()
75140
+ publicCertificatePem: readFileSync12(publicCertificatePath, "utf8").trim()
75026
75141
  };
75027
75142
  }
75028
75143
  function escapeOpenSslSubjectValue(value) {
@@ -75559,35 +75674,55 @@ async function handleTasks(client, subcommand, rest, flags, redactor) {
75559
75674
  const action = rest[0] ?? "list";
75560
75675
  const task = await requiredResolvedTask(client, masterKey, rest[1], scope, `activity ${action}`);
75561
75676
  const context = { teamId: scope.teamId, personal: scope.personal };
75562
- if (action === "list") {
75563
- const records = [];
75564
- let cursor;
75565
- do {
75566
- const page = await client.listUserTaskActivity(task.taskId, {
75567
- ...context,
75568
- cursor,
75569
- limit: typeof flags.limit === "string" ? Number(flags.limit) : void 0
75570
- });
75571
- records.push(...page.entries);
75572
- cursor = page.next_cursor ?? void 0;
75573
- } while (cursor);
75574
- const entries = await decryptTaskActivityEntries(task, masterKey, records);
75575
- if (flags.json === true) printJson2({ entries: entries.map(taskActivityToJson) });
75576
- else console.log(renderTaskActivityList(entries));
75677
+ const actor = flags["as-assignee"] === true ? "assignee" : "user";
75678
+ const delivery = () => activityDeliveryStore(JSON.stringify([
75679
+ client.getSession().apiUrl,
75680
+ client.getSession().hashedEmail,
75681
+ scope.teamId || "personal",
75682
+ task.taskId,
75683
+ actor
75684
+ ]));
75685
+ const createActivity = (input) => client.createUserTaskActivity(task.taskId, input, {
75686
+ ...context,
75687
+ ...actor === "assignee" ? { actorMode: "assignee" } : {}
75688
+ });
75689
+ if (action === "flush") {
75690
+ printJson2(await delivery().flush(createActivity));
75691
+ return;
75692
+ }
75693
+ if (action === "list" || action === "search") {
75694
+ const pending = flags["flush-pending"] === true ? await delivery().flush(createActivity) : void 0;
75695
+ const history = await readActivityHistory({
75696
+ maxEntries: typeof flags["max-entries"] === "string" ? Number(flags["max-entries"]) : action === "search" ? 200 : void 0,
75697
+ pageSize: typeof flags.limit === "string" ? Number(flags.limit) : 100,
75698
+ cursor: typeof flags.cursor === "string" ? flags.cursor : void 0,
75699
+ ...action === "search" ? { query: typeof flags.query === "string" ? flags.query : "" } : {},
75700
+ page: async (cursor, limit) => {
75701
+ const page = await client.listUserTaskActivity(task.taskId, {
75702
+ ...context,
75703
+ cursor,
75704
+ limit,
75705
+ newestFirst: flags["newest-first"] === true
75706
+ });
75707
+ return { entries: await decryptTaskActivityEntries(task, masterKey, page.entries), next_cursor: page.next_cursor };
75708
+ }
75709
+ });
75710
+ if (flags.json === true) printJson2({ ...history, entries: history.entries.map(taskActivityToJson), delivery: pending });
75711
+ else {
75712
+ console.log(renderTaskActivityList(history.entries));
75713
+ if (history.truncated) console.log(`Activity history truncated. Search all history: openmates tasks activity search ${task.shortId} --query "text" --max-entries 200`);
75714
+ if (history.next_cursor) console.log(`Next cursor: ${history.next_cursor}`);
75715
+ }
75577
75716
  return;
75578
75717
  }
75579
75718
  if (action === "add") {
75580
75719
  const message = typeof flags.message === "string" ? flags.message : rest.slice(2).join(" ");
75581
75720
  if (!message.trim()) throw new Error("Missing comment. Usage: openmates tasks activity add <task-id> --message <text>");
75582
- const input = await buildCreateTaskActivityInput(task, masterKey, { message });
75583
- const entry = await decryptTaskActivityEntry(
75584
- task,
75585
- masterKey,
75586
- await client.createUserTaskActivity(task.taskId, input, {
75587
- ...context,
75588
- ...flags["as-assignee"] === true ? { actorMode: "assignee" } : {}
75589
- })
75590
- );
75721
+ const deliveryId = typeof flags["delivery-id"] === "string" ? flags["delivery-id"] : void 0;
75722
+ const build = () => buildCreateTaskActivityInput(task, masterKey, { message, ...deliveryId ? { entryId: deliveryId } : {} });
75723
+ const record = deliveryId ? await delivery().deliver(deliveryId, build, createActivity) : await createActivity(await build());
75724
+ const entry = await decryptTaskActivityEntry(task, masterKey, record);
75725
+ if (entry.message !== message) throw new Error("Activity delivery id already belongs to a different milestone message");
75591
75726
  if (flags.json === true) printJson2({ entry: taskActivityToJson(entry) });
75592
75727
  else console.log(renderTaskActivityList([entry]));
75593
75728
  return;
@@ -75604,7 +75739,7 @@ async function handleTasks(client, subcommand, rest, flags, redactor) {
75604
75739
  else console.log(renderTaskActivityList([entry]));
75605
75740
  return;
75606
75741
  }
75607
- throw new Error("Usage: openmates tasks activity list|add|delete <task-id> [<entry-id>] [--message <text>]");
75742
+ throw new Error("Usage: openmates tasks activity list|search|add|flush|delete <task-id> [<entry-id>] [--message <text>]");
75608
75743
  }
75609
75744
  if (rest[0] === "add-to-project") {
75610
75745
  rejectRemoteCopyFlags(flags);
@@ -76540,7 +76675,7 @@ async function handlePlans(client, subcommand, rest, flags, redactor) {
76540
76675
  if (action === "diff") throw new Error("Revision diffs are reviewed in the authenticated web review page; use submit-for-review to print its URL.");
76541
76676
  if (action !== "submit-for-review") throw new Error("Usage: openmates plans revisions list|submit-for-review|status|diff <plan-id>");
76542
76677
  const snapshot = JSON.stringify(planToJson(plan));
76543
- const revision = await client.submitPlanRevision(plan.planId, { fingerprint: createHash14("sha256").update(snapshot).digest("hex"), encrypted_snapshot: await encryptPlanAssumptionSources(plan, masterKey, snapshot), created_at: nowSeconds3() });
76678
+ const revision = await client.submitPlanRevision(plan.planId, { fingerprint: createHash15("sha256").update(snapshot).digest("hex"), encrypted_snapshot: await encryptPlanAssumptionSources(plan, masterKey, snapshot), created_at: nowSeconds3() });
76544
76679
  const reviewUrl = `${deriveAppUrl(client.apiUrl)}/plans/${plan.planId}/review?revision=${revision.revision_id}`;
76545
76680
  if (flags.json === true) printJson2({ revision, review_url: reviewUrl });
76546
76681
  else console.log(`Plan revision submitted for web review: ${reviewUrl}`);
@@ -77096,8 +77231,8 @@ async function handleWorkRecovery(client, subcommand, rest, flags) {
77096
77231
  }
77097
77232
  if (subcommand === "validate" || subcommand === "restore") {
77098
77233
  const path2 = requiredStringFlag(flags.file ?? rest[0], "--file <projection.yml>");
77099
- if (!existsSync13(path2)) throw new Error(`Recovery projection does not exist: ${path2}`);
77100
- const document = parseYaml(readFileSync12(path2, "utf8"));
77234
+ if (!existsSync14(path2)) throw new Error(`Recovery projection does not exist: ${path2}`);
77235
+ const document = parseYaml(readFileSync13(path2, "utf8"));
77101
77236
  validateWorkRecoveryDocument(document);
77102
77237
  if (subcommand === "validate") {
77103
77238
  if (flags.json === true) printJson2({ valid: true });
@@ -77445,7 +77580,7 @@ async function handleProjects(client, subcommand, rest, flags, redactor) {
77445
77580
  last_opened_at: timestamp,
77446
77581
  key_wrappers: wrapping.teamId ? [{
77447
77582
  key_type: "team",
77448
- hashed_team_id: createHash14("sha256").update(wrapping.teamId).digest("hex"),
77583
+ hashed_team_id: createHash15("sha256").update(wrapping.teamId).digest("hex"),
77449
77584
  team_key_epoch: 1,
77450
77585
  encrypted_project_key: await encryptBytesWithAesGcm(projectKey, wrapping.key),
77451
77586
  wrapper_version: 1,
@@ -77928,7 +78063,7 @@ async function handleTeams(client, subcommand, rest, flags) {
77928
78063
  if (action === "get") {
77929
78064
  const output = requiredStringFlag(flags.output ?? flags.file ?? rest[2], "--output <path>");
77930
78065
  const image = await client.getTeamProfileImage(teamId);
77931
- writeFileSync10(output, image.data, { mode: 384 });
78066
+ writeFileSync11(output, image.data, { mode: 384 });
77932
78067
  if (flags.json === true) printJson2({ output, content_type: image.contentType, size_bytes: image.data.byteLength });
77933
78068
  else console.log(`Team profile image written: ${output}`);
77934
78069
  return;
@@ -78087,7 +78222,7 @@ async function handleTeams(client, subcommand, rest, flags) {
78087
78222
  const output = requiredStringFlag(flags.output, "--output <path>");
78088
78223
  const result = await client.exportTeamData(teamId);
78089
78224
  const artifact = result.artifact && typeof result.artifact === "object" ? result.artifact : result;
78090
- writeFileSync10(output, `${JSON.stringify(artifact, null, 2)}
78225
+ writeFileSync11(output, `${JSON.stringify(artifact, null, 2)}
78091
78226
  `, { encoding: "utf-8", mode: 384 });
78092
78227
  if (flags.json === true) printJson2({ ...result, output });
78093
78228
  else console.log(`Team export written: ${output}`);
@@ -78095,7 +78230,7 @@ async function handleTeams(client, subcommand, rest, flags) {
78095
78230
  }
78096
78231
  if (subcommand === "import") {
78097
78232
  const file = requiredStringFlag(flags.file ?? rest[0], "--file <path>");
78098
- const artifact = JSON.parse(readFileSync12(file, "utf-8"));
78233
+ const artifact = JSON.parse(readFileSync13(file, "utf-8"));
78099
78234
  let teamId = typeof flags.team === "string" ? flags.team : typeof flags["destination-team"] === "string" ? flags["destination-team"] : void 0;
78100
78235
  if (!teamId && typeof flags["new-team-name"] === "string") {
78101
78236
  const team = await client.createTeam({ name: flags["new-team-name"] });
@@ -78592,7 +78727,7 @@ async function createEncryptedRemoteAccessProject(client, masterKey, name, conte
78592
78727
  last_opened_at: timestamp,
78593
78728
  key_wrappers: wrapping.teamId ? [{
78594
78729
  key_type: "team",
78595
- hashed_team_id: createHash14("sha256").update(wrapping.teamId).digest("hex"),
78730
+ hashed_team_id: createHash15("sha256").update(wrapping.teamId).digest("hex"),
78596
78731
  team_key_epoch: 1,
78597
78732
  encrypted_project_key: await encryptBytesWithAesGcm(projectKey, wrapping.key),
78598
78733
  wrapper_version: 1,
@@ -79392,16 +79527,16 @@ ${deleted}/${resolved.length} chat(s) deleted.`);
79392
79527
  }
79393
79528
  }
79394
79529
  const { mkdir: mkdir2, writeFile: writeFile2 } = await import("fs/promises");
79395
- const { join: join12 } = await import("path");
79530
+ const { join: join13 } = await import("path");
79396
79531
  if (useZip) {
79397
- const tmpDir = join12(outputDir, `.${filenameBase}_tmp`);
79532
+ const tmpDir = join13(outputDir, `.${filenameBase}_tmp`);
79398
79533
  await mkdir2(tmpDir, { recursive: true });
79399
- await writeFile2(join12(tmpDir, `${filenameBase}.yml`), yamlContent);
79400
- await writeFile2(join12(tmpDir, `${filenameBase}.md`), mdContent);
79534
+ await writeFile2(join13(tmpDir, `${filenameBase}.yml`), yamlContent);
79535
+ await writeFile2(join13(tmpDir, `${filenameBase}.md`), mdContent);
79401
79536
  if (codeEmbeds.length > 0) {
79402
79537
  for (const ce of codeEmbeds) {
79403
79538
  const fpath = ce.filePath ?? ce.filename ?? `${ce.embedId.slice(0, 8)}.${getExtForLang(ce.language)}`;
79404
- const fullPath = join12(tmpDir, "code", fpath);
79539
+ const fullPath = join13(tmpDir, "code", fpath);
79405
79540
  await mkdir2(fullPath.substring(0, fullPath.lastIndexOf("/")), {
79406
79541
  recursive: true
79407
79542
  });
@@ -79409,13 +79544,13 @@ ${deleted}/${resolved.length} chat(s) deleted.`);
79409
79544
  }
79410
79545
  }
79411
79546
  if (transcriptEmbeds.length > 0) {
79412
- const tDir = join12(tmpDir, "transcripts");
79547
+ const tDir = join13(tmpDir, "transcripts");
79413
79548
  await mkdir2(tDir, { recursive: true });
79414
79549
  for (const te of transcriptEmbeds) {
79415
- await writeFile2(join12(tDir, te.filename), te.content);
79550
+ await writeFile2(join13(tDir, te.filename), te.content);
79416
79551
  }
79417
79552
  }
79418
- const zipPath = join12(outputDir, `${filenameBase}.zip`);
79553
+ const zipPath = join13(outputDir, `${filenameBase}.zip`);
79419
79554
  const { execSync: execSync2 } = await import("child_process");
79420
79555
  try {
79421
79556
  execSync2(`cd "${tmpDir}" && zip -r "${zipPath}" .`, { stdio: "pipe" });
@@ -79430,17 +79565,17 @@ ${deleted}/${resolved.length} chat(s) deleted.`);
79430
79565
  );
79431
79566
  }
79432
79567
  } else {
79433
- const chatDir = join12(outputDir, filenameBase);
79568
+ const chatDir = join13(outputDir, filenameBase);
79434
79569
  await mkdir2(chatDir, { recursive: true });
79435
79570
  const written = [];
79436
- await writeFile2(join12(chatDir, `${filenameBase}.yml`), yamlContent);
79571
+ await writeFile2(join13(chatDir, `${filenameBase}.yml`), yamlContent);
79437
79572
  written.push(`${filenameBase}.yml`);
79438
- await writeFile2(join12(chatDir, `${filenameBase}.md`), mdContent);
79573
+ await writeFile2(join13(chatDir, `${filenameBase}.md`), mdContent);
79439
79574
  written.push(`${filenameBase}.md`);
79440
79575
  if (codeEmbeds.length > 0) {
79441
79576
  for (const ce of codeEmbeds) {
79442
79577
  const fpath = ce.filePath ?? ce.filename ?? `${ce.embedId.slice(0, 8)}.${getExtForLang(ce.language)}`;
79443
- const fullPath = join12(chatDir, "code", fpath);
79578
+ const fullPath = join13(chatDir, "code", fpath);
79444
79579
  await mkdir2(fullPath.substring(0, fullPath.lastIndexOf("/")), {
79445
79580
  recursive: true
79446
79581
  });
@@ -79449,10 +79584,10 @@ ${deleted}/${resolved.length} chat(s) deleted.`);
79449
79584
  }
79450
79585
  }
79451
79586
  if (transcriptEmbeds.length > 0) {
79452
- const tDir = join12(chatDir, "transcripts");
79587
+ const tDir = join13(chatDir, "transcripts");
79453
79588
  await mkdir2(tDir, { recursive: true });
79454
79589
  for (const te of transcriptEmbeds) {
79455
- await writeFile2(join12(tDir, te.filename), te.content);
79590
+ await writeFile2(join13(tDir, te.filename), te.content);
79456
79591
  written.push(`transcripts/${te.filename}`);
79457
79592
  }
79458
79593
  }
@@ -79488,7 +79623,7 @@ ${deleted}/${resolved.length} chat(s) deleted.`);
79488
79623
  printJson2({
79489
79624
  chat_id: chat.id,
79490
79625
  title: chat.title,
79491
- output_dir: useZip ? join12(outputDir, `${filenameBase}.zip`) : join12(outputDir, filenameBase),
79626
+ output_dir: useZip ? join13(outputDir, `${filenameBase}.zip`) : join13(outputDir, filenameBase),
79492
79627
  files,
79493
79628
  code_embeds: codeEmbeds.length,
79494
79629
  transcript_embeds: transcriptEmbeds.length
@@ -79808,7 +79943,7 @@ function normalizeApiKeyLoadedChat(payload) {
79808
79943
  const messages = rawMessages.map((message) => {
79809
79944
  const messageId = String(message.client_message_id ?? message.message_id ?? message.id ?? "");
79810
79945
  const directEmbedIds = Array.isArray(message.embedIds) ? message.embedIds : Array.isArray(message.embed_ids) ? message.embed_ids : [];
79811
- const hashedMessageId = messageId ? createHash14("sha256").update(messageId).digest("hex") : null;
79946
+ const hashedMessageId = messageId ? createHash15("sha256").update(messageId).digest("hex") : null;
79812
79947
  const matchedEmbedIds = hashedMessageId ? rawEmbeds.filter((embed) => embed.hashed_message_id === hashedMessageId && !embed.parent_embed_id).map((embed) => String(embed.embed_id ?? embed.id ?? "")).filter(Boolean) : [];
79813
79948
  return {
79814
79949
  id: messageId,
@@ -80014,7 +80149,7 @@ async function handleWorkflows(client, subcommand, rest, flags, redactor) {
80014
80149
  if (subcommand === "validate") {
80015
80150
  const file = typeof flags.file === "string" ? flags.file : "";
80016
80151
  if (!file) throw new Error("Missing --file. Example: openmates workflows validate --file workflow.yml");
80017
- const validation = await client.validateWorkflowYaml(readFileSync12(file, "utf8"));
80152
+ const validation = await client.validateWorkflowYaml(readFileSync13(file, "utf8"));
80018
80153
  if (flags.json === true) {
80019
80154
  printJson2(validation);
80020
80155
  } else {
@@ -80030,7 +80165,7 @@ async function handleWorkflows(client, subcommand, rest, flags, redactor) {
80030
80165
  if (subcommand === "create") {
80031
80166
  const yamlFile = typeof flags.file === "string" ? flags.file : "";
80032
80167
  if (yamlFile) {
80033
- const result = await client.createWorkflowYaml(readFileSync12(yamlFile, "utf8"));
80168
+ const result = await client.createWorkflowYaml(readFileSync13(yamlFile, "utf8"));
80034
80169
  if (flags.json === true) {
80035
80170
  printJson2(result);
80036
80171
  } else {
@@ -80064,7 +80199,7 @@ async function handleWorkflows(client, subcommand, rest, flags, redactor) {
80064
80199
  const workflowId = rest[0] ? await requiredResolvedWorkflowId(client, rest[0], flags, "update") : void 0;
80065
80200
  const yamlFile = typeof flags.file === "string" ? flags.file : "";
80066
80201
  if (!workflowId || !yamlFile) throw new Error("Missing workflow ID or --file. Example: openmates workflows update <id> --file workflow.yml");
80067
- const result = await client.updateWorkflowYaml(workflowId, readFileSync12(yamlFile, "utf8"));
80202
+ const result = await client.updateWorkflowYaml(workflowId, readFileSync13(yamlFile, "utf8"));
80068
80203
  if (typeof flags.slug === "string") {
80069
80204
  result.workflow = await client.updateWorkflow(result.workflow.id, { slug: flags.slug });
80070
80205
  }
@@ -80666,7 +80801,7 @@ function buildCodeImageToHtmlRequest(positionals, flags) {
80666
80801
  );
80667
80802
  }
80668
80803
  const request = {
80669
- image_base64: readFileSync12(file).toString("base64"),
80804
+ image_base64: readFileSync13(file).toString("base64"),
80670
80805
  mime_type: inferImageToHtmlMimeType(file),
80671
80806
  filename: file.split(/[\\/]/).pop() ?? file
80672
80807
  };
@@ -81545,7 +81680,7 @@ async function handleEmbeds(client, subcommand, rest, flags) {
81545
81680
  throw new Error("Embed version content was not available after local reconstruction.");
81546
81681
  }
81547
81682
  if (typeof flags.output === "string") {
81548
- writeFileSync10(flags.output, result.content, "utf-8");
81683
+ writeFileSync11(flags.output, result.content, "utf-8");
81549
81684
  if (flags.json === true) {
81550
81685
  printJson2({ ...result, output: flags.output });
81551
81686
  } else {
@@ -82204,10 +82339,10 @@ function parseYamlScalar(value) {
82204
82339
  }
82205
82340
  async function saveDownloadedDocument(document, output) {
82206
82341
  const { mkdir: mkdir2, writeFile: writeFile2 } = await import("fs/promises");
82207
- const { join: join12, basename: basename5, dirname: dirname11 } = await import("path");
82342
+ const { join: join13, basename: basename5, dirname: dirname11 } = await import("path");
82208
82343
  const target = typeof output === "string" ? output : ".";
82209
82344
  const filename = basename5(document.filename || "document.pdf");
82210
- const filePath = target.endsWith(".pdf") ? target : join12(target, filename);
82345
+ const filePath = target.endsWith(".pdf") ? target : join13(target, filename);
82211
82346
  await mkdir2(dirname11(filePath), { recursive: true });
82212
82347
  await writeFile2(filePath, document.data);
82213
82348
  return filePath;
@@ -82380,7 +82515,7 @@ async function handleFinance(client, subcommand, _rest, flags) {
82380
82515
  }
82381
82516
  function readFinanceCsvStatements(flags) {
82382
82517
  const paths = parseCsvFlag(flags.csv) ?? [];
82383
- return paths.map((filePath) => ({ filename: basename4(filePath), content: readFileSync12(filePath, "utf8") }));
82518
+ return paths.map((filePath) => ({ filename: basename4(filePath), content: readFileSync13(filePath, "utf8") }));
82384
82519
  }
82385
82520
  function buildFinanceCheckAccountsInput(flags, csvStatements, connectedAccount) {
82386
82521
  const input = {
@@ -82609,7 +82744,7 @@ async function handleRevolutBusinessConnect(client, rest, flags) {
82609
82744
  if (!clientId.trim()) throw new Error("ClientID is required to connect Revolut Business.");
82610
82745
  const code = providedCode || await promptPlainText("Code from OpenMates callback page: ");
82611
82746
  if (!code.trim()) throw new Error("Authorization code is required to connect Revolut Business.");
82612
- const privateKeyPem = readFileSync12(result.privateKeyPath, "utf8");
82747
+ const privateKeyPem = readFileSync13(result.privateKeyPath, "utf8");
82613
82748
  const setup = await client.exchangeRevolutBusinessSetupCode({
82614
82749
  clientId: clientId.trim(),
82615
82750
  code: code.trim(),
@@ -86197,8 +86332,10 @@ function printTasksHelp() {
86197
86332
  openmates tasks reorder <task-id|short-id> [--before <task-id>] [--after <task-id>] [--position <n>] [--status <status>] [--json]
86198
86333
  openmates tasks dependencies list <task-id|short-id> [--json]
86199
86334
  openmates tasks dependencies add|remove <task-id|short-id> --target plan:<id>|task:<id> [--recovery-root <external-root>] [--json]
86200
- openmates tasks activity list <task-id|short-id> [--limit <n>] [--json]
86201
- openmates tasks activity add <task-id|short-id> --message <text> [--as-assignee] [--json]
86335
+ openmates tasks activity list <task-id|short-id> [--max-entries <1-200>] [--cursor <cursor>] [--newest-first] [--json]
86336
+ openmates tasks activity search <task-id|short-id> --query <text> [--max-entries <1-200>] [--json]
86337
+ openmates tasks activity add <task-id|short-id> --message <text> [--as-assignee] [--delivery-id <sha256>] [--json]
86338
+ openmates tasks activity flush <task-id|short-id> [--as-assignee] [--json]
86202
86339
  openmates tasks activity delete <task-id|short-id> <entry-id> [--json]
86203
86340
 
86204
86341
  Chat-scoped aliases:
@@ -86668,7 +86805,7 @@ async function handleDocs(client, subcommand, rest, flags) {
86668
86805
  }
86669
86806
  if (subcommand === "download") {
86670
86807
  const { writeFile: writeFile2, mkdir: mkdir2 } = await import("fs/promises");
86671
- const { join: join12, dirname: dirname11 } = await import("path");
86808
+ const { join: join13, dirname: dirname11 } = await import("path");
86672
86809
  if (flags.all === true) {
86673
86810
  const outputDir = typeof flags.output === "string" ? flags.output : "./openmates-docs";
86674
86811
  const tree = await client.listDocs();
@@ -86677,7 +86814,7 @@ async function handleDocs(client, subcommand, rest, flags) {
86677
86814
  let count = 0;
86678
86815
  for (const slug2 of slugs) {
86679
86816
  const content2 = await client.getDoc(slug2);
86680
- const filePath = join12(outputDir, `${slug2}.md`);
86817
+ const filePath = join13(outputDir, `${slug2}.md`);
86681
86818
  await mkdir2(dirname11(filePath), { recursive: true });
86682
86819
  await writeFile2(filePath, content2, "utf-8");
86683
86820
  count++;