anantham-v2 2.0.3 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/bin/anantham.js +10 -1
  2. package/dist/bin/anantham.js.map +1 -1
  3. package/dist/cli/command-registry.d.ts.map +1 -1
  4. package/dist/cli/command-registry.js +178 -99
  5. package/dist/cli/command-registry.js.map +1 -1
  6. package/dist/domain/tui.d.ts +1 -1
  7. package/dist/domain/tui.d.ts.map +1 -1
  8. package/dist/domain/tui.js +1 -0
  9. package/dist/domain/tui.js.map +1 -1
  10. package/dist/persistence/index.d.ts +2 -0
  11. package/dist/persistence/index.d.ts.map +1 -1
  12. package/dist/persistence/index.js +2 -0
  13. package/dist/persistence/index.js.map +1 -1
  14. package/dist/persistence/model-catalog-cache.d.ts +92 -0
  15. package/dist/persistence/model-catalog-cache.d.ts.map +1 -0
  16. package/dist/persistence/model-catalog-cache.js +430 -0
  17. package/dist/persistence/model-catalog-cache.js.map +1 -0
  18. package/dist/persistence/openrouter-key-validator.d.ts +40 -0
  19. package/dist/persistence/openrouter-key-validator.d.ts.map +1 -0
  20. package/dist/persistence/openrouter-key-validator.js +183 -0
  21. package/dist/persistence/openrouter-key-validator.js.map +1 -0
  22. package/dist/persistence/token-metrics-manager.d.ts +8 -2
  23. package/dist/persistence/token-metrics-manager.d.ts.map +1 -1
  24. package/dist/persistence/token-metrics-manager.js +60 -7
  25. package/dist/persistence/token-metrics-manager.js.map +1 -1
  26. package/dist/persistence/user-config-manager.d.ts +33 -9
  27. package/dist/persistence/user-config-manager.d.ts.map +1 -1
  28. package/dist/persistence/user-config-manager.js +133 -11
  29. package/dist/persistence/user-config-manager.js.map +1 -1
  30. package/dist/tui/index.d.ts +1 -0
  31. package/dist/tui/index.d.ts.map +1 -1
  32. package/dist/tui/index.js +1 -0
  33. package/dist/tui/index.js.map +1 -1
  34. package/dist/tui/model-accordion-browser.d.ts +80 -0
  35. package/dist/tui/model-accordion-browser.d.ts.map +1 -0
  36. package/dist/tui/model-accordion-browser.js +487 -0
  37. package/dist/tui/model-accordion-browser.js.map +1 -0
  38. package/dist/tui/model-catalog-cache.d.ts +7 -0
  39. package/dist/tui/model-catalog-cache.d.ts.map +1 -0
  40. package/dist/tui/model-catalog-cache.js +7 -0
  41. package/dist/tui/model-catalog-cache.js.map +1 -0
  42. package/dist/tui/teamwork-preview-canvas.d.ts +63 -0
  43. package/dist/tui/teamwork-preview-canvas.d.ts.map +1 -0
  44. package/dist/tui/teamwork-preview-canvas.js +294 -0
  45. package/dist/tui/teamwork-preview-canvas.js.map +1 -0
  46. package/dist/tui/terminal-layout.d.ts +56 -2
  47. package/dist/tui/terminal-layout.d.ts.map +1 -1
  48. package/dist/tui/terminal-layout.js +258 -22
  49. package/dist/tui/terminal-layout.js.map +1 -1
  50. package/dist/tui/terminal-logo-renderer.d.ts +63 -0
  51. package/dist/tui/terminal-logo-renderer.d.ts.map +1 -0
  52. package/dist/tui/terminal-logo-renderer.js +304 -0
  53. package/dist/tui/terminal-logo-renderer.js.map +1 -0
  54. package/dist/tui/token-usage-tracker.d.ts +8 -0
  55. package/dist/tui/token-usage-tracker.d.ts.map +1 -0
  56. package/dist/tui/token-usage-tracker.js +8 -0
  57. package/dist/tui/token-usage-tracker.js.map +1 -0
  58. package/dist/tui/tui-controller.d.ts +13 -0
  59. package/dist/tui/tui-controller.d.ts.map +1 -1
  60. package/dist/tui/tui-controller.js +116 -6
  61. package/dist/tui/tui-controller.js.map +1 -1
  62. package/dist/tui/tui-renderer.d.ts +3 -1
  63. package/dist/tui/tui-renderer.d.ts.map +1 -1
  64. package/dist/tui/tui-renderer.js +31 -41
  65. package/dist/tui/tui-renderer.js.map +1 -1
  66. package/package.json +1 -1
@@ -53,6 +53,14 @@ async function main() {
53
53
  else if (arg === "--session" && args[i + 1]) {
54
54
  initialSessionId = args[++i];
55
55
  }
56
+ else if (arg === "--logo" && args[i + 1]) {
57
+ const customLogo = args[++i];
58
+ process.env.ANANTHAM_LOGO_PATH = customLogo;
59
+ try {
60
+ UserConfigManager.getInstance().setLogoPath(customLogo);
61
+ }
62
+ catch { }
63
+ }
56
64
  else if (arg === "--help" || arg === "-h") {
57
65
  console.log(`
58
66
  Anantham V2 — Programmable AI Agent Operating Environment
@@ -68,13 +76,14 @@ Options:
68
76
  -e, --eval <cmd> Execute single slash command and exit
69
77
  --project <id> Initial active project ID
70
78
  --session <id> Initial active session ID
79
+ --logo <path> Custom logo image path (PNG/Sixel/ANSI)
71
80
  -h, --help Show this help message
72
81
  -v, --version Show runtime version
73
82
  `);
74
83
  process.exit(0);
75
84
  }
76
85
  else if (arg === "--version" || arg === "-v") {
77
- console.log("2.0.3");
86
+ console.log("2.0.5");
78
87
  process.exit(0);
79
88
  }
80
89
  else if (!arg.startsWith("-") && !executeCmd) {
@@ -1 +1 @@
1
- {"version":3,"file":"anantham.js","sourceRoot":"","sources":["../../src/bin/anantham.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"anantham.js","sourceRoot":"","sources":["../../src/bin/anantham.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"command-registry.d.ts","sourceRoot":"","sources":["../../src/cli/command-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"command-registry.d.ts","sourceRoot":"","sources":["../../src/cli/command-registry.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,9 @@ import { SlashMigrateCommand } from "./slash-migrate.js";
5
5
  import { maskSecret } from "../models/secret-store.js";
6
6
  import { UserConfigManager } from "../persistence/user-config-manager.js";
7
7
  import { TokenMetricsManager } from "../persistence/token-metrics-manager.js";
8
+ import { ModelCatalogCache } from "../persistence/model-catalog-cache.js";
9
+ import { validateOpenRouterKey } from "../persistence/openrouter-key-validator.js";
10
+ import { TeamworkPreviewCanvas } from "../tui/teamwork-preview-canvas.js";
8
11
  export const CURATED_MODELS_BY_PROVIDER = {
9
12
  openrouter: [
10
13
  "openrouter/anthropic/claude-3.5-sonnet",
@@ -65,7 +68,21 @@ export function getNumberedModelList(configMgr) {
65
68
  result.push({ id: customId, provider: "custom", isCustom: true });
66
69
  }
67
70
  }
68
- // 3. Fallback default models if no keys configured
71
+ // 3. Cached models from ModelCatalogCache (if any and not already present)
72
+ try {
73
+ const cached = ModelCatalogCache.getInstance().getCachedModels();
74
+ if (cached && cached.length > 0) {
75
+ for (const m of cached) {
76
+ if (!result.some((r) => r.id === m.id)) {
77
+ result.push({ id: m.id, provider: m.provider });
78
+ }
79
+ }
80
+ }
81
+ }
82
+ catch {
83
+ // safe fallback
84
+ }
85
+ // 4. Fallback default models if no keys configured
69
86
  if (result.length === 0) {
70
87
  const defaultOrder = ["openrouter", "gemini", "anthropic", "openai"];
71
88
  for (const prov of defaultOrder) {
@@ -119,7 +136,15 @@ export class CommandRegistry {
119
136
  }
120
137
  }
121
138
  getDescriptor(name) {
122
- return this.descriptors.get(name.toLowerCase());
139
+ const direct = this.descriptors.get(name.toLowerCase());
140
+ if (direct)
141
+ return direct;
142
+ for (const desc of this.descriptors.values()) {
143
+ if (desc.aliases.some((a) => a.toLowerCase() === name.toLowerCase())) {
144
+ return desc;
145
+ }
146
+ }
147
+ return undefined;
123
148
  }
124
149
  listDescriptors() {
125
150
  return Array.from(this.descriptors.values());
@@ -153,7 +178,7 @@ export class CommandRegistry {
153
178
  }, (cmd) => {
154
179
  if (cmd.args.length > 0) {
155
180
  const target = cmd.args[0].replace(/^\//, "").toLowerCase();
156
- const desc = this.descriptors.get(target);
181
+ const desc = this.getDescriptor(target);
157
182
  if (!desc) {
158
183
  return {
159
184
  success: false,
@@ -605,9 +630,9 @@ export class CommandRegistry {
605
630
  return {
606
631
  success: true,
607
632
  commandName: "version",
608
- message: "Anantham V2 v2.0.3",
633
+ message: "Anantham V2 v2.0.5",
609
634
  data: {
610
- version: "2.0.3",
635
+ version: "2.0.5",
611
636
  releaseChannel: "release",
612
637
  },
613
638
  exitRequested: false,
@@ -650,7 +675,7 @@ export class CommandRegistry {
650
675
  aliases: ["keys", "apikey", "connect"],
651
676
  usage: "/key [list | set <provider> <key> | remove <provider>]",
652
677
  options: [],
653
- }, (cmd, ctrl) => {
678
+ }, async (cmd, ctrl) => {
654
679
  let sub = cmd.args[0]?.toLowerCase() || "list";
655
680
  let providerArg = cmd.args[1];
656
681
  let keyArg = cmd.args[2];
@@ -675,12 +700,46 @@ export class CommandRegistry {
675
700
  if (!provider || !key) {
676
701
  throw new Error("Usage: /key set <provider> <apiKey> (e.g. /key set openrouter sk-or-v1-...)");
677
702
  }
703
+ if (provider === "openrouter") {
704
+ const validation = await validateOpenRouterKey(key);
705
+ if (!validation.valid) {
706
+ return {
707
+ success: false,
708
+ commandName: "key",
709
+ message: `✖ OpenRouter API key validation failed: ${validation.error || "Invalid key"}`,
710
+ data: { provider, valid: false, error: validation.error },
711
+ exitRequested: false,
712
+ };
713
+ }
714
+ configMgr.setApiKey(provider, key, workspaceDir);
715
+ if (validation.metadata) {
716
+ configMgr.setKeyMetadata(provider, validation.metadata);
717
+ }
718
+ const envVar = "OPENROUTER_API_KEY";
719
+ const meta = validation.metadata;
720
+ const metaLines = [];
721
+ if (meta?.label)
722
+ metaLines.push(` Label: ${meta.label}`);
723
+ if (meta) {
724
+ const limitStr = meta.limit !== null && meta.limit !== undefined ? `$${meta.limit} USD` : "Unlimited";
725
+ metaLines.push(` Usage: $${meta.usage.toFixed(4)} USD | Limit: ${limitStr}`);
726
+ metaLines.push(` Tier: ${meta.is_free_tier ? "Free Tier" : "Paid"}`);
727
+ }
728
+ const metaBlock = metaLines.length > 0 ? `\n${metaLines.join("\n")}` : "";
729
+ return {
730
+ success: true,
731
+ commandName: "key",
732
+ message: `✔ API key for provider '${provider}' connected successfully!${metaBlock}\n Variable: ${envVar} = ${maskSecret(key)}\n Saved to ~/.antigravity/config.json and workspace .env`,
733
+ data: { provider, envVar, maskedKey: maskSecret(key), metadata: meta },
734
+ exitRequested: false,
735
+ };
736
+ }
678
737
  configMgr.setApiKey(provider, key, workspaceDir);
679
738
  const envVar = `${provider.toUpperCase().replace(/-/g, "_")}_API_KEY`;
680
739
  return {
681
740
  success: true,
682
741
  commandName: "key",
683
- message: `✔ API key for provider '${provider}' connected successfully!\n Variable: ${envVar} = ${maskSecret(key)}\n Saved to ~/.anantham/config.json and workspace .env`,
742
+ message: `✔ API key for provider '${provider}' connected successfully!\n Variable: ${envVar} = ${maskSecret(key)}\n Saved to ~/.antigravity/config.json and workspace .env`,
684
743
  data: { provider, envVar, maskedKey: maskSecret(key) },
685
744
  exitRequested: false,
686
745
  };
@@ -701,7 +760,14 @@ export class CommandRegistry {
701
760
  }
702
761
  if (sub === "list") {
703
762
  const list = configMgr.listKeys();
704
- const rows = list.map((c) => ` ${c.provider.padEnd(12)} : ${c.masked.padEnd(16)} [${c.configured ? "✔ Configured" : "✖ Not Set"}]`);
763
+ const rows = list.map((c) => {
764
+ let metaExtra = "";
765
+ if (c.metadata) {
766
+ const limitStr = c.metadata.limit !== null && c.metadata.limit !== undefined ? `$${c.metadata.limit}` : "unlimited";
767
+ metaExtra = ` (${c.metadata.label || "default"} | usage: $${c.metadata.usage.toFixed(4)} / ${limitStr}${c.metadata.is_free_tier ? " | free tier" : ""})`;
768
+ }
769
+ return ` ${c.provider.padEnd(12)} : ${c.masked.padEnd(16)} [${c.configured ? "✔ Configured" : "✖ Not Set"}]${metaExtra}`;
770
+ });
705
771
  return {
706
772
  success: true,
707
773
  commandName: "key",
@@ -712,29 +778,69 @@ export class CommandRegistry {
712
778
  }
713
779
  throw new Error(`Unknown key subcommand '${sub}'. Use 'list', 'set <provider> <key>', or 'remove <provider>'.`);
714
780
  });
715
- // 15. /model
781
+ // 15. /models (Unified Model Command aliased to /model, /m, /model-list)
716
782
  this.registerCommand({
717
- name: "model",
718
- description: "Display, switch, or add active LLM models (supports /model <number>, /model add <id>)",
719
- aliases: ["m"],
720
- usage: "/model [<number> | <modelId> | add <modelId> | remove <modelId>]",
783
+ name: "models",
784
+ description: "Display, switch, search, or browse AI models (aliased to /model)",
785
+ aliases: ["model", "m", "model-list"],
786
+ usage: "/models [<number> | <modelId> | <provider> | add <id> | remove <id> | search <query> | all]",
721
787
  options: [],
722
- }, (cmd, ctrl) => {
788
+ }, async (cmd, ctrl) => {
723
789
  const configMgr = UserConfigManager.getInstance();
790
+ const cmdName = cmd.name.toLowerCase();
724
791
  const activeProjectId = ctrl.getContext().activeProjectId;
725
792
  const proj = activeProjectId ? this.projectRepo.findById(activeProjectId) : null;
726
793
  const currentModel = proj?.modelProfile || configMgr.getDefaultModel();
794
+ // 1. If run without arguments:
727
795
  if (cmd.args.length === 0) {
796
+ if (cmdName === "model") {
797
+ const list = getNumberedModelList(configMgr);
798
+ const customModels = configMgr.getCustomModels();
799
+ const customInfo = customModels.length > 0 ? `\nCustom models: ${customModels.join(", ")}` : "";
800
+ return {
801
+ success: true,
802
+ commandName: "model",
803
+ message: `Current active model: ${currentModel}\n\nQuick switch: /model <number> (e.g. /model 1)\nAdd custom: /model add <modelId>\nList models: /models${customInfo}`,
804
+ data: { model: currentModel, models: list, interactiveModal: true },
805
+ exitRequested: false,
806
+ };
807
+ }
808
+ const configuredKeys = configMgr.listKeys().filter((k) => k.configured);
809
+ const list = getNumberedModelList(configMgr);
810
+ let listBody;
811
+ if (configuredKeys.length > 0) {
812
+ const provNames = configuredKeys.map((k) => k.provider.toUpperCase()).join(", ");
813
+ const rows = list.map((item, idx) => {
814
+ const num = `[${idx + 1}]`.padEnd(4);
815
+ const isActive = item.id === currentModel ? " (ACTIVE)" : "";
816
+ const customTag = item.isCustom ? " [Custom]" : "";
817
+ return ` ${num} ${item.id}${customTag}${isActive}`;
818
+ });
819
+ listBody = `Available Models for Configured Providers (${provNames}):\n${rows.join("\n")}\n\nSwitch: /model <number> (e.g. /model 1) | /model <modelId>\nCustom: /model add <id> | Search: /models search <query>`;
820
+ }
821
+ else {
822
+ const fallbackRows = list.map((item, idx) => {
823
+ const num = `[${idx + 1}]`.padEnd(4);
824
+ const isActive = item.id === currentModel ? " (ACTIVE)" : "";
825
+ return ` ${num} ${item.id} [${item.provider}]${isActive}`;
826
+ });
827
+ listBody = `Curated AI Models (No API keys configured yet):\n${fallbackRows.join("\n")}\n\nConnect OpenRouter or other keys via:\n /key set openrouter <your-api-key>\nSwitch: /model <number> | View all: /models all`;
828
+ }
728
829
  return {
729
830
  success: true,
730
- commandName: "model",
731
- message: `Current active model: ${currentModel}\n\nQuick switch: /model <number> (e.g. /model 1)\nAdd custom: /model add <modelId>\nList models: /models`,
732
- data: { model: currentModel },
831
+ commandName: "models",
832
+ message: `Current active model: ${currentModel}\n\n${listBody}`,
833
+ data: {
834
+ model: currentModel,
835
+ activeModel: currentModel,
836
+ models: list,
837
+ interactiveModal: true,
838
+ },
733
839
  exitRequested: false,
734
840
  };
735
841
  }
736
842
  const sub = cmd.args[0].toLowerCase();
737
- // /model add <modelId>
843
+ // 2. /model add <modelId>
738
844
  if (sub === "add") {
739
845
  const modelId = cmd.args[1]?.trim();
740
846
  if (!modelId) {
@@ -748,13 +854,13 @@ export class CommandRegistry {
748
854
  }
749
855
  return {
750
856
  success: true,
751
- commandName: "model",
752
- message: `✔ Added custom model '${modelId}' and switched to it.\n Saved to ~/.anantham/config.json and active project.`,
857
+ commandName: cmdName,
858
+ message: `✔ Added custom model '${modelId}' and switched to it.\n Saved to ~/.antigravity/config.json and active project.`,
753
859
  data: { model: modelId, custom: true },
754
860
  exitRequested: false,
755
861
  };
756
862
  }
757
- // /model remove <modelId>
863
+ // 3. /model remove <modelId> or delete
758
864
  if (sub === "remove" || sub === "delete") {
759
865
  const modelId = cmd.args[1]?.trim();
760
866
  if (!modelId) {
@@ -763,7 +869,7 @@ export class CommandRegistry {
763
869
  const removed = configMgr.removeCustomModel(modelId);
764
870
  return {
765
871
  success: true,
766
- commandName: "model",
872
+ commandName: cmdName,
767
873
  message: removed
768
874
  ? `✔ Removed custom model '${modelId}'.`
769
875
  : `Model '${modelId}' was not in custom models list.`,
@@ -771,44 +877,8 @@ export class CommandRegistry {
771
877
  exitRequested: false,
772
878
  };
773
879
  }
774
- let targetModel = cmd.args[0].trim();
775
- // Check if numeric selection (e.g. /model 1 or /model 2)
776
- if (/^\d+$/.test(targetModel)) {
777
- const num = parseInt(targetModel, 10);
778
- const list = getNumberedModelList(configMgr);
779
- if (num < 1 || num > list.length) {
780
- throw new Error(`Invalid model index [${num}]. Run '/models' to view available numbers (1-${list.length}).`);
781
- }
782
- targetModel = list[num - 1].id;
783
- }
784
- configMgr.setDefaultModel(targetModel);
785
- if (proj) {
786
- proj.modelProfile = targetModel;
787
- this.projectRepo.save(proj);
788
- }
789
- return {
790
- success: true,
791
- commandName: "model",
792
- message: `✔ Active model switched to '${targetModel}' (persisted to config & project).`,
793
- data: { model: targetModel },
794
- exitRequested: false,
795
- };
796
- });
797
- // 16. /models
798
- this.registerCommand({
799
- name: "models",
800
- description: "List curated AI models, search OpenRouter models, or list by provider",
801
- aliases: ["model-list"],
802
- usage: "/models [all | <provider> | search <query> | fetch]",
803
- options: [],
804
- }, async (cmd, ctrl) => {
805
- const configMgr = UserConfigManager.getInstance();
806
- const activeProjectId = ctrl.getContext().activeProjectId;
807
- const proj = activeProjectId ? this.projectRepo.findById(activeProjectId) : null;
808
- const activeModel = proj?.modelProfile || configMgr.getDefaultModel();
809
- const arg = cmd.args[0]?.toLowerCase();
810
- // /models search <query> or /models fetch
811
- if (arg === "search" || arg === "fetch") {
880
+ // 4. /models search <query> or /models fetch
881
+ if (sub === "search" || sub === "fetch") {
812
882
  const query = cmd.args.slice(1).join(" ").toLowerCase();
813
883
  const orKey = configMgr.getApiKey("openrouter");
814
884
  if (!orKey) {
@@ -850,8 +920,8 @@ export class CommandRegistry {
850
920
  throw new Error(`Failed to query OpenRouter live models: ${err.message}`);
851
921
  }
852
922
  }
853
- // /models all
854
- if (arg === "all") {
923
+ // 5. /models all
924
+ if (sub === "all") {
855
925
  const sections = [];
856
926
  for (const [provider, models] of Object.entries(CURATED_MODELS_BY_PROVIDER)) {
857
927
  sections.push(`[${provider.toUpperCase()}]:\n` + models.slice(0, 3).map((m) => ` • ${m}`).join("\n"));
@@ -864,50 +934,57 @@ export class CommandRegistry {
864
934
  exitRequested: false,
865
935
  };
866
936
  }
867
- // Specific provider e.g. /models anthropic or /models openrouter
868
- if (arg && CURATED_MODELS_BY_PROVIDER[arg]) {
869
- const list = CURATED_MODELS_BY_PROVIDER[arg].map((m) => {
870
- const activeTag = m === activeModel ? " (ACTIVE)" : "";
937
+ // 6. Specific provider e.g. /models anthropic or /models openrouter
938
+ if (CURATED_MODELS_BY_PROVIDER[sub]) {
939
+ const list = CURATED_MODELS_BY_PROVIDER[sub].map((m) => {
940
+ const activeTag = m === currentModel ? " (ACTIVE)" : "";
871
941
  return ` • ${m}${activeTag}`;
872
942
  }).join("\n");
873
943
  return {
874
944
  success: true,
875
- commandName: "models",
876
- message: `Models for [${arg.toUpperCase()}]:\n${list}\n\nSwitch via: /model <modelId>`,
877
- data: CURATED_MODELS_BY_PROVIDER[arg],
945
+ commandName: cmdName,
946
+ message: `Models for [${sub.toUpperCase()}]:\n${list}\n\nSwitch via: /model <modelId>`,
947
+ data: CURATED_MODELS_BY_PROVIDER[sub],
878
948
  exitRequested: false,
879
949
  };
880
950
  }
881
- // Default: List models for configured providers + custom models
882
- const configuredKeys = configMgr.listKeys().filter((k) => k.configured);
883
- const list = getNumberedModelList(configMgr);
884
- if (configuredKeys.length > 0) {
885
- const provNames = configuredKeys.map((k) => k.provider.toUpperCase()).join(", ");
886
- const rows = list.map((item, idx) => {
951
+ // 7. Numeric selection (e.g. /model 1 or /model 2)
952
+ let targetModel = cmd.args[0].trim();
953
+ if (/^\d+$/.test(targetModel)) {
954
+ const num = parseInt(targetModel, 10);
955
+ const list = getNumberedModelList(configMgr);
956
+ if (num < 1 || num > list.length) {
957
+ throw new Error(`Invalid model index [${num}]. Run '/models' to view available numbers (1-${list.length}).`);
958
+ }
959
+ targetModel = list[num - 1].id;
960
+ }
961
+ else if (cmdName === "models" && !targetModel.includes("/")) {
962
+ // If invoked as /models with an unknown provider argument, fall back gracefully to Curated AI Models list
963
+ const list = getNumberedModelList(configMgr);
964
+ const fallbackRows = list.map((item, idx) => {
887
965
  const num = `[${idx + 1}]`.padEnd(4);
888
- const isActive = item.id === activeModel ? " (ACTIVE)" : "";
889
- const customTag = item.isCustom ? " [Custom]" : "";
890
- return ` ${num} ${item.id}${customTag}${isActive}`;
966
+ const isActive = item.id === currentModel ? " (ACTIVE)" : "";
967
+ return ` ${num} ${item.id} [${item.provider}]${isActive}`;
891
968
  });
892
969
  return {
893
970
  success: true,
894
971
  commandName: "models",
895
- message: `Available Models for Configured Providers (${provNames}):\n${rows.join("\n")}\n\nSwitch: /model <number> (e.g. /model 1) | /model <modelId>\nCustom: /model add <id> | Search: /models search <query>`,
972
+ message: `Curated AI Models (Unknown provider '${cmd.args[0]}'):\n${fallbackRows.join("\n")}\n\nSwitch: /model <number> | View all: /models all`,
896
973
  data: list,
897
974
  exitRequested: false,
898
975
  };
899
976
  }
900
- // Fallback when no keys configured
901
- const fallbackRows = list.map((item, idx) => {
902
- const num = `[${idx + 1}]`.padEnd(4);
903
- const isActive = item.id === activeModel ? " (ACTIVE)" : "";
904
- return ` ${num} ${item.id} [${item.provider}]${isActive}`;
905
- });
977
+ // 8. Model ID switch (e.g. /model gpt-4o or /model openrouter/anthropic/claude-3.5-sonnet)
978
+ configMgr.setDefaultModel(targetModel);
979
+ if (proj) {
980
+ proj.modelProfile = targetModel;
981
+ this.projectRepo.save(proj);
982
+ }
906
983
  return {
907
984
  success: true,
908
- commandName: "models",
909
- message: `Curated AI Models (No API keys configured yet):\n${fallbackRows.join("\n")}\n\nConnect OpenRouter or other keys via:\n /key set openrouter <your-api-key>\nSwitch: /model <number> | View all: /models all`,
910
- data: list,
985
+ commandName: cmdName,
986
+ message: `✔ Active model switched to '${targetModel}' (persisted to config & project).`,
987
+ data: { model: targetModel },
911
988
  exitRequested: false,
912
989
  };
913
990
  });
@@ -956,17 +1033,19 @@ export class CommandRegistry {
956
1033
  return {
957
1034
  success: true,
958
1035
  commandName: "teamwork-preview",
959
- message: [
960
- "❖ Teamwork Preview Harness Status: ONLINE",
961
- " Engine : Anantham V2 Autonomous Agent Coordinator",
962
- " Parallel Workers : 4 active worker execution slots",
963
- " Task Partitioning: Wave DAG with generation-fenced leases",
964
- " Durability : SQLite WAL (synchronous = FULL, RPO-0)",
965
- " Safety Boundary : ToolGateway sandboxed capability routing",
966
- "",
967
- "Autonomous team preview ready. Submit prompt tasks via interactive CLI or TUI.",
968
- ].join("\n"),
969
- data: { status: "ONLINE", workers: 4, mode: "wave_dag" },
1036
+ message: TeamworkPreviewCanvas.renderText(),
1037
+ data: {
1038
+ status: "ONLINE",
1039
+ workers: 4,
1040
+ mode: "wave_dag",
1041
+ fencingToken: "0x04F2",
1042
+ epoch: 14,
1043
+ depthWaves: 3,
1044
+ worktrees: ["/wt/architect", "/wt/coder-1", "/wt/coder-2", "/wt/sre"],
1045
+ leasesHeld: "4/4 held",
1046
+ durability: "SQLite WAL synchronous = FULL, RPO-0",
1047
+ security: "ToolGateway sandboxed",
1048
+ },
970
1049
  exitRequested: false,
971
1050
  };
972
1051
  });