openmates 0.11.0-alpha.6 → 0.11.0-alpha.7
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.
- package/dist/{chunk-NU4XR6MF.js → chunk-T77MVTFX.js} +492 -224
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +1 -8
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -180,8 +180,8 @@ var OpenMatesHttpClient = class {
|
|
|
180
180
|
async post(path, body, headers = {}) {
|
|
181
181
|
return this.request("POST", path, body, headers);
|
|
182
182
|
}
|
|
183
|
-
async delete(path, headers = {}) {
|
|
184
|
-
return this.request("DELETE", path,
|
|
183
|
+
async delete(path, body, headers = {}) {
|
|
184
|
+
return this.request("DELETE", path, body, headers);
|
|
185
185
|
}
|
|
186
186
|
async patch(path, body, headers = {}) {
|
|
187
187
|
return this.request("PATCH", path, body, headers);
|
|
@@ -603,18 +603,6 @@ function buildSession(onDisk, masterKey) {
|
|
|
603
603
|
autoLogoutMinutes: onDisk.autoLogoutMinutes
|
|
604
604
|
};
|
|
605
605
|
}
|
|
606
|
-
function loadIncognitoHistory() {
|
|
607
|
-
const filePath = join(ensureStateDir(), "incognito.json");
|
|
608
|
-
return readJsonFile(filePath) ?? [];
|
|
609
|
-
}
|
|
610
|
-
function saveIncognitoHistory(items) {
|
|
611
|
-
const filePath = join(ensureStateDir(), "incognito.json");
|
|
612
|
-
writeJsonFile(filePath, items);
|
|
613
|
-
}
|
|
614
|
-
function clearIncognitoHistory() {
|
|
615
|
-
const filePath = join(ensureStateDir(), "incognito.json");
|
|
616
|
-
writeJsonFile(filePath, []);
|
|
617
|
-
}
|
|
618
606
|
var SYNC_CACHE_FILE = "sync_cache.json";
|
|
619
607
|
function saveSyncCache(cache) {
|
|
620
608
|
const filePath = join(ensureStateDir(), SYNC_CACHE_FILE);
|
|
@@ -1718,7 +1706,11 @@ var BLOCKED_SETTINGS_MUTATE_PATHS = /* @__PURE__ */ new Set([
|
|
|
1718
1706
|
"/v1/auth/setup_password",
|
|
1719
1707
|
"/v1/auth/2fa/setup/initiate",
|
|
1720
1708
|
"/v1/auth/2fa/setup/provider",
|
|
1721
|
-
"/v1/auth/2fa/setup/verify-signup"
|
|
1709
|
+
"/v1/auth/2fa/setup/verify-signup",
|
|
1710
|
+
"/v1/settings/delete-account",
|
|
1711
|
+
"/v1/settings/request-action-verification",
|
|
1712
|
+
"/v1/settings/verify-action-code",
|
|
1713
|
+
"/v1/settings/user/disable-2fa"
|
|
1722
1714
|
]);
|
|
1723
1715
|
var OpenMatesClient = class _OpenMatesClient {
|
|
1724
1716
|
apiUrl;
|
|
@@ -1834,7 +1826,6 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
1834
1826
|
await this.http.post("/v1/auth/logout", {}, this.getCliRequestHeaders()).catch(() => void 0);
|
|
1835
1827
|
}
|
|
1836
1828
|
clearSession();
|
|
1837
|
-
clearIncognitoHistory();
|
|
1838
1829
|
}
|
|
1839
1830
|
// -------------------------------------------------------------------------
|
|
1840
1831
|
// Chats
|
|
@@ -2375,12 +2366,6 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
2375
2366
|
let followUpSuggestions = [];
|
|
2376
2367
|
const streamOpts = { onStream: params.onStream };
|
|
2377
2368
|
if (params.incognito) {
|
|
2378
|
-
const history = loadIncognitoHistory();
|
|
2379
|
-
history.push({
|
|
2380
|
-
role: "user",
|
|
2381
|
-
content: params.message,
|
|
2382
|
-
createdAt: Date.now()
|
|
2383
|
-
});
|
|
2384
2369
|
try {
|
|
2385
2370
|
const resp = await ws.collectAiResponse(messageId, chatId, streamOpts);
|
|
2386
2371
|
assistant = resp.content;
|
|
@@ -2389,12 +2374,6 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
2389
2374
|
} finally {
|
|
2390
2375
|
ws.close();
|
|
2391
2376
|
}
|
|
2392
|
-
history.push({
|
|
2393
|
-
role: "assistant",
|
|
2394
|
-
content: assistant,
|
|
2395
|
-
createdAt: Date.now()
|
|
2396
|
-
});
|
|
2397
|
-
saveIncognitoHistory(history);
|
|
2398
2377
|
} else {
|
|
2399
2378
|
try {
|
|
2400
2379
|
const resp = await ws.collectAiResponse(messageId, chatId, streamOpts);
|
|
@@ -2416,12 +2395,6 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
2416
2395
|
followUpSuggestions
|
|
2417
2396
|
};
|
|
2418
2397
|
}
|
|
2419
|
-
getIncognitoHistory() {
|
|
2420
|
-
return loadIncognitoHistory();
|
|
2421
|
-
}
|
|
2422
|
-
clearIncognitoHistory() {
|
|
2423
|
-
clearIncognitoHistory();
|
|
2424
|
-
}
|
|
2425
2398
|
/**
|
|
2426
2399
|
* Delete a chat by ID.
|
|
2427
2400
|
*
|
|
@@ -2734,7 +2707,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
2734
2707
|
}
|
|
2735
2708
|
return response.data;
|
|
2736
2709
|
}
|
|
2737
|
-
async settingsDelete(path) {
|
|
2710
|
+
async settingsDelete(path, body) {
|
|
2738
2711
|
this.requireSession();
|
|
2739
2712
|
const normalizedPath = this.normalizePath(path);
|
|
2740
2713
|
if (BLOCKED_SETTINGS_MUTATE_PATHS.has(normalizedPath)) {
|
|
@@ -2742,6 +2715,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
2742
2715
|
}
|
|
2743
2716
|
const response = await this.http.delete(
|
|
2744
2717
|
normalizedPath,
|
|
2718
|
+
body,
|
|
2745
2719
|
this.getCliRequestHeaders()
|
|
2746
2720
|
);
|
|
2747
2721
|
if (!response.ok) {
|
|
@@ -3921,8 +3895,8 @@ var SecretRegistry = class {
|
|
|
3921
3895
|
const sortedResults = [];
|
|
3922
3896
|
for (const result of results) {
|
|
3923
3897
|
const endIdx = result[0];
|
|
3924
|
-
const
|
|
3925
|
-
for (const match of
|
|
3898
|
+
const matches2 = result[1];
|
|
3899
|
+
for (const match of matches2) {
|
|
3926
3900
|
sortedResults.push({ endIndex: endIdx, match });
|
|
3927
3901
|
}
|
|
3928
3902
|
}
|
|
@@ -6821,17 +6795,11 @@ Run 'openmates chats show ` + chatId + "' to check if suggestions have been save
|
|
|
6821
6795
|
return;
|
|
6822
6796
|
}
|
|
6823
6797
|
if (subcommand === "incognito-history") {
|
|
6824
|
-
|
|
6825
|
-
if (flags.json === true) {
|
|
6826
|
-
printJson2(history);
|
|
6827
|
-
} else {
|
|
6828
|
-
printIncognitoHistory(history);
|
|
6829
|
-
}
|
|
6798
|
+
printIncognitoNoHistoryNotice(flags.json === true);
|
|
6830
6799
|
return;
|
|
6831
6800
|
}
|
|
6832
6801
|
if (subcommand === "incognito-clear") {
|
|
6833
|
-
|
|
6834
|
-
console.log("Incognito history cleared.");
|
|
6802
|
+
printIncognitoNoHistoryNotice(flags.json === true);
|
|
6835
6803
|
return;
|
|
6836
6804
|
}
|
|
6837
6805
|
if (subcommand === "show") {
|
|
@@ -7699,125 +7667,472 @@ async function handleEmbeds(client, subcommand, rest, flags) {
|
|
|
7699
7667
|
printEmbedsHelp();
|
|
7700
7668
|
process.exit(1);
|
|
7701
7669
|
}
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
7670
|
+
var SETTINGS_EXECUTABLE_COMMANDS = [
|
|
7671
|
+
{ path: ["account", "info"], description: "Show account info", examples: ["openmates settings account info --json"] },
|
|
7672
|
+
{ path: ["account", "timezone", "set"], description: "Set account timezone", examples: ["openmates settings account timezone set Europe/Berlin"] },
|
|
7673
|
+
{ path: ["account", "export", "manifest"], description: "Show account export manifest", examples: ["openmates settings account export manifest --json"] },
|
|
7674
|
+
{ path: ["account", "export", "data"], description: "Fetch account export data", examples: ["openmates settings account export data --json"] },
|
|
7675
|
+
{ 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"] },
|
|
7676
|
+
{ path: ["account", "chats", "stats"], description: "Show chat statistics", examples: ["openmates settings account chats stats"] },
|
|
7677
|
+
{ path: ["account", "delete", "preview"], description: "Preview account deletion impact", examples: ["openmates settings account delete preview"] },
|
|
7678
|
+
{ path: ["account", "storage", "overview"], description: "Show storage overview", examples: ["openmates settings account storage overview"] },
|
|
7679
|
+
{ path: ["account", "storage", "files"], description: "List stored files", examples: ["openmates settings account storage files --category images"] },
|
|
7680
|
+
{ path: ["account", "storage", "delete"], description: "Delete one stored file by file ID", examples: ["openmates settings account storage delete <file-id> --yes"] },
|
|
7681
|
+
{ path: ["interface", "language", "set"], description: "Set interface language", examples: ["openmates settings interface language set en"] },
|
|
7682
|
+
{ path: ["interface", "dark-mode", "set"], description: "Set dark mode on or off", examples: ["openmates settings interface dark-mode set on"] },
|
|
7683
|
+
{ path: ["interface", "font", "set"], description: "Set interface font", examples: ["openmates settings interface font set lexend"] },
|
|
7684
|
+
{ path: ["ai", "models", "set-defaults"], description: "Set default AI models", examples: ["openmates settings ai models set-defaults --simple gpt-5.4 --complex claude-opus-4-7"] },
|
|
7685
|
+
{ path: ["privacy", "auto-delete", "chats", "set"], description: "Set chat auto-deletion period", examples: ["openmates settings privacy auto-delete chats set 90d"] },
|
|
7686
|
+
{ path: ["privacy", "debug-logs", "share"], description: "Create a debug log sharing session", examples: ["openmates settings privacy debug-logs share --duration 1h --confirm"] },
|
|
7687
|
+
{ path: ["billing", "overview"], description: "Show billing overview", examples: ["openmates settings billing overview"] },
|
|
7688
|
+
{ path: ["billing", "usage"], description: "Show usage history", examples: ["openmates settings billing usage --json"] },
|
|
7689
|
+
{ path: ["billing", "usage", "summaries"], description: "Show usage summaries", examples: ["openmates settings billing usage summaries"] },
|
|
7690
|
+
{ path: ["billing", "usage", "daily"], description: "Show daily usage overview", examples: ["openmates settings billing usage daily"] },
|
|
7691
|
+
{ path: ["billing", "usage", "export"], description: "Export usage data", examples: ["openmates settings billing usage export --json"] },
|
|
7692
|
+
{ path: ["billing", "gift-card", "redeem"], description: "Redeem a gift card", examples: ["openmates settings billing gift-card redeem ABCD-1234"] },
|
|
7693
|
+
{ path: ["billing", "gift-card", "list"], description: "List redeemed gift cards", examples: ["openmates settings billing gift-card list"] },
|
|
7694
|
+
{ path: ["billing", "auto-topup", "low-balance", "set"], description: "Configure low-balance auto top-up", examples: ["openmates settings billing auto-topup low-balance set --enabled true --amount 1000 --currency eur --email you@example.com"] },
|
|
7695
|
+
{ path: ["reminders", "list"], description: "List active reminders", examples: ["openmates settings reminders list"] },
|
|
7696
|
+
{ path: ["reminders", "update"], description: "Update a reminder", examples: ["openmates settings reminders update <id> --enabled false"] },
|
|
7697
|
+
{ path: ["reminders", "delete"], description: "Delete a reminder", examples: ["openmates settings reminders delete <id> --yes"] },
|
|
7698
|
+
{ path: ["developers", "api-keys", "list"], description: "List API keys", examples: ["openmates settings developers api-keys list"] },
|
|
7699
|
+
{ path: ["developers", "api-keys", "revoke"], description: "Revoke an API key", examples: ["openmates settings developers api-keys revoke <key-id> --yes"] },
|
|
7700
|
+
{ path: ["report-issue", "create"], description: "Report an issue", examples: ['openmates settings report-issue create --title "Bug" --body "What happened"'] },
|
|
7701
|
+
{ path: ["report-issue", "status"], description: "Show issue status", examples: ["openmates settings report-issue status <issue-id>"] },
|
|
7702
|
+
{ path: ["memories"], description: "Manage encrypted memories", examples: ["openmates settings memories list", `openmates settings memories create --app-id code --item-type projects --data '{"name":"OpenMates"}'`] }
|
|
7703
|
+
];
|
|
7704
|
+
var SETTINGS_INFO_COMMANDS = [
|
|
7705
|
+
{ path: ["account", "username"], description: "Username management is not CLI-ready yet", webPath: "account/username", reason: "The current web flow writes encrypted profile fields; CLI support needs a dedicated encryption UX first.", examples: ["openmates settings account username --help"] },
|
|
7706
|
+
{ path: ["account", "email"], description: "Email changes are web-only", webPath: "account/email", reason: "Email changes require a guided identity verification flow.", examples: ["openmates settings account email"] },
|
|
7707
|
+
{ path: ["account", "profile-picture"], description: "Profile picture changes are not CLI-ready yet", webPath: "account/profile-picture", reason: "The upload/update flow needs image validation and parity with the browser uploader.", examples: ["openmates settings account profile-picture"] },
|
|
7708
|
+
{ path: ["account", "delete"], description: "Account deletion is web-only", webPath: "account/delete", reason: "Account deletion requires browser-based reauthentication and explicit confirmation.", examples: ["openmates settings account delete"] },
|
|
7709
|
+
{ path: ["security"], description: "Security settings are web-only", webPath: "account/security", reason: "Security settings require browser APIs or high-risk reauthentication.", examples: ["openmates settings security"] },
|
|
7710
|
+
{ path: ["security", "passkeys"], description: "Passkeys are web-only", webPath: "account/security/passkeys", reason: "Passkeys require WebAuthn browser APIs.", examples: ["openmates settings security passkeys"] },
|
|
7711
|
+
{ path: ["security", "password"], description: "Password changes are web-only", webPath: "account/security/password", reason: "The CLI never asks for account credentials.", examples: ["openmates settings security password"] },
|
|
7712
|
+
{ path: ["security", "2fa"], description: "2FA setup and changes are web-only", webPath: "account/security/2fa", reason: "2FA setup requires a guided browser verification flow.", examples: ["openmates settings security 2fa"] },
|
|
7713
|
+
{ path: ["security", "recovery-key"], description: "Recovery key settings are web-only", webPath: "account/security/recovery-key", reason: "Recovery keys are a high-risk account recovery surface.", examples: ["openmates settings security recovery-key"] },
|
|
7714
|
+
{ path: ["security", "sessions"], description: "Session management is web-only", webPath: "account/security/sessions", reason: "The CLI is a paired restricted session; approval and revocation stay in the browser.", examples: ["openmates settings security sessions"] },
|
|
7715
|
+
{ path: ["billing", "buy-credits"], description: "Credit purchase is web-only", webPath: "billing/buy-credits", reason: "Payment checkout must use the browser/payment provider UI.", examples: ["openmates settings billing buy-credits"] },
|
|
7716
|
+
{ path: ["billing", "gift-card", "buy"], description: "Gift card purchase is web-only", webPath: "billing/gift-cards/buy", reason: "Payment checkout must use the browser/payment provider UI.", examples: ["openmates settings billing gift-card buy"] },
|
|
7717
|
+
{ path: ["billing", "auto-topup", "monthly"], description: "Monthly auto top-up is web-only for now", webPath: "billing/auto-topup/monthly", reason: "Recurring payment setup needs a payment-flow audit before CLI support.", examples: ["openmates settings billing auto-topup monthly"] },
|
|
7718
|
+
{ path: ["billing", "invoices"], description: "Invoice management is web-only for now", webPath: "billing/invoices", reason: "Invoice download support needs auth-gated file streaming parity first.", examples: ["openmates settings billing invoices"] },
|
|
7719
|
+
{ path: ["privacy", "personal-data"], description: "Personal data management is not CLI-ready yet", webPath: "privacy/hide-personal-data", reason: "The CLI needs a dedicated encrypted personal-data UX before exposing writes.", examples: ["openmates settings privacy personal-data"] },
|
|
7720
|
+
{ path: ["notifications"], description: "Notification preferences are not CLI-ready yet", webPath: "notifications", reason: "Backend preference endpoints need an audit before terminal writes are exposed.", examples: ["openmates settings notifications"] },
|
|
7721
|
+
{ path: ["shared", "tip"], description: "Tips are web-only", webPath: "shared/tip", reason: "Payment checkout must use the browser/payment provider UI.", examples: ["openmates settings shared tip"] },
|
|
7722
|
+
{ path: ["mates"], description: "Mate browsing is available through mentions for now", webPath: "mates", reason: "Use @mate mentions in chat; rich mate settings remain browser-first.", examples: ["openmates mentions list --type mate"] },
|
|
7723
|
+
{ path: ["developers", "api-keys", "create"], description: "API key creation is web-only", webPath: "developers/api-keys", reason: "API key secrets are shown once and need the browser approval flow.", examples: ["openmates settings developers api-keys create"] },
|
|
7724
|
+
{ path: ["developers", "devices"], description: "Developer devices are web-only", webPath: "developers/devices", reason: "Device approvals and revocations are sensitive.", examples: ["openmates settings developers devices"] },
|
|
7725
|
+
{ path: ["developers", "webhooks"], description: "Developer webhooks are not CLI-ready yet", webPath: "developers/webhooks", reason: "Webhook CRUD needs a backend/API audit before CLI support.", examples: ["openmates settings developers webhooks"] },
|
|
7726
|
+
{ path: ["support"], description: "Support payments are web-only", webPath: "support", reason: "Payment flows must use the browser/payment provider UI.", examples: ["openmates settings support"] },
|
|
7727
|
+
{ path: ["newsletter"], description: "Newsletter settings are not CLI-ready yet", webPath: "newsletter", reason: "Newsletter API flow needs an audit before CLI support.", examples: ["openmates settings newsletter"] },
|
|
7728
|
+
{ path: ["incognito", "info"], description: "Explain incognito mode", reason: "Incognito chats are sent without saving chat history. The CLI stores no incognito transcript.", examples: ['openmates chats incognito "Private question"'] },
|
|
7729
|
+
{ path: ["server"], description: "Server admin settings are web/admin-only", webPath: "server", reason: "Use `openmates server --help` for self-hosted terminal server management.", examples: ["openmates server status"] }
|
|
7730
|
+
];
|
|
7731
|
+
function matches(actual, expected) {
|
|
7732
|
+
return expected.every((part, index) => actual[index] === part);
|
|
7733
|
+
}
|
|
7734
|
+
function findSettingsInfoCommand(tokens) {
|
|
7735
|
+
const all = [...SETTINGS_INFO_COMMANDS, ...SETTINGS_EXECUTABLE_COMMANDS];
|
|
7736
|
+
return all.sort((a, b) => b.path.length - a.path.length).find((command) => matches(tokens, command.path)) ?? null;
|
|
7737
|
+
}
|
|
7738
|
+
async function printSettingsResult(resultPromise, flags) {
|
|
7739
|
+
const result = await resultPromise;
|
|
7740
|
+
flags.json === true ? printJson2(result) : printGenericObject(result);
|
|
7741
|
+
}
|
|
7742
|
+
async function printSettingsMutationResult(resultPromise, flags) {
|
|
7743
|
+
const result = await resultPromise;
|
|
7744
|
+
if (flags.json === true) {
|
|
7745
|
+
printJson2(result);
|
|
7705
7746
|
return;
|
|
7706
7747
|
}
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
|
|
7748
|
+
process.stdout.write("\x1B[32m\u2713\x1B[0m Settings updated\n");
|
|
7749
|
+
if (result && typeof result === "object") printGenericObject(result);
|
|
7750
|
+
}
|
|
7751
|
+
function addQueryParam(params, key, value) {
|
|
7752
|
+
if (typeof value === "string" && value.length > 0) params.set(key, value);
|
|
7753
|
+
}
|
|
7754
|
+
function parseOnOff(value, label) {
|
|
7755
|
+
if (value === "on" || value === "true" || value === "1") return true;
|
|
7756
|
+
if (value === "off" || value === "false" || value === "0") return false;
|
|
7757
|
+
throw new Error(`Invalid ${label} value '${value ?? ""}'. Use on/off or true/false.`);
|
|
7758
|
+
}
|
|
7759
|
+
function parseRequiredNumber(value, flag) {
|
|
7760
|
+
if (typeof value !== "string") throw new Error(`Missing ${flag}.`);
|
|
7761
|
+
const parsed = Number(value);
|
|
7762
|
+
if (!Number.isFinite(parsed)) throw new Error(`Invalid ${flag}: ${value}`);
|
|
7763
|
+
return parsed;
|
|
7764
|
+
}
|
|
7765
|
+
function parseDataOrFlags(flags, booleanFlags) {
|
|
7766
|
+
if (typeof flags.data === "string") return JSON.parse(flags.data);
|
|
7767
|
+
const body = {};
|
|
7768
|
+
for (const key of booleanFlags) {
|
|
7769
|
+
if (flags[key] !== void 0) body[key] = parseOnOff(String(flags[key]), key);
|
|
7770
|
+
}
|
|
7771
|
+
if (Object.keys(body).length === 0) throw new Error("Provide --data '<json>' or a supported flag.");
|
|
7772
|
+
return body;
|
|
7773
|
+
}
|
|
7774
|
+
function parseChatImportPayload(raw) {
|
|
7775
|
+
const trimmed = raw.trim();
|
|
7776
|
+
if (!trimmed) throw new Error("Import file is empty.");
|
|
7777
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
7778
|
+
const parsed = JSON.parse(trimmed);
|
|
7779
|
+
if (Array.isArray(parsed)) return { chats: parsed };
|
|
7780
|
+
if (parsed && typeof parsed === "object" && Array.isArray(parsed.chats)) {
|
|
7781
|
+
return parsed;
|
|
7713
7782
|
}
|
|
7714
|
-
|
|
7715
|
-
|
|
7716
|
-
|
|
7717
|
-
} else {
|
|
7718
|
-
printGenericObject(result);
|
|
7783
|
+
if (parsed && typeof parsed === "object") {
|
|
7784
|
+
const object = parsed;
|
|
7785
|
+
if (object.chat || object.messages) return { chats: [normalizeImportedChat(object)] };
|
|
7719
7786
|
}
|
|
7720
|
-
|
|
7787
|
+
throw new Error("JSON import must contain a chats array, a chat object, or messages.");
|
|
7721
7788
|
}
|
|
7722
|
-
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
7789
|
+
return { chats: [parseCliExportYaml(trimmed)] };
|
|
7790
|
+
}
|
|
7791
|
+
function normalizeImportedChat(source) {
|
|
7792
|
+
const chat = source.chat && typeof source.chat === "object" ? source.chat : source;
|
|
7793
|
+
const messages = Array.isArray(source.messages) ? source.messages : [];
|
|
7794
|
+
return {
|
|
7795
|
+
title: chat.title ?? null,
|
|
7796
|
+
draft: chat.draft ?? null,
|
|
7797
|
+
summary: chat.summary ?? null,
|
|
7798
|
+
messages: messages.map((message) => normalizeImportedMessage(message))
|
|
7799
|
+
};
|
|
7800
|
+
}
|
|
7801
|
+
function normalizeImportedMessage(message) {
|
|
7802
|
+
return {
|
|
7803
|
+
role: message.role,
|
|
7804
|
+
content: message.content,
|
|
7805
|
+
completed_at: message.completed_at ?? message.timestamp ?? null,
|
|
7806
|
+
assistant_category: message.assistant_category ?? null,
|
|
7807
|
+
thinking: message.thinking ?? null,
|
|
7808
|
+
has_thinking: message.has_thinking ?? null,
|
|
7809
|
+
thinking_tokens: message.thinking_tokens ?? null
|
|
7810
|
+
};
|
|
7811
|
+
}
|
|
7812
|
+
function parseCliExportYaml(raw) {
|
|
7813
|
+
const chat = {};
|
|
7814
|
+
const messages = [];
|
|
7815
|
+
const lines = raw.split("\n");
|
|
7816
|
+
let section = null;
|
|
7817
|
+
let currentMessage = null;
|
|
7818
|
+
const multilineState = { current: null };
|
|
7819
|
+
const setValue = (target, key, value, indent) => {
|
|
7820
|
+
if (value === "|") {
|
|
7821
|
+
target[key] = "";
|
|
7822
|
+
multilineState.current = { target, key, indent: indent + 2 };
|
|
7823
|
+
return;
|
|
7728
7824
|
}
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7825
|
+
target[key] = parseYamlScalar(value);
|
|
7826
|
+
};
|
|
7827
|
+
for (const line of lines) {
|
|
7828
|
+
const indent = line.match(/^ */)?.[0].length ?? 0;
|
|
7829
|
+
const trimmed = line.trimEnd();
|
|
7830
|
+
if (!trimmed.trim()) continue;
|
|
7831
|
+
if (multilineState.current) {
|
|
7832
|
+
if (indent >= multilineState.current.indent) {
|
|
7833
|
+
const previous = String(multilineState.current.target[multilineState.current.key] ?? "");
|
|
7834
|
+
const nextLine = line.slice(multilineState.current.indent);
|
|
7835
|
+
multilineState.current.target[multilineState.current.key] = previous ? `${previous}
|
|
7836
|
+
${nextLine}` : nextLine;
|
|
7837
|
+
continue;
|
|
7838
|
+
}
|
|
7839
|
+
multilineState.current = null;
|
|
7736
7840
|
}
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
if (!path) {
|
|
7742
|
-
console.error("Missing path.\n");
|
|
7743
|
-
printSettingsHelp();
|
|
7744
|
-
process.exit(1);
|
|
7841
|
+
if (trimmed === "chat:") {
|
|
7842
|
+
section = "chat";
|
|
7843
|
+
currentMessage = null;
|
|
7844
|
+
continue;
|
|
7745
7845
|
}
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7846
|
+
if (trimmed === "messages:") {
|
|
7847
|
+
section = "messages";
|
|
7848
|
+
currentMessage = null;
|
|
7849
|
+
continue;
|
|
7850
|
+
}
|
|
7851
|
+
if (section === "messages" && trimmed.trim() === "-") {
|
|
7852
|
+
currentMessage = {};
|
|
7853
|
+
messages.push(currentMessage);
|
|
7854
|
+
continue;
|
|
7751
7855
|
}
|
|
7856
|
+
const match = /^\s*([\w-]+):\s*(.*)$/.exec(line);
|
|
7857
|
+
if (!match) continue;
|
|
7858
|
+
const [, key, value] = match;
|
|
7859
|
+
if (section === "chat") setValue(chat, key, value, indent);
|
|
7860
|
+
if (section === "messages" && currentMessage) setValue(currentMessage, key, value, indent);
|
|
7861
|
+
}
|
|
7862
|
+
if (messages.length === 0) throw new Error("Import YAML did not contain any messages.");
|
|
7863
|
+
return normalizeImportedChat({ chat, messages });
|
|
7864
|
+
}
|
|
7865
|
+
function parseYamlScalar(value) {
|
|
7866
|
+
const trimmed = value.trim();
|
|
7867
|
+
if (trimmed === "null") return null;
|
|
7868
|
+
if (trimmed === "true") return true;
|
|
7869
|
+
if (trimmed === "false") return false;
|
|
7870
|
+
if (trimmed !== "" && Number.isFinite(Number(trimmed))) return Number(trimmed);
|
|
7871
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
7872
|
+
return trimmed.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
7873
|
+
}
|
|
7874
|
+
return trimmed;
|
|
7875
|
+
}
|
|
7876
|
+
async function confirmOrExit(question) {
|
|
7877
|
+
const rl = await import("readline");
|
|
7878
|
+
const iface = rl.createInterface({ input: process.stdin, output: process.stdout });
|
|
7879
|
+
const answer = await new Promise((resolve4) => iface.question(question, resolve4));
|
|
7880
|
+
iface.close();
|
|
7881
|
+
if (answer.trim().toLowerCase() !== "y") {
|
|
7882
|
+
console.log("Aborted.");
|
|
7883
|
+
process.exit(0);
|
|
7884
|
+
}
|
|
7885
|
+
}
|
|
7886
|
+
function printSettingsInfoCommand(client, command, json) {
|
|
7887
|
+
const appUrl = deriveAppUrl(client.apiUrl);
|
|
7888
|
+
const webUrl = command.webPath ? `${appUrl}/#settings/${command.webPath}` : null;
|
|
7889
|
+
if (json) {
|
|
7890
|
+
printJson2({
|
|
7891
|
+
command: `openmates settings ${command.path.join(" ")}`,
|
|
7892
|
+
supported_in_cli: false,
|
|
7893
|
+
description: command.description,
|
|
7894
|
+
reason: command.reason ?? null,
|
|
7895
|
+
web_url: webUrl,
|
|
7896
|
+
examples: command.examples
|
|
7897
|
+
});
|
|
7752
7898
|
return;
|
|
7753
7899
|
}
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
7900
|
+
header(command.description);
|
|
7901
|
+
if (command.reason) console.log(command.reason);
|
|
7902
|
+
if (webUrl) console.log(`
|
|
7903
|
+
Open in web app:
|
|
7904
|
+
${webUrl}`);
|
|
7905
|
+
if (command.examples.length > 0) {
|
|
7906
|
+
console.log("\nExamples:");
|
|
7907
|
+
for (const example of command.examples) console.log(` ${example}`);
|
|
7908
|
+
}
|
|
7909
|
+
}
|
|
7910
|
+
async function handleSettings(client, subcommand, rest, flags) {
|
|
7911
|
+
if (!subcommand || subcommand === "help") {
|
|
7912
|
+
printSettingsHelp(client, subcommand ? [] : void 0);
|
|
7913
|
+
return;
|
|
7914
|
+
}
|
|
7915
|
+
const tokens = [subcommand, ...rest].filter((token) => token !== "help");
|
|
7916
|
+
if (rest.includes("help") || Boolean(flags.help)) {
|
|
7917
|
+
printSettingsHelp(client, tokens);
|
|
7918
|
+
return;
|
|
7919
|
+
}
|
|
7920
|
+
if (["get", "post", "patch", "delete"].includes(subcommand)) {
|
|
7921
|
+
console.error(
|
|
7922
|
+
"Raw settings passthrough is no longer supported. Use a predefined settings command.\n"
|
|
7923
|
+
);
|
|
7924
|
+
printSettingsHelp(client);
|
|
7925
|
+
process.exit(1);
|
|
7926
|
+
}
|
|
7927
|
+
if (matches(tokens, ["account", "info"])) {
|
|
7928
|
+
const user = await client.whoAmI();
|
|
7929
|
+
flags.json === true ? printJson2(user) : printWhoAmI(user);
|
|
7930
|
+
return;
|
|
7931
|
+
}
|
|
7932
|
+
if (matches(tokens, ["account", "timezone", "set"])) {
|
|
7933
|
+
const timezone = rest[2];
|
|
7934
|
+
if (!timezone) throw new Error("Missing timezone. Example: openmates settings account timezone set Europe/Berlin");
|
|
7935
|
+
await printSettingsMutationResult(
|
|
7936
|
+
client.settingsPost("user/timezone", { timezone }),
|
|
7937
|
+
flags
|
|
7938
|
+
);
|
|
7939
|
+
return;
|
|
7940
|
+
}
|
|
7941
|
+
if (matches(tokens, ["account", "export", "manifest"])) {
|
|
7942
|
+
await printSettingsResult(client.settingsGet("export-account-manifest"), flags);
|
|
7943
|
+
return;
|
|
7944
|
+
}
|
|
7945
|
+
if (matches(tokens, ["account", "export", "data"])) {
|
|
7946
|
+
await printSettingsResult(client.settingsGet("export-account-data"), flags);
|
|
7947
|
+
return;
|
|
7948
|
+
}
|
|
7949
|
+
if (matches(tokens, ["account", "import-chat"])) {
|
|
7950
|
+
const file = rest[1];
|
|
7951
|
+
if (!file) throw new Error("Missing import file. Example: openmates settings account import-chat ./chat.yml");
|
|
7952
|
+
const { readFile } = await import("fs/promises");
|
|
7953
|
+
const content = await readFile(file, "utf-8");
|
|
7954
|
+
await printSettingsMutationResult(
|
|
7955
|
+
client.settingsPost("import-chat", parseChatImportPayload(content)),
|
|
7956
|
+
flags
|
|
7957
|
+
);
|
|
7958
|
+
return;
|
|
7959
|
+
}
|
|
7960
|
+
if (matches(tokens, ["account", "chats", "stats"])) {
|
|
7961
|
+
await printSettingsResult(client.settingsGet("chats"), flags);
|
|
7962
|
+
return;
|
|
7963
|
+
}
|
|
7964
|
+
if (matches(tokens, ["account", "delete", "preview"])) {
|
|
7965
|
+
await printSettingsResult(client.settingsGet("delete-account-preview"), flags);
|
|
7966
|
+
return;
|
|
7967
|
+
}
|
|
7968
|
+
if (matches(tokens, ["account", "storage", "overview"])) {
|
|
7969
|
+
await printSettingsResult(client.settingsGet("storage"), flags);
|
|
7970
|
+
return;
|
|
7971
|
+
}
|
|
7972
|
+
if (matches(tokens, ["account", "storage", "files"])) {
|
|
7973
|
+
const params = new URLSearchParams();
|
|
7974
|
+
addQueryParam(params, "category", flags.category ?? flags.type);
|
|
7975
|
+
const query = params.toString();
|
|
7976
|
+
await printSettingsResult(client.settingsGet(`storage/files${query ? `?${query}` : ""}`), flags);
|
|
7977
|
+
return;
|
|
7978
|
+
}
|
|
7979
|
+
if (matches(tokens, ["account", "storage", "delete"])) {
|
|
7980
|
+
const fileId = rest[3];
|
|
7981
|
+
const category = typeof flags.category === "string" ? flags.category : void 0;
|
|
7982
|
+
const scope = flags.all === true ? "all" : category ? "category" : "single";
|
|
7983
|
+
if (scope === "single" && !fileId) throw new Error("Missing file ID.");
|
|
7984
|
+
if (flags.yes !== true) await confirmOrExit(`Delete stored file data (${scope})? This cannot be undone. [y/N] `);
|
|
7985
|
+
await printSettingsMutationResult(
|
|
7986
|
+
client.settingsDelete("storage/files", { scope, file_id: fileId, category }),
|
|
7987
|
+
flags
|
|
7988
|
+
);
|
|
7989
|
+
return;
|
|
7990
|
+
}
|
|
7991
|
+
if (matches(tokens, ["interface", "language", "set"])) {
|
|
7992
|
+
const language = rest[2];
|
|
7993
|
+
if (!language) throw new Error("Missing language code. Example: openmates settings interface language set en");
|
|
7994
|
+
await printSettingsMutationResult(client.settingsPost("user/language", { language }), flags);
|
|
7995
|
+
return;
|
|
7996
|
+
}
|
|
7997
|
+
if (matches(tokens, ["interface", "dark-mode", "set"])) {
|
|
7998
|
+
const value = parseOnOff(rest[2], "dark mode");
|
|
7999
|
+
await printSettingsMutationResult(client.settingsPost("user/darkmode", { dark_mode: value }), flags);
|
|
8000
|
+
return;
|
|
8001
|
+
}
|
|
8002
|
+
if (matches(tokens, ["interface", "font", "set"])) {
|
|
8003
|
+
const font = rest[2];
|
|
8004
|
+
if (!font) throw new Error("Missing font. Example: openmates settings interface font set lexend");
|
|
8005
|
+
await printSettingsMutationResult(client.settingsPost("user/ui-font", { ui_font: font }), flags);
|
|
8006
|
+
return;
|
|
8007
|
+
}
|
|
8008
|
+
if (matches(tokens, ["ai", "models", "set-defaults"])) {
|
|
8009
|
+
const simple = typeof flags.simple === "string" ? flags.simple : void 0;
|
|
8010
|
+
const complex = typeof flags.complex === "string" ? flags.complex : void 0;
|
|
8011
|
+
if (!simple && !complex) throw new Error("Provide --simple <model-id> and/or --complex <model-id>.");
|
|
8012
|
+
await printSettingsMutationResult(client.settingsPost("ai-model-defaults", { simple, complex }), flags);
|
|
8013
|
+
return;
|
|
8014
|
+
}
|
|
8015
|
+
if (matches(tokens, ["privacy", "auto-delete", "chats", "set"])) {
|
|
8016
|
+
const period = rest[3];
|
|
8017
|
+
if (!period) throw new Error("Missing period. Example: openmates settings privacy auto-delete chats set 90d");
|
|
8018
|
+
await printSettingsMutationResult(client.settingsPost("auto-delete-chats", { period }), flags);
|
|
8019
|
+
return;
|
|
8020
|
+
}
|
|
8021
|
+
if (matches(tokens, ["privacy", "debug-logs", "share"])) {
|
|
8022
|
+
if (flags.yes !== true && flags.confirm !== true) {
|
|
8023
|
+
await confirmOrExit("Share debug logs with OpenMates support? [y/N] ");
|
|
7760
8024
|
}
|
|
7761
|
-
const
|
|
7762
|
-
|
|
7763
|
-
|
|
8025
|
+
const duration = typeof flags.duration === "string" ? flags.duration : "1h";
|
|
8026
|
+
await printSettingsMutationResult(client.settingsPost("debug-session", { duration }), flags);
|
|
8027
|
+
return;
|
|
8028
|
+
}
|
|
8029
|
+
if (matches(tokens, ["billing", "overview"])) {
|
|
8030
|
+
await printSettingsResult(client.settingsGet("billing"), flags);
|
|
8031
|
+
return;
|
|
8032
|
+
}
|
|
8033
|
+
if (matches(tokens, ["billing", "usage", "summaries"])) {
|
|
8034
|
+
await printSettingsResult(client.settingsGet("usage/summaries"), flags);
|
|
8035
|
+
return;
|
|
8036
|
+
}
|
|
8037
|
+
if (matches(tokens, ["billing", "usage", "daily"])) {
|
|
8038
|
+
await printSettingsResult(client.settingsGet("usage/daily-overview"), flags);
|
|
8039
|
+
return;
|
|
8040
|
+
}
|
|
8041
|
+
if (matches(tokens, ["billing", "usage", "export"])) {
|
|
8042
|
+
await printSettingsResult(client.settingsGet("usage/export"), flags);
|
|
8043
|
+
return;
|
|
8044
|
+
}
|
|
8045
|
+
if (matches(tokens, ["billing", "usage"])) {
|
|
8046
|
+
await printSettingsResult(client.settingsGet("usage"), flags);
|
|
8047
|
+
return;
|
|
8048
|
+
}
|
|
8049
|
+
if (matches(tokens, ["billing", "gift-card", "redeem"]) || subcommand === "gift-card" && rest[0] === "redeem") {
|
|
8050
|
+
const code = matches(tokens, ["billing", "gift-card", "redeem"]) ? rest[2] : rest[1];
|
|
8051
|
+
if (!code) throw new Error("Missing gift card code.");
|
|
8052
|
+
const result = await client.redeemGiftCard(code);
|
|
7764
8053
|
if (flags.json === true) {
|
|
7765
8054
|
printJson2(result);
|
|
8055
|
+
} else if (result.success) {
|
|
8056
|
+
process.stdout.write(`\x1B[32m\u2713\x1B[0m Gift card redeemed! +${result.credits_added} credits
|
|
8057
|
+
`);
|
|
8058
|
+
process.stdout.write(` Balance: ${result.current_credits} credits
|
|
8059
|
+
`);
|
|
7766
8060
|
} else {
|
|
7767
|
-
|
|
8061
|
+
process.stdout.write(`\x1B[31m\u2717\x1B[0m ${result.message}
|
|
8062
|
+
`);
|
|
7768
8063
|
}
|
|
7769
8064
|
return;
|
|
7770
8065
|
}
|
|
8066
|
+
if (matches(tokens, ["billing", "gift-card", "list"]) || subcommand === "gift-card" && rest[0] === "list") {
|
|
8067
|
+
await printSettingsResult(client.listRedeemedGiftCards(), flags);
|
|
8068
|
+
return;
|
|
8069
|
+
}
|
|
8070
|
+
if (matches(tokens, ["billing", "auto-topup", "low-balance", "set"])) {
|
|
8071
|
+
const enabled = parseOnOff(String(flags.enabled ?? ""), "low-balance auto top-up");
|
|
8072
|
+
const amount = parseRequiredNumber(flags.amount, "--amount");
|
|
8073
|
+
const currency = typeof flags.currency === "string" ? flags.currency : "eur";
|
|
8074
|
+
const email = typeof flags.email === "string" ? flags.email : void 0;
|
|
8075
|
+
if (enabled && !email) throw new Error("Provide --email when enabling low-balance auto top-up.");
|
|
8076
|
+
await printSettingsMutationResult(
|
|
8077
|
+
client.settingsPost("auto-topup/low-balance", { enabled, threshold: 100, amount, currency, email }),
|
|
8078
|
+
flags
|
|
8079
|
+
);
|
|
8080
|
+
return;
|
|
8081
|
+
}
|
|
8082
|
+
if (matches(tokens, ["reminders", "list"])) {
|
|
8083
|
+
await printSettingsResult(client.settingsGet("reminders"), flags);
|
|
8084
|
+
return;
|
|
8085
|
+
}
|
|
8086
|
+
if (matches(tokens, ["reminders", "update"])) {
|
|
8087
|
+
const id = rest[1];
|
|
8088
|
+
if (!id) throw new Error("Missing reminder ID.");
|
|
8089
|
+
const body = parseDataOrFlags(flags, ["enabled"]);
|
|
8090
|
+
await printSettingsMutationResult(client.settingsPatch(`reminders/${id}`, body), flags);
|
|
8091
|
+
return;
|
|
8092
|
+
}
|
|
8093
|
+
if (matches(tokens, ["reminders", "delete"])) {
|
|
8094
|
+
const id = rest[1];
|
|
8095
|
+
if (!id) throw new Error("Missing reminder ID.");
|
|
8096
|
+
if (flags.yes !== true) await confirmOrExit(`Delete reminder ${id}? [y/N] `);
|
|
8097
|
+
await printSettingsMutationResult(client.settingsDelete(`reminders/${id}`), flags);
|
|
8098
|
+
return;
|
|
8099
|
+
}
|
|
8100
|
+
if (matches(tokens, ["developers", "api-keys", "list"])) {
|
|
8101
|
+
await printSettingsResult(client.settingsGet("api-keys"), flags);
|
|
8102
|
+
return;
|
|
8103
|
+
}
|
|
8104
|
+
if (matches(tokens, ["developers", "api-keys", "revoke"])) {
|
|
8105
|
+
const id = rest[2];
|
|
8106
|
+
if (!id) throw new Error("Missing API key ID.");
|
|
8107
|
+
if (flags.yes !== true) await confirmOrExit(`Revoke API key ${id}? [y/N] `);
|
|
8108
|
+
await printSettingsMutationResult(client.settingsDelete(`api-keys/${id}`), flags);
|
|
8109
|
+
return;
|
|
8110
|
+
}
|
|
8111
|
+
if (matches(tokens, ["report-issue", "create"])) {
|
|
8112
|
+
const title = typeof flags.title === "string" ? flags.title : void 0;
|
|
8113
|
+
const body = typeof flags.body === "string" ? flags.body : void 0;
|
|
8114
|
+
if (!title || !body) throw new Error("Provide --title and --body.");
|
|
8115
|
+
await printSettingsMutationResult(client.settingsPost("issues", { title, description: body }), flags);
|
|
8116
|
+
return;
|
|
8117
|
+
}
|
|
8118
|
+
if (matches(tokens, ["report-issue", "status"])) {
|
|
8119
|
+
const id = rest[1];
|
|
8120
|
+
if (!id) throw new Error("Missing issue ID.");
|
|
8121
|
+
await printSettingsResult(client.settingsGet(`issues/${id}/status`), flags);
|
|
8122
|
+
return;
|
|
8123
|
+
}
|
|
7771
8124
|
if (subcommand === "memories") {
|
|
7772
8125
|
await handleMemories(client, rest, flags);
|
|
7773
8126
|
return;
|
|
7774
8127
|
}
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
const code = rest[1];
|
|
7779
|
-
if (!code) {
|
|
7780
|
-
console.error("Missing gift card code.\n");
|
|
7781
|
-
console.log("Usage: openmates settings gift-card redeem <CODE>");
|
|
7782
|
-
process.exit(1);
|
|
7783
|
-
}
|
|
7784
|
-
const result = await client.redeemGiftCard(code);
|
|
7785
|
-
if (flags.json === true) {
|
|
7786
|
-
printJson2(result);
|
|
7787
|
-
} else {
|
|
7788
|
-
if (result.success) {
|
|
7789
|
-
process.stdout.write(
|
|
7790
|
-
`\x1B[32m\u2713\x1B[0m Gift card redeemed! +${result.credits_added} credits
|
|
7791
|
-
`
|
|
7792
|
-
);
|
|
7793
|
-
process.stdout.write(
|
|
7794
|
-
` Balance: ${result.current_credits} credits
|
|
7795
|
-
`
|
|
7796
|
-
);
|
|
7797
|
-
} else {
|
|
7798
|
-
process.stdout.write(`\x1B[31m\u2717\x1B[0m ${result.message}
|
|
7799
|
-
`);
|
|
7800
|
-
}
|
|
7801
|
-
}
|
|
7802
|
-
return;
|
|
7803
|
-
}
|
|
7804
|
-
if (action === "list") {
|
|
7805
|
-
const result = await client.listRedeemedGiftCards();
|
|
7806
|
-
if (flags.json === true) {
|
|
7807
|
-
printJson2(result);
|
|
7808
|
-
} else {
|
|
7809
|
-
printGenericObject(result);
|
|
7810
|
-
}
|
|
7811
|
-
return;
|
|
7812
|
-
}
|
|
7813
|
-
console.log(`Gift card commands:
|
|
7814
|
-
openmates settings gift-card redeem <CODE> Redeem a gift card
|
|
7815
|
-
openmates settings gift-card list List redeemed gift cards`);
|
|
8128
|
+
const webOnly = findSettingsInfoCommand(tokens);
|
|
8129
|
+
if (webOnly) {
|
|
8130
|
+
printSettingsInfoCommand(client, webOnly, flags.json === true);
|
|
7816
8131
|
return;
|
|
7817
8132
|
}
|
|
7818
|
-
console.error(`Unknown settings
|
|
8133
|
+
console.error(`Unknown settings command '${tokens.join(" ")}'.
|
|
7819
8134
|
`);
|
|
7820
|
-
printSettingsHelp();
|
|
8135
|
+
printSettingsHelp(client, [subcommand]);
|
|
7821
8136
|
process.exit(1);
|
|
7822
8137
|
}
|
|
7823
8138
|
async function handleMemories(client, rest, flags) {
|
|
@@ -8370,21 +8685,13 @@ async function sendMessageStreaming(client, params, redactor) {
|
|
|
8370
8685
|
}
|
|
8371
8686
|
return result;
|
|
8372
8687
|
}
|
|
8373
|
-
function
|
|
8374
|
-
|
|
8375
|
-
|
|
8688
|
+
function printIncognitoNoHistoryNotice(json) {
|
|
8689
|
+
const message = "Incognito chats are not stored. There is no incognito history to show or clear.";
|
|
8690
|
+
if (json) {
|
|
8691
|
+
printJson2({ history: [], stored: false, message });
|
|
8376
8692
|
return;
|
|
8377
8693
|
}
|
|
8378
|
-
|
|
8379
|
-
console.log();
|
|
8380
|
-
for (const msg of history) {
|
|
8381
|
-
const ts = formatTimestamp(Math.floor(msg.createdAt / 1e3));
|
|
8382
|
-
const roleLabel = msg.role === "user" ? "\x1B[1mYou\x1B[0m" : "\x1B[36mAssistant\x1B[0m";
|
|
8383
|
-
process.stdout.write(`${roleLabel} \x1B[2m${ts}\x1B[0m
|
|
8384
|
-
`);
|
|
8385
|
-
console.log(msg.content);
|
|
8386
|
-
console.log();
|
|
8387
|
-
}
|
|
8694
|
+
console.log(message);
|
|
8388
8695
|
}
|
|
8389
8696
|
var SEP = `\x1B[2m${"\u2500".repeat(60)}\x1B[0m`;
|
|
8390
8697
|
function parseMessageSegments(content) {
|
|
@@ -9351,23 +9658,23 @@ async function handleMentions(client, subcommand, _rest, flags) {
|
|
|
9351
9658
|
const context = await client.buildMentionContext();
|
|
9352
9659
|
const allOptions = listMentionOptions(context);
|
|
9353
9660
|
const normalizedQuery = query.toLowerCase().replace(/[\s_-]+/g, "");
|
|
9354
|
-
const
|
|
9661
|
+
const matches2 = allOptions.filter((opt) => {
|
|
9355
9662
|
const normalizedName = opt.displayName.toLowerCase().replace(/[@\s_-]+/g, "");
|
|
9356
9663
|
const normalizedDesc = opt.description.toLowerCase().replace(/[\s_-]+/g, "");
|
|
9357
9664
|
return normalizedName.includes(normalizedQuery) || normalizedDesc.includes(normalizedQuery);
|
|
9358
9665
|
}).slice(0, 15);
|
|
9359
9666
|
if (flags.json === true) {
|
|
9360
|
-
console.log(JSON.stringify(
|
|
9667
|
+
console.log(JSON.stringify(matches2, null, 2));
|
|
9361
9668
|
return;
|
|
9362
9669
|
}
|
|
9363
|
-
if (
|
|
9670
|
+
if (matches2.length === 0) {
|
|
9364
9671
|
console.log(`No mentions matching '${query}'.`);
|
|
9365
9672
|
return;
|
|
9366
9673
|
}
|
|
9367
9674
|
process.stdout.write(`
|
|
9368
9675
|
\x1B[1mMatches for '${query}':\x1B[0m
|
|
9369
9676
|
`);
|
|
9370
|
-
for (const m of
|
|
9677
|
+
for (const m of matches2) {
|
|
9371
9678
|
const typeLabel = m.type.replace("_", " ");
|
|
9372
9679
|
process.stdout.write(
|
|
9373
9680
|
` \x1B[36m${m.displayName.padEnd(35)}\x1B[0m \x1B[2m${m.description} (${typeLabel})\x1B[0m
|
|
@@ -9512,7 +9819,7 @@ Commands:
|
|
|
9512
9819
|
openmates apps [--help] App skill commands (list, run, ...)
|
|
9513
9820
|
openmates mentions [--help] List available @mentions
|
|
9514
9821
|
openmates embeds [--help] Embed commands (show)
|
|
9515
|
-
openmates settings [--help]
|
|
9822
|
+
openmates settings [--help] Predefined settings commands
|
|
9516
9823
|
openmates inspirations [--lang <code>] [--json] Daily inspirations
|
|
9517
9824
|
openmates newchatsuggestions [--limit <n>] [--json] Personalized new chat suggestions
|
|
9518
9825
|
openmates server [--help] Server management (install, start, stop, ...)
|
|
@@ -9537,8 +9844,8 @@ function printChatsHelp() {
|
|
|
9537
9844
|
openmates chats delete <id1> [id2] [id3] ... [--yes]
|
|
9538
9845
|
openmates chats share [<chat-id>] [--expires <seconds>] [--password <pwd>] [--json]
|
|
9539
9846
|
openmates chats incognito <message> [--json]
|
|
9540
|
-
openmates chats incognito-history [--json]
|
|
9541
|
-
openmates chats incognito-clear
|
|
9847
|
+
openmates chats incognito-history [--json] Deprecated: incognito stores no history
|
|
9848
|
+
openmates chats incognito-clear Deprecated: incognito stores no history
|
|
9542
9849
|
|
|
9543
9850
|
Options for 'list':
|
|
9544
9851
|
--limit <n> Number of chats per page (default: 10)
|
|
@@ -9662,72 +9969,33 @@ Examples:
|
|
|
9662
9969
|
openmates inspirations --lang de
|
|
9663
9970
|
openmates inspirations --json`);
|
|
9664
9971
|
}
|
|
9665
|
-
function printSettingsHelp(client) {
|
|
9972
|
+
function printSettingsHelp(client, filter) {
|
|
9973
|
+
const commands = [...SETTINGS_EXECUTABLE_COMMANDS, ...SETTINGS_INFO_COMMANDS].filter((command) => {
|
|
9974
|
+
if (!filter || filter.length === 0) return true;
|
|
9975
|
+
return filter.every((part, index) => command.path[index] === part);
|
|
9976
|
+
}).sort((a, b) => a.path.join(" ").localeCompare(b.path.join(" ")));
|
|
9666
9977
|
const appUrl = client ? deriveAppUrl(client.apiUrl) : "https://openmates.org";
|
|
9667
|
-
const
|
|
9668
|
-
|
|
9669
|
-
|
|
9670
|
-
|
|
9671
|
-
|
|
9672
|
-
|
|
9673
|
-
|
|
9674
|
-
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
|
|
9678
|
-
|
|
9679
|
-
|
|
9680
|
-
|
|
9681
|
-
|
|
9682
|
-
|
|
9683
|
-
|
|
9684
|
-
|
|
9685
|
-
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
openmates settings get usage/export [--json] Export usage as CSV
|
|
9689
|
-
openmates settings gift-card redeem <CODE> Redeem a gift card
|
|
9690
|
-
openmates settings gift-card list List redeemed gift cards
|
|
9691
|
-
\x1B[2mBuy credits: ${s("billing/buy-credits")}\x1B[0m
|
|
9692
|
-
\x1B[2mMonthly auto top-up: ${s("billing/auto-topup/monthly")}\x1B[0m
|
|
9693
|
-
\x1B[2mInvoices: ${s("billing/invoices")}\x1B[0m
|
|
9694
|
-
\x1B[2mGift cards (buy/manage): ${s("billing/gift-cards")}\x1B[0m
|
|
9695
|
-
${h("Privacy")}
|
|
9696
|
-
openmates settings post auto-delete-chats --data '{"period":"90d"}'
|
|
9697
|
-
\x1B[2mHide personal data / anonymization: ${s("privacy/hide-personal-data")}\x1B[0m
|
|
9698
|
-
${h("Notifications")}
|
|
9699
|
-
openmates settings get reminders [--json] Active reminders
|
|
9700
|
-
\x1B[2mChat notifications: ${s("notifications/chat")}\x1B[0m
|
|
9701
|
-
\x1B[2mBackup reminders: ${s("notifications/backup")}\x1B[0m
|
|
9702
|
-
${h("Interface")}
|
|
9703
|
-
openmates settings post user/language --data '{"language":"en"}'
|
|
9704
|
-
openmates settings post user/darkmode --data '{"dark_mode":true}'
|
|
9705
|
-
openmates settings post ai-model-defaults --data '{"simple":"...","complex":"..."}'
|
|
9706
|
-
${h("Apps")}
|
|
9707
|
-
openmates apps list Same as Apps
|
|
9708
|
-
openmates apps <app-id> App details
|
|
9709
|
-
\x1B[2mWeb: ${s("app_store")}\x1B[0m
|
|
9710
|
-
${h("Mates")}
|
|
9711
|
-
\x1B[2m${s("mates")}\x1B[0m
|
|
9712
|
-
${h("Memories & app settings")}
|
|
9713
|
-
openmates settings memories list [--app-id <id>] [--item-type <type>] [--json]
|
|
9714
|
-
openmates settings memories types [--app-id <id>] [--json]
|
|
9715
|
-
openmates settings memories create --app-id <id> --item-type <type> --data '<json>'
|
|
9716
|
-
openmates settings memories update --id <id> --app-id <id> --item-type <type> --data '<json>'
|
|
9717
|
-
openmates settings memories delete --id <entry-id>
|
|
9718
|
-
${h("Developers")}
|
|
9719
|
-
openmates settings get api-keys [--json] List API keys
|
|
9720
|
-
openmates settings delete api-keys/<key-id> Revoke API key
|
|
9721
|
-
\x1B[2mCreate API key (shows secret once): ${s("developers/api-keys")}\x1B[0m
|
|
9722
|
-
\x1B[2mManage devices: ${s("developers/devices")}\x1B[0m
|
|
9723
|
-
${h("Support")}
|
|
9724
|
-
openmates settings post issues --data '<json>' Report an issue
|
|
9725
|
-
|
|
9726
|
-
\x1B[2mWeb app only (security \u2014 manage in browser):\x1B[0m
|
|
9727
|
-
\x1B[2mPasskeys: ${s("account/security/passkeys")}\x1B[0m
|
|
9728
|
-
\x1B[2mPassword: ${s("account/security/password")}\x1B[0m
|
|
9729
|
-
\x1B[2m2FA: ${s("account/security/2fa")}\x1B[0m
|
|
9730
|
-
\x1B[2mSessions: ${s("account/security/sessions")}\x1B[0m`);
|
|
9978
|
+
const title = filter && filter.length > 0 ? `Settings: ${filter.join(" ")}` : "Settings";
|
|
9979
|
+
header(title);
|
|
9980
|
+
console.log("Predefined commands only. Raw settings get/post/patch/delete is not supported.\n");
|
|
9981
|
+
if (commands.length === 0) {
|
|
9982
|
+
console.log("No matching settings commands.");
|
|
9983
|
+
return;
|
|
9984
|
+
}
|
|
9985
|
+
for (const command of commands) {
|
|
9986
|
+
const isInfoOnly = SETTINGS_INFO_COMMANDS.includes(command);
|
|
9987
|
+
const label = `openmates settings ${command.path.join(" ")}`;
|
|
9988
|
+
process.stdout.write(` ${label.padEnd(58)} ${command.description}`);
|
|
9989
|
+
if (isInfoOnly) process.stdout.write(" \x1B[2m(info/web-only)\x1B[0m");
|
|
9990
|
+
process.stdout.write("\n");
|
|
9991
|
+
if (filter && filter.length > 0) {
|
|
9992
|
+
for (const example of command.examples) process.stdout.write(` e.g. ${example}
|
|
9993
|
+
`);
|
|
9994
|
+
if (command.webPath) process.stdout.write(` web: ${appUrl}/#settings/${command.webPath}
|
|
9995
|
+
`);
|
|
9996
|
+
}
|
|
9997
|
+
}
|
|
9998
|
+
console.log("\nUse --help after a group for examples, e.g. openmates settings billing --help");
|
|
9731
9999
|
}
|
|
9732
10000
|
function printNewChatSuggestionsHelp() {
|
|
9733
10001
|
console.log(`New chat suggestions command:
|
package/dist/cli.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -13,11 +13,6 @@ interface OpenMatesSession {
|
|
|
13
13
|
authorizerDeviceName: string | null;
|
|
14
14
|
autoLogoutMinutes: number | null;
|
|
15
15
|
}
|
|
16
|
-
interface IncognitoHistoryItem {
|
|
17
|
-
role: "user" | "assistant";
|
|
18
|
-
content: string;
|
|
19
|
-
createdAt: number;
|
|
20
|
-
}
|
|
21
16
|
/**
|
|
22
17
|
* Raw chat record from the WS phase3 payload.
|
|
23
18
|
* All encrypted_* fields are stored as-is (base64 ciphertext).
|
|
@@ -420,8 +415,6 @@ declare class OpenMatesClient {
|
|
|
420
415
|
/** Follow-up suggestions from post-processing (may be empty for incognito chats). */
|
|
421
416
|
followUpSuggestions: string[];
|
|
422
417
|
}>;
|
|
423
|
-
getIncognitoHistory(): IncognitoHistoryItem[];
|
|
424
|
-
clearIncognitoHistory(): void;
|
|
425
418
|
/**
|
|
426
419
|
* Delete a chat by ID.
|
|
427
420
|
*
|
|
@@ -465,7 +458,7 @@ declare class OpenMatesClient {
|
|
|
465
458
|
}>;
|
|
466
459
|
settingsGet(path: string): Promise<unknown>;
|
|
467
460
|
settingsPost(path: string, body: Record<string, unknown>): Promise<unknown>;
|
|
468
|
-
settingsDelete(path: string): Promise<unknown>;
|
|
461
|
+
settingsDelete(path: string, body?: Record<string, unknown>): Promise<unknown>;
|
|
469
462
|
settingsPatch(path: string, body: Record<string, unknown>): Promise<unknown>;
|
|
470
463
|
redeemGiftCard(code: string): Promise<{
|
|
471
464
|
success: boolean;
|
package/dist/index.js
CHANGED