openmates 0.15.0-alpha.34 → 0.15.0-alpha.36

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.
@@ -706,6 +706,7 @@ import {
706
706
  chmodSync,
707
707
  existsSync as existsSync2,
708
708
  mkdirSync,
709
+ readdirSync,
709
710
  readFileSync as readFileSync2,
710
711
  rmSync,
711
712
  writeFileSync
@@ -1138,6 +1139,30 @@ function deleteLocalTeamKey(hashedEmail, teamId) {
1138
1139
  writeJsonFile(filePath, keys);
1139
1140
  }
1140
1141
  }
1142
+ function pruneLocalTeamArtifacts(hashedEmail, teamIds) {
1143
+ const stateDir = ensureStateDir();
1144
+ const allowedKeyIds = new Set(teamIds.map((teamId) => teamKeyStorageId(hashedEmail, teamId)));
1145
+ const keysFilePath = join(stateDir, LOCAL_TEAM_KEYS_FILE);
1146
+ const keys = readJsonFile(keysFilePath);
1147
+ if (keys) {
1148
+ let changed = false;
1149
+ const prefix = `${hashedEmail}:team:`;
1150
+ for (const storageId of Object.keys(keys.teams)) {
1151
+ if (storageId.startsWith(prefix) && !allowedKeyIds.has(storageId)) {
1152
+ deleteMasterKey("keychain", storageId);
1153
+ delete keys.teams[storageId];
1154
+ changed = true;
1155
+ }
1156
+ }
1157
+ if (changed) writeJsonFile(keysFilePath, keys);
1158
+ }
1159
+ const allowedCacheFiles = new Set(teamIds.map((teamId) => syncCacheFile(teamId)));
1160
+ for (const fileName of readdirSync(stateDir)) {
1161
+ if (fileName.startsWith("sync_cache.team.") && fileName.endsWith(".json") && !allowedCacheFiles.has(fileName)) {
1162
+ rmSync(join(stateDir, fileName), { force: true });
1163
+ }
1164
+ }
1165
+ }
1141
1166
  function syncCacheFile(teamId) {
1142
1167
  if (!teamId) return SYNC_CACHE_FILE;
1143
1168
  const digest = createHash3("sha256").update(teamId).digest("hex").slice(0, 32);
@@ -1628,6 +1653,9 @@ var OpenMatesWsClient = class {
1628
1653
  let recoveryJobId = null;
1629
1654
  let followUpSuggestions = [];
1630
1655
  let newChatSuggestions = [];
1656
+ let chatSummary = null;
1657
+ let chatTags = [];
1658
+ let updatedChatTitle = null;
1631
1659
  let taskProposals = [];
1632
1660
  let taskUpdateProposals = [];
1633
1661
  const taskEvents = [];
@@ -1698,6 +1726,9 @@ var OpenMatesWsClient = class {
1698
1726
  modelName,
1699
1727
  followUpSuggestions,
1700
1728
  newChatSuggestions,
1729
+ chatSummary,
1730
+ chatTags,
1731
+ updatedChatTitle,
1701
1732
  taskProposals,
1702
1733
  taskUpdateProposals,
1703
1734
  taskEvents,
@@ -1731,6 +1762,9 @@ var OpenMatesWsClient = class {
1731
1762
  modelName,
1732
1763
  followUpSuggestions,
1733
1764
  newChatSuggestions,
1765
+ chatSummary,
1766
+ chatTags,
1767
+ updatedChatTitle,
1734
1768
  taskProposals,
1735
1769
  taskUpdateProposals,
1736
1770
  taskEvents,
@@ -1753,6 +1787,9 @@ var OpenMatesWsClient = class {
1753
1787
  modelName,
1754
1788
  followUpSuggestions,
1755
1789
  newChatSuggestions,
1790
+ chatSummary,
1791
+ chatTags,
1792
+ updatedChatTitle,
1756
1793
  taskProposals,
1757
1794
  taskUpdateProposals,
1758
1795
  taskEvents,
@@ -1967,6 +2004,18 @@ var OpenMatesWsClient = class {
1967
2004
  (s) => typeof s === "string" && s.length > 0
1968
2005
  );
1969
2006
  }
2007
+ if (typeof p.chat_summary === "string" && p.chat_summary.trim()) {
2008
+ chatSummary = p.chat_summary.trim();
2009
+ }
2010
+ const rawChatTags = p.chat_tags;
2011
+ if (Array.isArray(rawChatTags) && rawChatTags.length > 0) {
2012
+ chatTags = rawChatTags.filter(
2013
+ (tag) => typeof tag === "string" && tag.trim().length > 0
2014
+ ).slice(0, 10);
2015
+ }
2016
+ if (typeof p.updated_chat_title === "string" && p.updated_chat_title.trim()) {
2017
+ updatedChatTitle = p.updated_chat_title.trim();
2018
+ }
1970
2019
  taskProposals = parseTaskProposals(p.task_proposals);
1971
2020
  taskUpdateProposals = parseTaskUpdateProposals(p.task_update_proposals);
1972
2021
  if (aiResponseDone) {
@@ -1997,6 +2046,9 @@ var OpenMatesWsClient = class {
1997
2046
  modelName,
1998
2047
  followUpSuggestions,
1999
2048
  newChatSuggestions,
2049
+ chatSummary,
2050
+ chatTags,
2051
+ updatedChatTitle,
2000
2052
  taskProposals,
2001
2053
  taskUpdateProposals,
2002
2054
  taskEvents,
@@ -5303,6 +5355,59 @@ var OpenMatesClient = class _OpenMatesClient {
5303
5355
  if (options.teamId !== void 0) return options.teamId;
5304
5356
  return this.getActiveTeamId();
5305
5357
  }
5358
+ async startAccountExport(options = {}) {
5359
+ this.requireSession();
5360
+ const response = await this.http.post("/v1/account-exports", {
5361
+ domains: options.domains,
5362
+ filters: options.filters ?? {},
5363
+ format: options.format ?? "zip",
5364
+ include_advanced_metadata: options.includeAdvancedMetadata === true
5365
+ }, this.getCliRequestHeaders());
5366
+ if (!response.ok) throw new Error(`Account export start failed with HTTP ${response.status}`);
5367
+ return response.data;
5368
+ }
5369
+ async getAccountExport(exportId) {
5370
+ this.requireSession();
5371
+ const response = await this.http.get(`/v1/account-exports/${encodeURIComponent(exportId)}`, this.getCliRequestHeaders());
5372
+ if (!response.ok) throw new Error(`Account export status failed with HTTP ${response.status}`);
5373
+ return response.data;
5374
+ }
5375
+ async getAccountExportManifest(exportId) {
5376
+ this.requireSession();
5377
+ const response = await this.http.get(`/v1/account-exports/${encodeURIComponent(exportId)}/manifest`, this.getCliRequestHeaders());
5378
+ if (!response.ok) throw new Error(`Account export manifest failed with HTTP ${response.status}`);
5379
+ return response.data;
5380
+ }
5381
+ async listAccountExportChunks(exportId) {
5382
+ this.requireSession();
5383
+ const response = await this.http.get(`/v1/account-exports/${encodeURIComponent(exportId)}/chunks`, this.getCliRequestHeaders());
5384
+ if (!response.ok) throw new Error(`Account export chunk list failed with HTTP ${response.status}`);
5385
+ return response.data;
5386
+ }
5387
+ async getAccountExportChunk(exportId, chunkId) {
5388
+ this.requireSession();
5389
+ const response = await this.http.get(`/v1/account-exports/${encodeURIComponent(exportId)}/chunks/${encodeURIComponent(chunkId)}`, this.getCliRequestHeaders());
5390
+ if (!response.ok || !response.data.chunk) throw new Error(`Account export chunk download failed with HTTP ${response.status}`);
5391
+ return response.data.chunk;
5392
+ }
5393
+ async completeAccountExport(exportId) {
5394
+ this.requireSession();
5395
+ const response = await this.http.post(`/v1/account-exports/${encodeURIComponent(exportId)}/complete`, {}, this.getCliRequestHeaders());
5396
+ if (!response.ok) throw new Error(`Account export complete failed with HTTP ${response.status}`);
5397
+ return response.data;
5398
+ }
5399
+ async acceptPartialAccountExport(exportId) {
5400
+ this.requireSession();
5401
+ const response = await this.http.post(`/v1/account-exports/${encodeURIComponent(exportId)}/accept-partial`, {}, this.getCliRequestHeaders());
5402
+ if (!response.ok) throw new Error(`Account export accept partial failed with HTTP ${response.status}`);
5403
+ return response.data;
5404
+ }
5405
+ async cancelAccountExport(exportId) {
5406
+ this.requireSession();
5407
+ const response = await this.http.post(`/v1/account-exports/${encodeURIComponent(exportId)}/cancel`, {}, this.getCliRequestHeaders());
5408
+ if (!response.ok) throw new Error(`Account export cancel failed with HTTP ${response.status}`);
5409
+ return response.data;
5410
+ }
5306
5411
  appendTeamQuery(path, options = {}) {
5307
5412
  const teamId = this.resolveTeamContext(options);
5308
5413
  if (!teamId) return path;
@@ -5315,6 +5420,11 @@ var OpenMatesClient = class _OpenMatesClient {
5315
5420
  if (!response.ok) throw new Error(`Team list failed with HTTP ${response.status}`);
5316
5421
  const teams = response.data.teams ?? [];
5317
5422
  await Promise.all(teams.map((team) => this.cacheTeamKeyFromRecord(team)));
5423
+ const teamIds = teams.map((team) => team.team_id).filter((teamId) => typeof teamId === "string" && teamId.length > 0);
5424
+ pruneLocalTeamArtifacts(this.requireSession().hashedEmail, teamIds);
5425
+ if (this.session?.activeTeamId && !teamIds.includes(this.session.activeTeamId)) {
5426
+ this.setActiveTeamId(null);
5427
+ }
5318
5428
  return teams;
5319
5429
  }
5320
5430
  async createTeam(input) {
@@ -7245,8 +7355,9 @@ var OpenMatesClient = class _OpenMatesClient {
7245
7355
  inference_request: messagePayload
7246
7356
  };
7247
7357
  if (isNewChat) {
7358
+ const initialTitle = teamId && !shouldWaitForAi ? "New team chat" : "";
7248
7359
  preflightPayload.encrypted_chat_metadata = {
7249
- encrypted_title: await encryptWithAesGcmCombined("", chatKeyBytes),
7360
+ encrypted_title: await encryptWithAesGcmCombined(initialTitle, chatKeyBytes),
7250
7361
  encrypted_chat_key: encryptedChatKey,
7251
7362
  created_at: createdAt,
7252
7363
  updated_at: createdAt
@@ -7296,6 +7407,9 @@ var OpenMatesClient = class _OpenMatesClient {
7296
7407
  if (!params.incognito && typeof confirmedPayload.new_messages_v === "number" && Number.isSafeInteger(confirmedPayload.new_messages_v)) {
7297
7408
  terminalExpectedMessagesV = confirmedPayload.new_messages_v;
7298
7409
  }
7410
+ if (!params.incognito) {
7411
+ clearSyncCache(teamId);
7412
+ }
7299
7413
  let assistant = "";
7300
7414
  let assistantMessageId = null;
7301
7415
  let category = null;
@@ -7710,6 +7824,9 @@ var OpenMatesClient = class _OpenMatesClient {
7710
7824
  chatKeyBytes,
7711
7825
  followUpSuggestions: resp.followUpSuggestions,
7712
7826
  newChatSuggestions: resp.newChatSuggestions,
7827
+ chatSummary: resp.chatSummary,
7828
+ chatTags: resp.chatTags,
7829
+ updatedChatTitle: resp.updatedChatTitle,
7713
7830
  encryptedChatKey
7714
7831
  });
7715
7832
  const persistedTaskJobIds = await this.persistPendingTaskUpdateJobs({
@@ -8148,12 +8265,18 @@ var OpenMatesClient = class _OpenMatesClient {
8148
8265
  (suggestion) => encryptWithAesGcmCombined(suggestion, masterKey)
8149
8266
  )
8150
8267
  );
8151
- if (!encryptedFollowUps && encryptedNewChatSuggestions.length === 0) return;
8268
+ const encryptedChatSummary = params.chatSummary ? await encryptWithAesGcmCombined(params.chatSummary, params.chatKeyBytes) : "";
8269
+ const encryptedChatTags = params.chatTags.length > 0 ? await encryptWithAesGcmCombined(JSON.stringify(params.chatTags.slice(0, 10)), params.chatKeyBytes) : "";
8270
+ const encryptedUpdatedTitle = params.updatedChatTitle ? await encryptWithAesGcmCombined(params.updatedChatTitle, params.chatKeyBytes) : "";
8271
+ if (!encryptedFollowUps && encryptedNewChatSuggestions.length === 0 && !encryptedChatSummary && !encryptedChatTags && !encryptedUpdatedTitle) return;
8152
8272
  await params.ws.sendAsync("update_post_processing_metadata", {
8153
8273
  chat_id: params.chatId,
8154
8274
  ...params.teamId ? { team_id: params.teamId } : {},
8155
8275
  encrypted_follow_up_suggestions: encryptedFollowUps,
8156
8276
  encrypted_new_chat_suggestions: encryptedNewChatSuggestions,
8277
+ encrypted_chat_summary: encryptedChatSummary,
8278
+ encrypted_chat_tags: encryptedChatTags,
8279
+ encrypted_title: encryptedUpdatedTitle,
8157
8280
  encrypted_chat_key: params.encryptedChatKey ?? ""
8158
8281
  });
8159
8282
  await params.ws.waitForMessage(
@@ -15799,6 +15922,53 @@ var OpenMatesAccount = class {
15799
15922
  async clearInterests() {
15800
15923
  return this.setInterests([]);
15801
15924
  }
15925
+ async startExport(options = {}) {
15926
+ return this.client.request("/v1/account-exports", {
15927
+ domains: options.domains,
15928
+ filters: options.filters ?? {},
15929
+ format: options.format ?? "zip",
15930
+ include_advanced_metadata: options.includeAdvancedMetadata === true
15931
+ });
15932
+ }
15933
+ async getExport(exportId) {
15934
+ return this.client.get(`/v1/account-exports/${encodeURIComponent(exportId)}`);
15935
+ }
15936
+ async exportJobManifest(exportId) {
15937
+ return this.client.get(`/v1/account-exports/${encodeURIComponent(exportId)}/manifest`);
15938
+ }
15939
+ async exportChunks(exportId) {
15940
+ return this.client.get(`/v1/account-exports/${encodeURIComponent(exportId)}/chunks`);
15941
+ }
15942
+ async exportChunk(exportId, chunkId) {
15943
+ const result = await this.client.get(`/v1/account-exports/${encodeURIComponent(exportId)}/chunks/${encodeURIComponent(chunkId)}`);
15944
+ return result.chunk ?? {};
15945
+ }
15946
+ async *iterExportChunks(exportId) {
15947
+ const listed = await this.exportChunks(exportId);
15948
+ for (const chunk of listed.chunks) {
15949
+ const chunkId = String(chunk.chunk_id ?? "");
15950
+ yield chunkId ? await this.exportChunk(exportId, chunkId) : chunk;
15951
+ }
15952
+ }
15953
+ async completeExport(exportId) {
15954
+ return this.client.request(`/v1/account-exports/${encodeURIComponent(exportId)}/complete`, {});
15955
+ }
15956
+ async acceptPartialExport(exportId) {
15957
+ return this.client.request(`/v1/account-exports/${encodeURIComponent(exportId)}/accept-partial`, {});
15958
+ }
15959
+ async cancelExport(exportId) {
15960
+ return this.client.request(`/v1/account-exports/${encodeURIComponent(exportId)}/cancel`, {});
15961
+ }
15962
+ async downloadExport(options = {}) {
15963
+ const started = await this.startExport(options);
15964
+ const exportId = String(started.export.export_id ?? "");
15965
+ const [manifest, chunks] = await Promise.all([
15966
+ this.exportJobManifest(exportId),
15967
+ this.exportChunks(exportId)
15968
+ ]);
15969
+ const completed = await this.completeExport(exportId);
15970
+ return { export: completed.export, manifest: manifest.manifest, chunks: chunks.chunks };
15971
+ }
15802
15972
  async exportManifest() {
15803
15973
  return this.client.get("/v1/sdk/account/export/manifest");
15804
15974
  }
@@ -18890,7 +19060,7 @@ function formatTs(ts) {
18890
19060
  // src/server.ts
18891
19061
  import { execFileSync as execFileSync2, execSync, spawn as nodeSpawn, spawnSync } from "child_process";
18892
19062
  import { createHash as createHash10, randomBytes as randomBytes5 } from "crypto";
18893
- import { chmodSync as chmodSync3, closeSync, copyFileSync, cpSync, existsSync as existsSync7, mkdirSync as mkdirSync4, mkdtempSync, openSync, readFileSync as readFileSync6, readSync, readdirSync, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
19063
+ import { chmodSync as chmodSync3, closeSync, copyFileSync, cpSync, existsSync as existsSync7, mkdirSync as mkdirSync4, mkdtempSync, openSync, readFileSync as readFileSync6, readSync, readdirSync as readdirSync2, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
18894
19064
  import { createInterface as createInterface3 } from "readline";
18895
19065
  import { createInterface as createPromptInterface } from "readline/promises";
18896
19066
  import { homedir as homedir6 } from "os";
@@ -19957,7 +20127,7 @@ function hashFile(path) {
19957
20127
  function writeChecksums(rootDir) {
19958
20128
  const lines = [];
19959
20129
  const walk = (dir) => {
19960
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
20130
+ for (const entry of readdirSync2(dir, { withFileTypes: true })) {
19961
20131
  const path = join4(dir, entry.name);
19962
20132
  if (entry.isDirectory()) {
19963
20133
  walk(path);
@@ -21024,7 +21194,7 @@ async function serverBackup(rest, flags) {
21024
21194
  const role = getServerRole(flags, config);
21025
21195
  if (action === "list") {
21026
21196
  const dir = roleBackupDir(installPath, role);
21027
- const files = existsSync7(dir) ? readdirSync(dir).filter((item) => item.endsWith(".tar.gz")).sort() : [];
21197
+ const files = existsSync7(dir) ? readdirSync2(dir).filter((item) => item.endsWith(".tar.gz")).sort() : [];
21028
21198
  if (flags.json === true) {
21029
21199
  printJson({ role, backupDir: dir, files });
21030
21200
  return;
@@ -56672,7 +56842,7 @@ function buildAssistantFeedbackDecision(rating) {
56672
56842
 
56673
56843
  // src/benchmark.ts
56674
56844
  import { randomUUID as randomUUID7 } from "crypto";
56675
- import { existsSync as existsSync8, mkdtempSync as mkdtempSync2, readFileSync as readFileSync7, readdirSync as readdirSync2, writeFileSync as writeFileSync5 } from "fs";
56845
+ import { existsSync as existsSync8, mkdtempSync as mkdtempSync2, readFileSync as readFileSync7, readdirSync as readdirSync3, writeFileSync as writeFileSync5 } from "fs";
56676
56846
  import { tmpdir } from "os";
56677
56847
  import { dirname as dirname4, join as join5, resolve as resolve5 } from "path";
56678
56848
  import { fileURLToPath } from "url";
@@ -57471,7 +57641,7 @@ function loadProviderPricing() {
57471
57641
  const providersDir = findProvidersDir();
57472
57642
  const pricing = /* @__PURE__ */ new Map();
57473
57643
  if (!providersDir) return pricing;
57474
- for (const fileName of readdirSync2(providersDir)) {
57644
+ for (const fileName of readdirSync3(providersDir)) {
57475
57645
  if (!fileName.endsWith(".yml")) continue;
57476
57646
  const filePath = join5(providersDir, fileName);
57477
57647
  const text = readFileSync7(filePath, "utf-8");
@@ -59522,6 +59692,10 @@ async function main() {
59522
59692
  printSettingsHelp(client);
59523
59693
  return;
59524
59694
  }
59695
+ if (command === "account") {
59696
+ printSettingsHelp(client, ["account"]);
59697
+ return;
59698
+ }
59525
59699
  if (command === "workflows") {
59526
59700
  printWorkflowsHelp();
59527
59701
  return;
@@ -59684,6 +59858,10 @@ async function main() {
59684
59858
  await handleSettings(client, subcommand, rest, parsed.flags);
59685
59859
  return;
59686
59860
  }
59861
+ if (command === "account") {
59862
+ await handleSettings(client, "account", [subcommand, ...rest].filter((part) => typeof part === "string"), parsed.flags);
59863
+ return;
59864
+ }
59687
59865
  if (command === "workflows") {
59688
59866
  await handleWorkflows(client, subcommand, rest, parsed.flags);
59689
59867
  return;
@@ -62676,8 +62854,12 @@ var SETTINGS_EXECUTABLE_COMMANDS = [
62676
62854
  { path: ["account", "interests", "list"], description: "Show encrypted account topic interests", examples: ["openmates settings account interests list --json"] },
62677
62855
  { path: ["account", "interests", "set"], description: "Set encrypted account topic interests", examples: ["openmates settings account interests set software_development run_code privacy"] },
62678
62856
  { path: ["account", "interests", "clear"], description: "Clear encrypted account topic interests", examples: ["openmates settings account interests clear --yes"] },
62679
- { path: ["account", "export", "manifest"], description: "Show account export manifest", examples: ["openmates settings account export manifest --json"] },
62680
- { path: ["account", "export", "data"], description: "Fetch account export data", examples: ["openmates settings account export data --json"] },
62857
+ { path: ["account", "export"], description: "Start a complete Account Export V1 job", examples: ["openmates account export --output ./openmates-export.json", "openmates settings account export --domains chats,usage --json"] },
62858
+ { path: ["account", "export", "start"], description: "Start a complete Account Export V1 job", examples: ["openmates settings account export start --output ./openmates-export.json"] },
62859
+ { path: ["account", "export", "status"], description: "Show account export job status", examples: ["openmates settings account export status <export-id> --json"] },
62860
+ { path: ["account", "export", "manifest"], description: "Show account export manifest", examples: ["openmates settings account export manifest <export-id> --json"] },
62861
+ { path: ["account", "export", "chunks"], description: "List account export chunks", examples: ["openmates settings account export chunks <export-id> --json"] },
62862
+ { path: ["account", "export", "data"], description: "Fetch account export chunks", examples: ["openmates settings account export data <export-id> --json"] },
62681
62863
  { path: ["account", "import-chat"], description: "Import a CLI chat export file", examples: ["openmates settings account import-chat ./chat.yml", "openmates settings account import-chat ./payload.json"] },
62682
62864
  { path: ["account", "username", "set"], description: "Change account username", examples: ["openmates settings account username set alice_123"] },
62683
62865
  { path: ["account", "profile-picture", "set"], description: "Upload a profile picture", examples: ["openmates settings account profile-picture set ./avatar.jpg"] },
@@ -62768,6 +62950,47 @@ async function printSettingsResult(resultPromise, flags) {
62768
62950
  printGenericObject(result);
62769
62951
  }
62770
62952
  }
62953
+ function parseCsvFlag(value) {
62954
+ if (typeof value !== "string") return void 0;
62955
+ const items = value.split(",").map((item) => item.trim()).filter(Boolean);
62956
+ return items.length > 0 ? items : void 0;
62957
+ }
62958
+ async function runAccountExport(client, flags) {
62959
+ const filters = typeof flags.filters === "string" ? parseJsonFlag(flags.filters, "--filters") : {};
62960
+ const started = await client.startAccountExport({
62961
+ domains: parseCsvFlag(flags.domains),
62962
+ filters,
62963
+ format: flags.format === "directory" ? "directory" : "zip",
62964
+ includeAdvancedMetadata: flags["include-advanced-metadata"] === true
62965
+ });
62966
+ const exportRecord = started.export;
62967
+ const exportId = String(exportRecord.export_id ?? "");
62968
+ const [manifest, chunks] = await Promise.all([
62969
+ client.getAccountExportManifest(exportId),
62970
+ client.listAccountExportChunks(exportId)
62971
+ ]);
62972
+ const completed = await client.completeAccountExport(exportId);
62973
+ return {
62974
+ export: completed.export,
62975
+ manifest: manifest.manifest,
62976
+ chunks: chunks.chunks
62977
+ };
62978
+ }
62979
+ function printAccountExportBundle(bundle, flags) {
62980
+ if (typeof flags.output === "string") {
62981
+ writeFileSync7(flags.output, `${JSON.stringify(bundle, null, 2)}
62982
+ `, "utf-8");
62983
+ }
62984
+ if (flags.json === true) {
62985
+ printJson2(typeof flags.output === "string" ? { ...bundle, output: flags.output } : bundle);
62986
+ return;
62987
+ }
62988
+ const exportRecord = bundle.export && typeof bundle.export === "object" ? bundle.export : {};
62989
+ process.stdout.write(`Account export ${String(exportRecord.export_id ?? "")} ${String(exportRecord.status ?? "unknown")}
62990
+ `);
62991
+ if (typeof flags.output === "string") process.stdout.write(`Wrote ${flags.output}
62992
+ `);
62993
+ }
62771
62994
  function printApiKeyList(result, flags) {
62772
62995
  if (flags.json === true) {
62773
62996
  printJson2(result);
@@ -63478,12 +63701,38 @@ async function handleSettings(client, subcommand, rest, flags) {
63478
63701
  printTopicPreferences(preferences, flags, "Interests cleared");
63479
63702
  return;
63480
63703
  }
63704
+ if (matches(tokens, ["account", "export"]) || matches(tokens, ["account", "export", "start"])) {
63705
+ printAccountExportBundle(await runAccountExport(client, flags), flags);
63706
+ return;
63707
+ }
63708
+ if (matches(tokens, ["account", "export", "status"])) {
63709
+ const exportId = rest[2];
63710
+ if (!exportId) throw new Error("Missing export ID. Example: openmates settings account export status <export-id>");
63711
+ await printSettingsResult(client.getAccountExport(exportId), flags);
63712
+ return;
63713
+ }
63481
63714
  if (matches(tokens, ["account", "export", "manifest"])) {
63482
- await printSettingsResult(client.settingsGet("export-account-manifest"), flags);
63715
+ const exportId = rest[2];
63716
+ if (!exportId) {
63717
+ await printSettingsResult(client.settingsGet("export-account-manifest"), flags);
63718
+ return;
63719
+ }
63720
+ await printSettingsResult(client.getAccountExportManifest(exportId), flags);
63721
+ return;
63722
+ }
63723
+ if (matches(tokens, ["account", "export", "chunks"])) {
63724
+ const exportId = rest[2];
63725
+ if (!exportId) throw new Error("Missing export ID. Example: openmates settings account export chunks <export-id>");
63726
+ await printSettingsResult(client.listAccountExportChunks(exportId), flags);
63483
63727
  return;
63484
63728
  }
63485
63729
  if (matches(tokens, ["account", "export", "data"])) {
63486
- await printSettingsResult(client.settingsGet("export-account-data"), flags);
63730
+ const exportId = rest[2];
63731
+ if (!exportId) {
63732
+ await printSettingsResult(client.settingsGet("export-account-data"), flags);
63733
+ return;
63734
+ }
63735
+ await printSettingsResult(client.listAccountExportChunks(exportId), flags);
63487
63736
  return;
63488
63737
  }
63489
63738
  if (matches(tokens, ["account", "import-chat"])) {
@@ -64406,14 +64655,18 @@ async function sendMessageStreaming(client, params, redactor) {
64406
64655
  };
64407
64656
  const preparedEmbeds = [];
64408
64657
  let finalMessage = params.message;
64658
+ const isTeamAiTrigger = params.personal !== true && (typeof params.teamId === "string" || Boolean(client.getActiveTeamId()));
64409
64659
  if (params.message.includes("@")) {
64410
64660
  try {
64411
64661
  const mentionCtx = await client.buildMentionContext();
64412
64662
  const parsed = parseMentions(params.message, mentionCtx);
64413
64663
  finalMessage = parsed.processedMessage;
64414
- if (parsed.unresolved.length > 0) {
64664
+ const unresolvedMentions = parsed.unresolved.filter(
64665
+ (mention) => !(isTeamAiTrigger && mention.original.toLowerCase() === "@openmates")
64666
+ );
64667
+ if (unresolvedMentions.length > 0) {
64415
64668
  clearTyping();
64416
- for (const u of parsed.unresolved) {
64669
+ for (const u of unresolvedMentions) {
64417
64670
  process.stderr.write(
64418
64671
  `\x1B[31mError:\x1B[0m Unknown mention ${u.original}
64419
64672
  `
@@ -64582,6 +64835,9 @@ async function sendMessageStreaming(client, params, redactor) {
64582
64835
  } catch {
64583
64836
  }
64584
64837
  }
64838
+ if (isTeamAiTrigger && params.message.toLowerCase().includes("@openmates") && !finalMessage.toLowerCase().includes("@openmates")) {
64839
+ finalMessage = `@openmates ${finalMessage}`.trim();
64840
+ }
64585
64841
  const piiResult = params.piiDetection !== false && redactor?.isInitialized ? redactor.redactWithMappings(finalMessage) : { redacted: finalMessage, mappings: [] };
64586
64842
  finalMessage = piiResult.redacted;
64587
64843
  if (!client.hasSession()) {
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  getExtForLang,
4
4
  serializeToYaml
5
- } from "./chunk-ASTZUBZU.js";
5
+ } from "./chunk-BEKDFMUN.js";
6
6
  import "./chunk-AXNRPVLE.js";
7
7
  export {
8
8
  getExtForLang,
package/dist/index.d.ts CHANGED
@@ -216,6 +216,9 @@ declare class OpenMatesWsClient {
216
216
  modelName: string | null;
217
217
  followUpSuggestions: string[];
218
218
  newChatSuggestions: string[];
219
+ chatSummary: string | null;
220
+ chatTags: string[];
221
+ updatedChatTitle: string | null;
219
222
  taskProposals: TaskProposalEvent[];
220
223
  taskUpdateProposals: TaskUpdateProposalEvent[];
221
224
  taskEvents: TaskEventFrame[];
@@ -475,6 +478,21 @@ interface TeamContextOptions {
475
478
  teamId?: string | null;
476
479
  personal?: boolean;
477
480
  }
481
+ interface AccountExportStartOptions$1 {
482
+ domains?: string[];
483
+ filters?: Record<string, unknown>;
484
+ format?: "zip" | "directory";
485
+ includeAdvancedMetadata?: boolean;
486
+ }
487
+ interface AccountExportResponse$1 {
488
+ export: Record<string, unknown>;
489
+ }
490
+ interface AccountExportManifestResponse$1 {
491
+ manifest: Record<string, unknown>;
492
+ }
493
+ interface AccountExportChunksResponse$1 {
494
+ chunks: Array<Record<string, unknown>>;
495
+ }
478
496
  interface TeamCreateInput {
479
497
  name?: string;
480
498
  description?: string | null;
@@ -1246,6 +1264,14 @@ declare class OpenMatesClient {
1246
1264
  getActiveTeamId(): string | null;
1247
1265
  setActiveTeamId(teamId: string | null): void;
1248
1266
  resolveTeamContext(options?: TeamContextOptions): string | null;
1267
+ startAccountExport(options?: AccountExportStartOptions$1): Promise<AccountExportResponse$1>;
1268
+ getAccountExport(exportId: string): Promise<AccountExportResponse$1>;
1269
+ getAccountExportManifest(exportId: string): Promise<AccountExportManifestResponse$1>;
1270
+ listAccountExportChunks(exportId: string): Promise<AccountExportChunksResponse$1>;
1271
+ getAccountExportChunk(exportId: string, chunkId: string): Promise<Record<string, unknown>>;
1272
+ completeAccountExport(exportId: string): Promise<AccountExportResponse$1>;
1273
+ acceptPartialAccountExport(exportId: string): Promise<AccountExportResponse$1>;
1274
+ cancelAccountExport(exportId: string): Promise<AccountExportResponse$1>;
1249
1275
  private appendTeamQuery;
1250
1276
  listTeams(): Promise<TeamRecord[]>;
1251
1277
  createTeam(input: TeamCreateInput): Promise<TeamRecord>;
@@ -5133,6 +5159,21 @@ interface ConfirmedMutationOptions {
5133
5159
  interface RequestOptions {
5134
5160
  query?: Record<string, string | number | boolean | undefined | null>;
5135
5161
  }
5162
+ interface AccountExportStartOptions {
5163
+ domains?: string[];
5164
+ filters?: Record<string, unknown>;
5165
+ format?: "zip" | "directory";
5166
+ includeAdvancedMetadata?: boolean;
5167
+ }
5168
+ interface AccountExportResponse {
5169
+ export: Record<string, unknown>;
5170
+ }
5171
+ interface AccountExportManifestResponse {
5172
+ manifest: Record<string, unknown>;
5173
+ }
5174
+ interface AccountExportChunksResponse {
5175
+ chunks: Array<Record<string, unknown>>;
5176
+ }
5136
5177
  interface ApiKeyCreateOptions {
5137
5178
  name: string;
5138
5179
  fullAccess?: boolean;
@@ -5384,6 +5425,16 @@ declare class OpenMatesAccount {
5384
5425
  listInterests(): Promise<Record<string, unknown>>;
5385
5426
  setInterests(selectedTagIds: string[]): Promise<Record<string, unknown>>;
5386
5427
  clearInterests(): Promise<Record<string, unknown>>;
5428
+ startExport(options?: AccountExportStartOptions): Promise<AccountExportResponse>;
5429
+ getExport(exportId: string): Promise<AccountExportResponse>;
5430
+ exportJobManifest(exportId: string): Promise<AccountExportManifestResponse>;
5431
+ exportChunks(exportId: string): Promise<AccountExportChunksResponse>;
5432
+ exportChunk(exportId: string, chunkId: string): Promise<Record<string, unknown>>;
5433
+ iterExportChunks(exportId: string): AsyncGenerator<Record<string, unknown>>;
5434
+ completeExport(exportId: string): Promise<AccountExportResponse>;
5435
+ acceptPartialExport(exportId: string): Promise<AccountExportResponse>;
5436
+ cancelExport(exportId: string): Promise<AccountExportResponse>;
5437
+ downloadExport(options?: AccountExportStartOptions): Promise<Record<string, unknown>>;
5387
5438
  exportManifest(): Promise<Record<string, unknown>>;
5388
5439
  exportData(): Promise<Record<string, unknown>>;
5389
5440
  setUsername(username: string): Promise<Record<string, unknown>>;
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  reconcileAuthoritativeChats,
19
19
  renderSupportInfo,
20
20
  serializeToYaml
21
- } from "./chunk-ASTZUBZU.js";
21
+ } from "./chunk-BEKDFMUN.js";
22
22
  import "./chunk-AXNRPVLE.js";
23
23
  export {
24
24
  APP_SKILL_METADATA,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openmates",
3
- "version": "0.15.0-alpha.34",
3
+ "version": "0.15.0-alpha.36",
4
4
  "description": "OpenMates CLI and SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",