openmates 0.12.0-alpha.17 → 0.12.0-alpha.19

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.
@@ -8587,6 +8587,13 @@ var IMAGE_CHANNEL_TAGS = {
8587
8587
  main: MAIN_BRANCH,
8588
8588
  dev: DEV_BRANCH
8589
8589
  };
8590
+ var BACKEND_CONFIG_FILE = join3("backend", "config", "backend_config.yml");
8591
+ var OFF_BY_DEFAULT_FEATURES = /* @__PURE__ */ new Map([
8592
+ ["embed:code:application", "Application previews are still unstable"],
8593
+ ["platform:projects", "Projects workspace is not ready by default"],
8594
+ ["platform:workflows", "Workflows workspace is not implemented yet"],
8595
+ ["platform:tasks", "Tasks workspace is not implemented yet"]
8596
+ ]);
8590
8597
  var MINIMAL_ENV_TEMPLATE = `# OpenMates self-host image-mode environment
8591
8598
  SECRET__MISTRAL_AI__API_KEY=
8592
8599
  SECRET__CEREBRAS__API_KEY=
@@ -8674,6 +8681,65 @@ function getInstallMode(installPath, config = loadConfigForInstallPath(installPa
8674
8681
  function shouldPullImages() {
8675
8682
  return process.env.OPENMATES_SKIP_IMAGE_PULL !== "1";
8676
8683
  }
8684
+ function normalizeFeatureList(items) {
8685
+ const seen = /* @__PURE__ */ new Set();
8686
+ const normalized = [];
8687
+ for (const item of items) {
8688
+ const value = item.trim();
8689
+ if (!value || seen.has(value)) continue;
8690
+ seen.add(value);
8691
+ normalized.push(value);
8692
+ }
8693
+ return normalized;
8694
+ }
8695
+ function parseListBlock(content, key) {
8696
+ const match = content.match(new RegExp(`^${key}:\\n((?:[ \\t]+.*\\n?)*)`, "m"));
8697
+ if (!match) return [];
8698
+ const block = match[1] ?? "";
8699
+ return normalizeFeatureList(
8700
+ [...block.matchAll(/^\s*-\s*["']?([^"'\n#]+)["']?/gm)].map((item) => item[1] ?? "")
8701
+ );
8702
+ }
8703
+ function parseFeatureOverrides(content) {
8704
+ const overridesMatch = content.match(/^feature_overrides:\n((?:[ \t]+.*\n?)*)/m);
8705
+ const overridesBlock = overridesMatch?.[1] ?? "";
8706
+ const enabled = parseListBlock(overridesBlock.replace(/^ {2}/gm, ""), "enabled");
8707
+ const disabled = parseListBlock(overridesBlock.replace(/^ {2}/gm, ""), "disabled");
8708
+ const legacyDisabledApps = parseListBlock(content, "disabled_apps").map(
8709
+ (appId) => appId.startsWith("app:") ? appId : `app:${appId}`
8710
+ );
8711
+ return {
8712
+ enabled: normalizeFeatureList(enabled),
8713
+ disabled: normalizeFeatureList([...disabled, ...legacyDisabledApps])
8714
+ };
8715
+ }
8716
+ function renderFeatureOverrides(overrides) {
8717
+ const renderList = (key, items) => {
8718
+ if (!items.length) return ` ${key}: []`;
8719
+ return [` ${key}:`, ...items.map((item) => ` - "${item}"`)].join("\n");
8720
+ };
8721
+ return [
8722
+ "# Admin feature overrides. Changes require a server restart.",
8723
+ "feature_overrides:",
8724
+ renderList("enabled", overrides.enabled),
8725
+ renderList("disabled", overrides.disabled),
8726
+ ""
8727
+ ].join("\n");
8728
+ }
8729
+ function removeConfigBlock(content, key) {
8730
+ return content.replace(new RegExp(`(?:^|\\n)#.*\\n${key}:\\n(?:[ \\t]+.*\\n?)*`, "m"), "\n").replace(new RegExp(`^${key}:\\n(?:[ \\t]+.*\\n?)*`, "m"), "");
8731
+ }
8732
+ function updateFeatureOverridesContent(content, overrides) {
8733
+ let next = removeConfigBlock(content, "feature_overrides");
8734
+ next = removeConfigBlock(next, "disabled_apps");
8735
+ next = next.trimEnd();
8736
+ return `${next}
8737
+
8738
+ ${renderFeatureOverrides(overrides)}`;
8739
+ }
8740
+ function featureKind(featureId) {
8741
+ return featureId.split(":", 1)[0] || "unknown";
8742
+ }
8677
8743
  function composeArgs(installPath, withOverrides, installMode = getInstallMode(installPath)) {
8678
8744
  const composeFile = installMode === "image" ? IMAGE_COMPOSE_FILE : SOURCE_COMPOSE_FILE;
8679
8745
  const args = ["compose", "--env-file", ".env", "-f", composeFile];
@@ -9383,6 +9449,70 @@ async function serverMakeAdmin(rest, flags) {
9383
9449
  console.log(`Admin privileges granted to ${email}.`);
9384
9450
  }
9385
9451
  }
9452
+ async function serverFeatures(rest, flags) {
9453
+ const action = rest[0] ?? "list";
9454
+ const featureId = rest[1];
9455
+ const installPath = resolveServerPath(flags);
9456
+ const configPath = join3(installPath, BACKEND_CONFIG_FILE);
9457
+ if (!existsSync5(configPath)) {
9458
+ throw new Error(`Backend config not found at ${configPath}. Run 'openmates server install' first or pass --path <dir>.`);
9459
+ }
9460
+ const content = readFileSync5(configPath, "utf-8");
9461
+ const overrides = parseFeatureOverrides(content);
9462
+ const writeOverrides = (nextOverrides) => {
9463
+ writeFileSync3(configPath, updateFeatureOverridesContent(content, nextOverrides));
9464
+ console.log(`Updated ${configPath}`);
9465
+ console.log("Restart the server for feature changes to take effect: openmates server restart");
9466
+ };
9467
+ if (action === "list") {
9468
+ console.log("Feature overrides:");
9469
+ console.log(` enabled: ${overrides.enabled.length ? overrides.enabled.join(", ") : "none"}`);
9470
+ console.log(` disabled: ${overrides.disabled.length ? overrides.disabled.join(", ") : "none"}`);
9471
+ console.log("\nKnown off-by-default features:");
9472
+ for (const [id, reason] of OFF_BY_DEFAULT_FEATURES.entries()) {
9473
+ const override = overrides.enabled.includes(id) ? "enabled override" : overrides.disabled.includes(id) ? "disabled override" : "default off";
9474
+ console.log(` ${id} (${featureKind(id)}): ${override} - ${reason}`);
9475
+ }
9476
+ return;
9477
+ }
9478
+ if (!featureId) {
9479
+ throw new Error(`Usage: openmates server features ${action} <feature-id>`);
9480
+ }
9481
+ if (action === "enable") {
9482
+ writeOverrides({
9483
+ enabled: normalizeFeatureList([...overrides.enabled, featureId]),
9484
+ disabled: overrides.disabled.filter((id) => id !== featureId)
9485
+ });
9486
+ return;
9487
+ }
9488
+ if (action === "disable") {
9489
+ writeOverrides({
9490
+ enabled: overrides.enabled.filter((id) => id !== featureId),
9491
+ disabled: normalizeFeatureList([...overrides.disabled, featureId])
9492
+ });
9493
+ return;
9494
+ }
9495
+ if (action === "reset") {
9496
+ writeOverrides({
9497
+ enabled: overrides.enabled.filter((id) => id !== featureId),
9498
+ disabled: overrides.disabled.filter((id) => id !== featureId)
9499
+ });
9500
+ return;
9501
+ }
9502
+ if (action === "explain") {
9503
+ const defaultReason = OFF_BY_DEFAULT_FEATURES.get(featureId);
9504
+ const override = overrides.enabled.includes(featureId) ? "enabled" : overrides.disabled.includes(featureId) ? "disabled" : "none";
9505
+ const defaultState = defaultReason ? "off" : "on";
9506
+ const effective = override === "enabled" ? "enabled" : override === "disabled" ? "disabled" : defaultState === "on" ? "enabled" : "disabled";
9507
+ console.log(`Feature: ${featureId}`);
9508
+ console.log(`Kind: ${featureKind(featureId)}`);
9509
+ console.log(`Default: ${defaultState}${defaultReason ? ` (${defaultReason})` : ""}`);
9510
+ console.log(`Override: ${override}`);
9511
+ console.log(`Effective after restart: ${effective}`);
9512
+ return;
9513
+ }
9514
+ throw new Error(`Unknown server features command '${action}'. Use list, enable, disable, reset, or explain.`);
9515
+ }
9386
9516
  async function serverUninstall(flags) {
9387
9517
  requireDocker();
9388
9518
  const installPath = resolveServerPath(flags);
@@ -9494,11 +9624,20 @@ Command Options:
9494
9624
  make-admin:
9495
9625
  openmates server make-admin <email>
9496
9626
 
9627
+ features:
9628
+ openmates server features list
9629
+ openmates server features enable <feature-id>
9630
+ openmates server features disable <feature-id>
9631
+ openmates server features reset <feature-id>
9632
+ openmates server features explain <feature-id>
9633
+
9497
9634
  Examples:
9498
9635
  openmates server install
9499
9636
  openmates server start --with-overrides
9500
9637
  openmates server logs --container api --follow
9501
9638
  openmates server make-admin user@example.com
9639
+ openmates server features disable app:videos
9640
+ openmates server features enable embed:code:application
9502
9641
  openmates server update
9503
9642
  openmates server update --dry-run
9504
9643
  openmates server update --image-tag v0.12.0-alpha.1
@@ -9530,6 +9669,8 @@ async function handleServer(subcommand, rest, flags) {
9530
9669
  return serverReset(flags);
9531
9670
  case "make-admin":
9532
9671
  return serverMakeAdmin(rest, flags);
9672
+ case "features":
9673
+ return serverFeatures(rest, flags);
9533
9674
  case "uninstall":
9534
9675
  return serverUninstall(flags);
9535
9676
  default:
@@ -26291,6 +26432,9 @@ Only output the final Markdown table. Do NOT include explanations, notes, or any
26291
26432
  anonymous_free_usage: {
26292
26433
  feature_notice: {
26293
26434
  text: "You are using free anonymous credits. File uploads, memories, chat sync, and some other features require creating an account."
26435
+ },
26436
+ daily_credits_exhausted: {
26437
+ text: "You used up your free daily credits. Sign up & buy credits to make full use of OpenMates."
26294
26438
  }
26295
26439
  },
26296
26440
  interactive_question_failed: {
@@ -27965,6 +28109,44 @@ Only output the final Markdown table. Do NOT include explanations, notes, or any
27965
28109
  account_created_second_login_info: {
27966
28110
  text: "If you signed up with a passkey, add password plus 2FA as a backup. If you signed up with password plus 2FA, add a passkey for faster secure login."
27967
28111
  },
28112
+ existing_account: {
28113
+ subject: {
28114
+ text: "An OpenMates account already exists for this email"
28115
+ },
28116
+ title: {
28117
+ text: "An account with your email already exists"
28118
+ },
28119
+ intro: {
28120
+ text: "Someone tried to create a new OpenMates account with this email address, but this email is already connected to an existing account."
28121
+ },
28122
+ saved_logins_title: {
28123
+ text: "Check your saved logins"
28124
+ },
28125
+ saved_logins_body: {
28126
+ text: "Your browser, password manager, or device may already have the login saved. Look for OpenMates in saved passwords or passkeys before creating a new account."
28127
+ },
28128
+ login_methods_title: {
28129
+ text: "Try your login methods"
28130
+ },
28131
+ login_methods_body: {
28132
+ text: "You can log in with a passkey, or with your password plus 2FA. If you set up backup codes, keep them ready for the 2FA step."
28133
+ },
28134
+ login_button: {
28135
+ text: "Log in to OpenMates"
28136
+ },
28137
+ recovery_key_title: {
28138
+ text: "Have your recovery key?"
28139
+ },
28140
+ recovery_key_body: {
28141
+ text: "If you do not remember your password or passkey but still have your recovery key, use recovery key login. It preserves your encrypted chats and account data."
28142
+ },
28143
+ recovery_button: {
28144
+ text: "Open login and use recovery key"
28145
+ },
28146
+ reset_warning: {
28147
+ text: "If you lost every login method and your recovery key, account reset is the last resort. Because OpenMates encrypts your data, resetting the account can permanently delete encrypted chats, memories, app settings, embeds, passkeys, and API keys."
28148
+ }
28149
+ },
27968
28150
  password_security_reminder: {
27969
28151
  subject: {
27970
28152
  text: "Action needed to secure your OpenMates account"
@@ -37693,7 +37875,7 @@ As of mid-2026, the severe supply shocks from the 2024\u20132025 avian flu have
37693
37875
  text: "Incognito"
37694
37876
  },
37695
37877
  learning_mode: {
37696
- text: "Learning Mode"
37878
+ text: "Learning"
37697
37879
  },
37698
37880
  learning_mode_active: {
37699
37881
  text: "Active for all chats on this account"
@@ -37725,6 +37907,57 @@ As of mid-2026, the severe supply shocks from the 2024\u20132025 avian flu have
37725
37907
  learning_mode_invalid_age_group: {
37726
37908
  text: "Invalid age group. Use under_10, 10_12, 13_15, 16_18, or adult."
37727
37909
  },
37910
+ learning_mode_enable_description: {
37911
+ text: "Choose the learner age group and set a passcode. Learning Mode will apply to every chat on this account."
37912
+ },
37913
+ learning_mode_disable_description: {
37914
+ text: "Enter the Learning Mode passcode to turn it off for this account."
37915
+ },
37916
+ learning_mode_active_detail: {
37917
+ text: "Learning Mode is active for every chat on this account. Answers stay teaching-first and selected tools are restricted."
37918
+ },
37919
+ learning_mode_inactive_detail: {
37920
+ text: "When enabled, OpenMates guides the learner step by step instead of giving complete answers."
37921
+ },
37922
+ learning_mode_age_group_label: {
37923
+ text: "Learner age group"
37924
+ },
37925
+ learning_mode_age_under_10: {
37926
+ text: "Under 10"
37927
+ },
37928
+ learning_mode_age_10_12: {
37929
+ text: "10 to 12"
37930
+ },
37931
+ learning_mode_age_13_15: {
37932
+ text: "13 to 15"
37933
+ },
37934
+ learning_mode_age_16_18: {
37935
+ text: "16 to 18"
37936
+ },
37937
+ learning_mode_age_adult: {
37938
+ text: "Adult"
37939
+ },
37940
+ learning_mode_enable_passcode_label: {
37941
+ text: "Set passcode"
37942
+ },
37943
+ learning_mode_disable_passcode_label: {
37944
+ text: "Enter passcode"
37945
+ },
37946
+ learning_mode_enable_passcode_placeholder: {
37947
+ text: "Create a passcode"
37948
+ },
37949
+ learning_mode_disable_passcode_placeholder: {
37950
+ text: "Learning Mode passcode"
37951
+ },
37952
+ learning_mode_passcode_required: {
37953
+ text: "Enter a passcode to continue."
37954
+ },
37955
+ learning_mode_enable_button: {
37956
+ text: "Start Learning Mode"
37957
+ },
37958
+ learning_mode_disable_button: {
37959
+ text: "Turn off Learning Mode"
37960
+ },
37728
37961
  incognito_explainer_description: {
37729
37962
  text: "Incognito mode applies only to new chats you create. New chats created while incognito mode is active are not synced across devices, not stored on the server, and not cached. These chats exist only in your current browser session. Existing chats remain unchanged."
37730
37963
  },
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  getExtForLang,
4
4
  serializeToYaml
5
- } from "./chunk-OSMG5HH3.js";
5
+ } from "./chunk-FTMMOTBN.js";
6
6
  import "./chunk-AXNRPVLE.js";
7
7
  export {
8
8
  getExtForLang,
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  deriveAppUrl,
10
10
  getExtForLang,
11
11
  serializeToYaml
12
- } from "./chunk-OSMG5HH3.js";
12
+ } from "./chunk-FTMMOTBN.js";
13
13
  import "./chunk-AXNRPVLE.js";
14
14
  export {
15
15
  ASSISTANT_FEEDBACK_REPORT_TITLE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openmates",
3
- "version": "0.12.0-alpha.17",
3
+ "version": "0.12.0-alpha.19",
4
4
  "description": "OpenMates CLI and SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",