@involvex/super-agent-cli 0.0.62 → 0.0.64

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/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
2
3
  var __create = Object.create;
3
4
  var __getProtoOf = Object.getPrototypeOf;
4
5
  var __defProp = Object.defineProperty;
@@ -41,12 +42,14 @@ var __export = (target, all) => {
41
42
  });
42
43
  };
43
44
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
45
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
44
46
 
45
47
  // src/utils/settings-manager.ts
46
48
  var exports_settings_manager = {};
47
49
  __export(exports_settings_manager, {
48
50
  getSettingsManager: () => getSettingsManager,
49
- SettingsManager: () => SettingsManager
51
+ SettingsManager: () => SettingsManager,
52
+ PROVIDER_MODELS: () => PROVIDER_MODELS
50
53
  });
51
54
  import * as path from "path";
52
55
  import * as os from "os";
@@ -87,7 +90,20 @@ class SettingsManager {
87
90
  }
88
91
  const content = fs.readFileSync(this.userSettingsPath, "utf-8");
89
92
  const settings = JSON.parse(content);
90
- return { ...DEFAULT_USER_SETTINGS, ...settings };
93
+ const mergedProviders = { ...DEFAULT_USER_SETTINGS.providers };
94
+ if (settings.providers) {
95
+ for (const [key, value] of Object.entries(settings.providers)) {
96
+ mergedProviders[key] = {
97
+ ...mergedProviders[key] || {},
98
+ ...value
99
+ };
100
+ }
101
+ }
102
+ return {
103
+ ...DEFAULT_USER_SETTINGS,
104
+ ...settings,
105
+ providers: mergedProviders
106
+ };
91
107
  } catch (error) {
92
108
  console.warn("Failed to load user settings:", error);
93
109
  return { ...DEFAULT_USER_SETTINGS };
@@ -175,6 +191,12 @@ class SettingsManager {
175
191
  if (models) {
176
192
  return models;
177
193
  }
194
+ if (activeProvider) {
195
+ const config = this.getEffectiveSettings().providers[activeProvider];
196
+ if (config && config.model) {
197
+ return [config.model];
198
+ }
199
+ }
178
200
  return [
179
201
  "grok-beta",
180
202
  "grok-vision-beta",
@@ -336,6 +358,94 @@ var init_settings_manager = __esm(() => {
336
358
  DEFAULT_PROJECT_SETTINGS = {};
337
359
  });
338
360
 
361
+ // src/utils/file-utils.ts
362
+ var exports_file_utils = {};
363
+ __export(exports_file_utils, {
364
+ resolveSourcePath: () => resolveSourcePath,
365
+ listFilesRecursive: () => listFilesRecursive,
366
+ filterFileEntries: () => filterFileEntries,
367
+ expandHome: () => expandHome
368
+ });
369
+ import * as fs2 from "fs-extra";
370
+ import * as path2 from "path";
371
+ import * as os2 from "os";
372
+ function expandHome(filepath) {
373
+ if (filepath.startsWith("~")) {
374
+ return path2.join(os2.homedir(), filepath.slice(1));
375
+ }
376
+ return filepath;
377
+ }
378
+ function resolveSourcePath(source) {
379
+ const defaults = {
380
+ gemini: "~/.gemini",
381
+ claude: "~/.claude",
382
+ kilo: "~/.kilocode"
383
+ };
384
+ const rawPath = defaults[source.toLowerCase()] || source;
385
+ return expandHome(rawPath);
386
+ }
387
+ async function listFilesRecursive(dir, baseDir = dir, maxDepth = 3) {
388
+ const result = [];
389
+ try {
390
+ const entries = await fs2.readdir(dir, { withFileTypes: true });
391
+ for (const entry of entries) {
392
+ const fullPath = path2.join(dir, entry.name);
393
+ const relativePath = path2.relative(baseDir, fullPath);
394
+ const isIgnored = [
395
+ "node_modules",
396
+ ".git",
397
+ "dist",
398
+ "build",
399
+ ".next",
400
+ "target",
401
+ "vendor"
402
+ ].includes(entry.name);
403
+ if (isIgnored) {
404
+ continue;
405
+ }
406
+ if (entry.name.startsWith(".") && entry.name !== ".env") {
407
+ continue;
408
+ }
409
+ result.push({
410
+ name: entry.name,
411
+ path: relativePath,
412
+ isDirectory: entry.isDirectory()
413
+ });
414
+ if (entry.isDirectory() && maxDepth > 0) {
415
+ const subFiles = await listFilesRecursive(fullPath, baseDir, maxDepth - 1);
416
+ result.push(...subFiles);
417
+ }
418
+ }
419
+ } catch (error) {}
420
+ return result;
421
+ }
422
+ function filterFileEntries(entries, query) {
423
+ if (!query) {
424
+ return entries.slice(0, 20);
425
+ }
426
+ const lowerQuery = query.toLowerCase();
427
+ return entries.filter((e) => e.path.toLowerCase().includes(lowerQuery)).sort((a, b) => {
428
+ const aLower = a.name.toLowerCase();
429
+ const bLower = b.name.toLowerCase();
430
+ if (aLower === lowerQuery && bLower !== lowerQuery) {
431
+ return -1;
432
+ }
433
+ if (bLower === lowerQuery && aLower !== lowerQuery) {
434
+ return 1;
435
+ }
436
+ const aPathLower = a.path.toLowerCase();
437
+ const bPathLower = b.path.toLowerCase();
438
+ if (aPathLower.startsWith(lowerQuery) && !bPathLower.startsWith(lowerQuery)) {
439
+ return -1;
440
+ }
441
+ if (bPathLower.startsWith(lowerQuery) && !aPathLower.startsWith(lowerQuery)) {
442
+ return 1;
443
+ }
444
+ return a.path.length - b.path.length;
445
+ }).slice(0, 20);
446
+ }
447
+ var init_file_utils = () => {};
448
+
339
449
  // src/mcp/config.ts
340
450
  var exports_config = {};
341
451
  __export(exports_config, {
@@ -412,14 +522,231 @@ var init_config = __esm(() => {
412
522
  PREDEFINED_SERVERS = {};
413
523
  });
414
524
 
525
+ // src/agents/manager.ts
526
+ var exports_manager = {};
527
+ __export(exports_manager, {
528
+ AgentsManager: () => AgentsManager
529
+ });
530
+ import fs6 from "fs/promises";
531
+ import path6 from "path";
532
+
533
+ class AgentsManager {
534
+ static instance;
535
+ agentsPath;
536
+ constructor() {
537
+ this.agentsPath = path6.join(getSettingsManager().getStorageDirectory(), "agents");
538
+ }
539
+ static getInstance() {
540
+ if (!AgentsManager.instance) {
541
+ AgentsManager.instance = new AgentsManager;
542
+ }
543
+ return AgentsManager.instance;
544
+ }
545
+ async ensureAgentsDirectory() {
546
+ try {
547
+ await fs6.mkdir(this.agentsPath, { recursive: true });
548
+ } catch (error) {}
549
+ }
550
+ async listAgents() {
551
+ await this.ensureAgentsDirectory();
552
+ try {
553
+ const files = await fs6.readdir(this.agentsPath);
554
+ const agents = [];
555
+ for (const file of files) {
556
+ if (file.endsWith(".json")) {
557
+ try {
558
+ const content = await fs6.readFile(path6.join(this.agentsPath, file), "utf-8");
559
+ agents.push(JSON.parse(content));
560
+ } catch (e) {}
561
+ }
562
+ }
563
+ return agents;
564
+ } catch (error) {
565
+ return [];
566
+ }
567
+ }
568
+ async getAgent(name) {
569
+ try {
570
+ const content = await fs6.readFile(path6.join(this.agentsPath, `${name}.json`), "utf-8");
571
+ return JSON.parse(content);
572
+ } catch (error) {
573
+ return null;
574
+ }
575
+ }
576
+ async createAgent(config) {
577
+ await this.ensureAgentsDirectory();
578
+ const filePath = path6.join(this.agentsPath, `${config.name}.json`);
579
+ await fs6.writeFile(filePath, JSON.stringify(config, null, 2));
580
+ }
581
+ async generateAgent(name, description, agent) {
582
+ const prompt = `Create a configuration for an AI agent named "${name}" based on this description: "${description}".
583
+
584
+ The configuration should be a JSON object matching this interface:
585
+ interface AgentConfig {
586
+ name: string;
587
+ role: string;
588
+ description: string;
589
+ model?: string; // suggest a model if appropriate, or leave undefined
590
+ tools?: string[]; // suggest relevant tools/skills names
591
+ temperature?: number;
592
+ systemPrompt?: string; // a detailed system prompt for this agent
593
+ }
594
+
595
+ Return ONLY the JSON object.`;
596
+ const response = await agent.processUserMessage(prompt);
597
+ let jsonData = "";
598
+ for (const entry of response) {
599
+ if (entry.type === "assistant") {
600
+ const match = entry.content.match(/```(?:json)?\n([\s\S]*?)```/);
601
+ if (match) {
602
+ jsonData = match[1];
603
+ break;
604
+ } else {
605
+ if (entry.content.trim().startsWith("{")) {
606
+ jsonData = entry.content;
607
+ }
608
+ }
609
+ }
610
+ }
611
+ if (!jsonData) {
612
+ throw new Error("Failed to generate agent configuration");
613
+ }
614
+ try {
615
+ const config = JSON.parse(jsonData);
616
+ config.name = name;
617
+ await this.createAgent(config);
618
+ } catch (e) {
619
+ throw new Error(`Failed to parse generated agent config: ${e.message}`);
620
+ }
621
+ }
622
+ async deleteAgent(name) {
623
+ try {
624
+ const filePath = path6.join(this.agentsPath, `${name}.json`);
625
+ await fs6.unlink(filePath);
626
+ } catch (error) {
627
+ throw new Error(`Failed to delete agent '${name}'`);
628
+ }
629
+ }
630
+ }
631
+ var init_manager = __esm(() => {
632
+ init_settings_manager();
633
+ });
634
+
635
+ // src/skills/manager.ts
636
+ var exports_manager2 = {};
637
+ __export(exports_manager2, {
638
+ SkillsManager: () => SkillsManager
639
+ });
640
+ import fs7 from "fs/promises";
641
+ import path7 from "path";
642
+
643
+ class SkillsManager {
644
+ static instance;
645
+ skillsPath;
646
+ constructor() {
647
+ this.skillsPath = path7.join(getSettingsManager().getStorageDirectory(), "skills");
648
+ }
649
+ static getInstance() {
650
+ if (!SkillsManager.instance) {
651
+ SkillsManager.instance = new SkillsManager;
652
+ }
653
+ return SkillsManager.instance;
654
+ }
655
+ async ensureSkillsDirectory() {
656
+ try {
657
+ await fs7.mkdir(this.skillsPath, { recursive: true });
658
+ } catch (error) {}
659
+ }
660
+ async listSkills() {
661
+ await this.ensureSkillsDirectory();
662
+ try {
663
+ const files = await fs7.readdir(this.skillsPath);
664
+ return files.filter((file) => file.endsWith(".ts") || file.endsWith(".js") || file.endsWith(".json")).map((file) => path7.parse(file).name);
665
+ } catch (error) {
666
+ return [];
667
+ }
668
+ }
669
+ async getSkillPath(name) {
670
+ const extensions = [".ts", ".js", ".json"];
671
+ for (const ext of extensions) {
672
+ const fullPath = path7.join(this.skillsPath, `${name}${ext}`);
673
+ try {
674
+ await fs7.access(fullPath);
675
+ return fullPath;
676
+ } catch {
677
+ continue;
678
+ }
679
+ }
680
+ throw new Error(`Skill '${name}' not found`);
681
+ }
682
+ async getSkillContent(name) {
683
+ const skillPath = await this.getSkillPath(name);
684
+ return await fs7.readFile(skillPath, "utf-8");
685
+ }
686
+ async createSkill(name, description, agent) {
687
+ await this.ensureSkillsDirectory();
688
+ const prompt = `Create a robust TypeScript skill for the Super Agent CLI named "${name}".
689
+
690
+ Description: ${description}
691
+
692
+ The skill should be a module that exports a default function or class that implements the desired functionality.
693
+ It should valid standalone TypeScript code.
694
+ Include comments explaining how it works.
695
+
696
+ Structure:
697
+ \`\`\`typescript
698
+ // ${name} skill
699
+ export default async function(args: any) {
700
+ // implementation
701
+ }
702
+ \`\`\`
703
+
704
+ Return ONLY the code block.`;
705
+ const response = await agent.processUserMessage(prompt);
706
+ let code = "";
707
+ for (const entry of response) {
708
+ if (entry.type === "assistant") {
709
+ const match = entry.content.match(/```(?:typescript|ts)?\n([\s\S]*?)```/);
710
+ if (match) {
711
+ code = match[1];
712
+ break;
713
+ } else {
714
+ code = entry.content;
715
+ }
716
+ }
717
+ }
718
+ if (!code) {
719
+ throw new Error("Failed to generate skill code");
720
+ }
721
+ const filePath = path7.join(this.skillsPath, `${name}.ts`);
722
+ await fs7.writeFile(filePath, code);
723
+ }
724
+ async deleteSkill(name) {
725
+ try {
726
+ const skillPath = await this.getSkillPath(name);
727
+ await fs7.unlink(skillPath);
728
+ } catch (error) {
729
+ throw new Error(`Failed to delete skill '${name}': ${error.message}`);
730
+ }
731
+ }
732
+ async saveSkill(name, content) {
733
+ await this.ensureSkillsDirectory();
734
+ const filePath = path7.join(this.skillsPath, name.endsWith(".ts") ? name : `${name}.ts`);
735
+ await fs7.writeFile(filePath, content);
736
+ }
737
+ }
738
+ var init_manager2 = __esm(() => {
739
+ init_settings_manager();
740
+ });
741
+
415
742
  // src/indexing/indexer.ts
416
743
  var exports_indexer = {};
417
744
  __export(exports_indexer, {
418
745
  getFileIndexer: () => getFileIndexer,
419
746
  FileIndexer: () => FileIndexer
420
747
  });
421
- import * as fs9 from "fs-extra";
422
- import * as path8 from "path";
748
+ import * as fs11 from "fs-extra";
749
+ import * as path10 from "path";
423
750
 
424
751
  class FileIndexer {
425
752
  static instance;
@@ -429,7 +756,7 @@ class FileIndexer {
429
756
  isScanning = false;
430
757
  constructor() {
431
758
  const settingsManager = getSettingsManager();
432
- this.storagePath = path8.join(settingsManager.getStorageDirectory(), INDEX_FILENAME);
759
+ this.storagePath = path10.join(settingsManager.getStorageDirectory(), INDEX_FILENAME);
433
760
  this.rootPath = process.cwd();
434
761
  }
435
762
  static getInstance() {
@@ -440,8 +767,8 @@ class FileIndexer {
440
767
  }
441
768
  async loadIndex() {
442
769
  try {
443
- if (fs9.existsSync(this.storagePath)) {
444
- const content = await fs9.readFile(this.storagePath, "utf-8");
770
+ if (fs11.existsSync(this.storagePath)) {
771
+ const content = await fs11.readFile(this.storagePath, "utf-8");
445
772
  this.index = JSON.parse(content);
446
773
  if (!this.index || this.index.metadata.version !== INDEX_VERSION || this.index.metadata.rootPath !== this.rootPath) {
447
774
  this.index = null;
@@ -457,7 +784,7 @@ class FileIndexer {
457
784
  return;
458
785
  }
459
786
  try {
460
- await fs9.outputFile(this.storagePath, JSON.stringify(this.index, null, 2));
787
+ await fs11.outputFile(this.storagePath, JSON.stringify(this.index, null, 2));
461
788
  } catch (error) {
462
789
  console.error("Failed to save file index:", error);
463
790
  }
@@ -483,15 +810,15 @@ class FileIndexer {
483
810
  ];
484
811
  const entries = [];
485
812
  const scanDir = async (dir) => {
486
- const files = await fs9.readdir(dir, { withFileTypes: true });
813
+ const files = await fs11.readdir(dir, { withFileTypes: true });
487
814
  for (const file of files) {
488
815
  if (ignoreList.includes(file.name) || file.name.startsWith(".")) {
489
816
  if (file.name !== ".env") {
490
817
  continue;
491
818
  }
492
819
  }
493
- const fullPath = path8.join(dir, file.name);
494
- const relativePath = path8.relative(this.rootPath, fullPath);
820
+ const fullPath = path10.join(dir, file.name);
821
+ const relativePath = path10.relative(this.rootPath, fullPath);
495
822
  if (file.isDirectory()) {
496
823
  entries.push({
497
824
  path: relativePath,
@@ -501,7 +828,7 @@ class FileIndexer {
501
828
  });
502
829
  await scanDir(fullPath);
503
830
  } else {
504
- const stats = await fs9.stat(fullPath);
831
+ const stats = await fs11.stat(fullPath);
505
832
  entries.push({
506
833
  path: relativePath,
507
834
  size: stats.size,
@@ -542,8 +869,8 @@ __export(exports_session_manager, {
542
869
  getSessionManager: () => getSessionManager,
543
870
  SessionManager: () => SessionManager
544
871
  });
545
- import * as fs13 from "fs-extra";
546
- import * as path12 from "path";
872
+ import * as fs15 from "fs-extra";
873
+ import * as path14 from "path";
547
874
 
548
875
  class SessionManager {
549
876
  static instance;
@@ -551,8 +878,8 @@ class SessionManager {
551
878
  currentSession = null;
552
879
  constructor() {
553
880
  const settingsManager = getSettingsManager();
554
- this.sessionsDir = path12.join(settingsManager.getStorageDirectory(), "sessions");
555
- fs13.ensureDirSync(this.sessionsDir);
881
+ this.sessionsDir = path14.join(settingsManager.getStorageDirectory(), "sessions");
882
+ fs15.ensureDirSync(this.sessionsDir);
556
883
  }
557
884
  static getInstance() {
558
885
  if (!SessionManager.instance) {
@@ -561,18 +888,18 @@ class SessionManager {
561
888
  return SessionManager.instance;
562
889
  }
563
890
  generateSessionId(workingDir) {
564
- const normalized = path12.normalize(workingDir).toLowerCase();
891
+ const normalized = path14.normalize(workingDir).toLowerCase();
565
892
  return Buffer.from(normalized).toString("base64").replace(/[/+=]/g, "_");
566
893
  }
567
894
  getSessionFilePath(sessionId) {
568
- return path12.join(this.sessionsDir, `${sessionId}.json`);
895
+ return path14.join(this.sessionsDir, `${sessionId}.json`);
569
896
  }
570
897
  async getOrCreateSession(workingDirectory, name) {
571
898
  const sessionId = this.generateSessionId(workingDirectory);
572
899
  const sessionFile = this.getSessionFilePath(sessionId);
573
900
  try {
574
- if (await fs13.pathExists(sessionFile)) {
575
- const session = await fs13.readJson(sessionFile);
901
+ if (await fs15.pathExists(sessionFile)) {
902
+ const session = await fs15.readJson(sessionFile);
576
903
  session.lastAccessed = Date.now();
577
904
  this.currentSession = session;
578
905
  await this.saveSession(session);
@@ -582,7 +909,7 @@ class SessionManager {
582
909
  const newSession = {
583
910
  id: sessionId,
584
911
  workingDirectory,
585
- name: name || path12.basename(workingDirectory),
912
+ name: name || path14.basename(workingDirectory),
586
913
  messages: [],
587
914
  lastAccessed: Date.now(),
588
915
  createdAt: Date.now()
@@ -593,7 +920,7 @@ class SessionManager {
593
920
  }
594
921
  async saveSession(session) {
595
922
  const sessionFile = this.getSessionFilePath(session.id);
596
- await fs13.outputJson(sessionFile, session, { spaces: 2 });
923
+ await fs15.outputJson(sessionFile, session, { spaces: 2 });
597
924
  }
598
925
  async addMessage(message) {
599
926
  if (!this.currentSession) {
@@ -604,12 +931,12 @@ class SessionManager {
604
931
  await this.saveSession(this.currentSession);
605
932
  }
606
933
  async listSessions() {
607
- const sessionFiles = await fs13.readdir(this.sessionsDir);
934
+ const sessionFiles = await fs15.readdir(this.sessionsDir);
608
935
  const sessions = [];
609
936
  for (const file of sessionFiles) {
610
937
  if (file.endsWith(".json")) {
611
938
  try {
612
- const session = await fs13.readJson(path12.join(this.sessionsDir, file));
939
+ const session = await fs15.readJson(path14.join(this.sessionsDir, file));
613
940
  sessions.push(session);
614
941
  } catch (error) {}
615
942
  }
@@ -619,8 +946,8 @@ class SessionManager {
619
946
  }
620
947
  async deleteSession(sessionId) {
621
948
  const sessionFile = this.getSessionFilePath(sessionId);
622
- if (await fs13.pathExists(sessionFile)) {
623
- await fs13.remove(sessionFile);
949
+ if (await fs15.pathExists(sessionFile)) {
950
+ await fs15.remove(sessionFile);
624
951
  }
625
952
  }
626
953
  getCurrentSession() {
@@ -629,8 +956,8 @@ class SessionManager {
629
956
  async switchSession(sessionId) {
630
957
  const sessionFile = this.getSessionFilePath(sessionId);
631
958
  try {
632
- if (await fs13.pathExists(sessionFile)) {
633
- const session = await fs13.readJson(sessionFile);
959
+ if (await fs15.pathExists(sessionFile)) {
960
+ const session = await fs15.readJson(sessionFile);
634
961
  session.lastAccessed = Date.now();
635
962
  this.currentSession = session;
636
963
  await this.saveSession(session);
@@ -651,12 +978,15 @@ var init_session_manager = __esm(() => {
651
978
  var require_package = __commonJS((exports, module) => {
652
979
  module.exports = {
653
980
  name: "@involvex/super-agent-cli",
654
- version: "0.0.62",
981
+ version: "0.0.64",
655
982
  description: "An open-source AI agent that brings the power of Super Agent directly into your terminal.",
656
983
  keywords: [
657
984
  "cli",
658
985
  "agent",
659
- "text-editor",
986
+ "cli-agent",
987
+ "ai-cli",
988
+ "coding-cli",
989
+ "ai-coding-cli",
660
990
  "ai"
661
991
  ],
662
992
  homepage: "https://involvex.github.io/super-agent-cli/",
@@ -758,8 +1088,8 @@ __export(exports_update_checker, {
758
1088
  getUpdateChecker: () => getUpdateChecker,
759
1089
  UpdateChecker: () => UpdateChecker
760
1090
  });
761
- import * as fs14 from "fs-extra";
762
- import * as path13 from "path";
1091
+ import * as fs16 from "fs-extra";
1092
+ import * as path15 from "path";
763
1093
  import axios3 from "axios";
764
1094
 
765
1095
  class UpdateChecker {
@@ -768,7 +1098,7 @@ class UpdateChecker {
768
1098
  currentVersion;
769
1099
  constructor(currentVersion) {
770
1100
  const settingsManager = getSettingsManager();
771
- this.cacheFile = path13.join(settingsManager.getStorageDirectory(), "update-cache.json");
1101
+ this.cacheFile = path15.join(settingsManager.getStorageDirectory(), "update-cache.json");
772
1102
  this.currentVersion = currentVersion;
773
1103
  }
774
1104
  static getInstance(currentVersion) {
@@ -779,8 +1109,8 @@ class UpdateChecker {
779
1109
  }
780
1110
  async loadCache() {
781
1111
  try {
782
- if (await fs14.pathExists(this.cacheFile)) {
783
- const cache = await fs14.readJson(this.cacheFile);
1112
+ if (await fs16.pathExists(this.cacheFile)) {
1113
+ const cache = await fs16.readJson(this.cacheFile);
784
1114
  const now = Date.now();
785
1115
  if (cache.lastChecked && now - cache.lastChecked < CACHE_DURATION) {
786
1116
  return cache;
@@ -791,7 +1121,7 @@ class UpdateChecker {
791
1121
  }
792
1122
  async saveCache(info) {
793
1123
  try {
794
- await fs14.outputJson(this.cacheFile, info);
1124
+ await fs16.outputJson(this.cacheFile, info);
795
1125
  } catch (error) {}
796
1126
  }
797
1127
  compareVersions(v1, v2) {
@@ -971,91 +1301,30 @@ class ConfirmationService extends EventEmitter {
971
1301
  }
972
1302
  throw new Error("VS Code not found");
973
1303
  }
974
- isPending() {
975
- return this.pendingConfirmation !== null;
976
- }
977
- resetSession() {
978
- this.sessionFlags = {
979
- fileOperations: false,
980
- bashCommands: false,
981
- allOperations: false
982
- };
983
- }
984
- getSessionFlags() {
985
- return { ...this.sessionFlags };
986
- }
987
- setSessionFlag(flagType, value) {
988
- this.sessionFlags[flagType] = value;
989
- }
990
- }
991
-
992
- // src/index.ts
993
- init_settings_manager();
994
-
995
- // src/utils/file-utils.ts
996
- import * as fs2 from "fs-extra";
997
- import * as path2 from "path";
998
- async function listFilesRecursive(dir, baseDir = dir, maxDepth = 3) {
999
- const result = [];
1000
- try {
1001
- const entries = await fs2.readdir(dir, { withFileTypes: true });
1002
- for (const entry of entries) {
1003
- const fullPath = path2.join(dir, entry.name);
1004
- const relativePath = path2.relative(baseDir, fullPath);
1005
- const isIgnored = [
1006
- "node_modules",
1007
- ".git",
1008
- "dist",
1009
- "build",
1010
- ".next",
1011
- "target",
1012
- "vendor"
1013
- ].includes(entry.name);
1014
- if (isIgnored) {
1015
- continue;
1016
- }
1017
- if (entry.name.startsWith(".") && entry.name !== ".env") {
1018
- continue;
1019
- }
1020
- result.push({
1021
- name: entry.name,
1022
- path: relativePath,
1023
- isDirectory: entry.isDirectory()
1024
- });
1025
- if (entry.isDirectory() && maxDepth > 0) {
1026
- const subFiles = await listFilesRecursive(fullPath, baseDir, maxDepth - 1);
1027
- result.push(...subFiles);
1028
- }
1029
- }
1030
- } catch (error) {}
1031
- return result;
1032
- }
1033
- function filterFileEntries(entries, query) {
1034
- if (!query) {
1035
- return entries.slice(0, 20);
1036
- }
1037
- const lowerQuery = query.toLowerCase();
1038
- return entries.filter((e) => e.path.toLowerCase().includes(lowerQuery)).sort((a, b) => {
1039
- const aLower = a.name.toLowerCase();
1040
- const bLower = b.name.toLowerCase();
1041
- if (aLower === lowerQuery && bLower !== lowerQuery) {
1042
- return -1;
1043
- }
1044
- if (bLower === lowerQuery && aLower !== lowerQuery) {
1045
- return 1;
1046
- }
1047
- const aPathLower = a.path.toLowerCase();
1048
- const bPathLower = b.path.toLowerCase();
1049
- if (aPathLower.startsWith(lowerQuery) && !bPathLower.startsWith(lowerQuery)) {
1050
- return -1;
1051
- }
1052
- if (bPathLower.startsWith(lowerQuery) && !aPathLower.startsWith(lowerQuery)) {
1053
- return 1;
1054
- }
1055
- return a.path.length - b.path.length;
1056
- }).slice(0, 20);
1304
+ isPending() {
1305
+ return this.pendingConfirmation !== null;
1306
+ }
1307
+ resetSession() {
1308
+ this.sessionFlags = {
1309
+ fileOperations: false,
1310
+ bashCommands: false,
1311
+ allOperations: false
1312
+ };
1313
+ }
1314
+ getSessionFlags() {
1315
+ return { ...this.sessionFlags };
1316
+ }
1317
+ setSessionFlag(flagType, value) {
1318
+ this.sessionFlags[flagType] = value;
1319
+ }
1057
1320
  }
1058
1321
 
1322
+ // src/index.ts
1323
+ init_settings_manager();
1324
+
1325
+ // src/hooks/use-input-handler.ts
1326
+ init_file_utils();
1327
+
1059
1328
  // src/utils/text-utils.ts
1060
1329
  function isWordBoundary(char) {
1061
1330
  if (!char) {
@@ -1499,9 +1768,9 @@ function CommandSuggestions({
1499
1768
 
1500
1769
  // src/utils/model-config.ts
1501
1770
  init_settings_manager();
1502
- function loadModelConfig() {
1771
+ function loadModelConfig(providerId) {
1503
1772
  const manager = getSettingsManager();
1504
- const models = manager.getAvailableModels();
1773
+ const models = manager.getAvailableModels(providerId);
1505
1774
  return models.map((model) => ({
1506
1775
  model: model.trim()
1507
1776
  }));
@@ -2473,7 +2742,7 @@ function getChatManager() {
2473
2742
  }
2474
2743
 
2475
2744
  // src/hooks/use-input-handler.ts
2476
- import * as fs6 from "fs-extra";
2745
+ import * as fs8 from "fs-extra";
2477
2746
  function useInputHandler({
2478
2747
  agent,
2479
2748
  chatHistory,
@@ -2615,6 +2884,7 @@ function useInputHandler({
2615
2884
  if (providers.length > 0) {
2616
2885
  const selectedProviderId = providers[selectedProviderIndex];
2617
2886
  manager.updateUserSetting("active_provider", selectedProviderId);
2887
+ setActiveProvider(selectedProviderId);
2618
2888
  setChatHistory((prev) => [
2619
2889
  ...prev,
2620
2890
  {
@@ -2631,6 +2901,24 @@ function useInputHandler({
2631
2901
  setShowProviderSelection(false);
2632
2902
  return true;
2633
2903
  }
2904
+ if (char === "e" || char === "E") {
2905
+ if (providers.length > 0) {
2906
+ const selectedProviderId = providers[selectedProviderIndex];
2907
+ const manager2 = getSettingsManager();
2908
+ const currentKey = manager2.getUserSetting("providers")?.[selectedProviderId]?.api_key || "";
2909
+ setChatHistory((prev) => [
2910
+ ...prev,
2911
+ {
2912
+ type: "assistant",
2913
+ content: `\uD83D\uDCDD Editing API key for ${selectedProviderId}. Press Enter after pasting key.`,
2914
+ timestamp: new Date
2915
+ }
2916
+ ]);
2917
+ setShowProviderSelection(false);
2918
+ setInput(`/provider set-key ${selectedProviderId} `);
2919
+ }
2920
+ return true;
2921
+ }
2634
2922
  return true;
2635
2923
  }
2636
2924
  if (showConfigViewer) {
@@ -2826,14 +3114,40 @@ function useInputHandler({
2826
3114
  description: "Manage plugins (list, install, remove)"
2827
3115
  },
2828
3116
  { command: "/commit-and-push", description: "AI commit & push to remote" },
3117
+ {
3118
+ command: "/import <type> <source>",
3119
+ description: "Import resources (agents, skills, hooks)"
3120
+ },
2829
3121
  { command: "/exit", description: "Exit the application" }
2830
3122
  ];
2831
3123
  const [activeProvider, setActiveProvider] = useState3(() => {
2832
3124
  return getSettingsManager().loadUserSettings().active_provider;
2833
3125
  });
3126
+ const [dynamicModels, setDynamicModels] = useState3([]);
3127
+ useEffect(() => {
3128
+ let mounted = true;
3129
+ const fetchModels = async () => {
3130
+ try {
3131
+ const models = await agent.listModels();
3132
+ if (mounted && models.length > 0) {
3133
+ setDynamicModels(models);
3134
+ }
3135
+ } catch (e) {}
3136
+ };
3137
+ fetchModels();
3138
+ return () => {
3139
+ mounted = false;
3140
+ };
3141
+ }, [activeProvider, agent]);
2834
3142
  const availableModels = useMemo2(() => {
2835
- return loadModelConfig();
2836
- }, [activeProvider]);
3143
+ const configModels = loadModelConfig(activeProvider);
3144
+ if (dynamicModels.length > 0) {
3145
+ const configModelNames = new Set(configModels.map((m) => m.model));
3146
+ const newModels = dynamicModels.filter((m) => !configModelNames.has(m)).map((m) => ({ model: m }));
3147
+ return [...configModels, ...newModels];
3148
+ }
3149
+ return configModels;
3150
+ }, [activeProvider, dynamicModels]);
2837
3151
  const handleDirectCommand = async (input2) => {
2838
3152
  const trimmedInput = input2.trim();
2839
3153
  if (trimmedInput === "/clear") {
@@ -2887,6 +3201,73 @@ Config Commands:
2887
3201
  if (trimmedInput === "/exit") {
2888
3202
  process.exit(0);
2889
3203
  }
3204
+ if (trimmedInput === "/doctor") {
3205
+ setIsProcessing(true);
3206
+ const manager = getSettingsManager();
3207
+ const settings = manager.loadUserSettings();
3208
+ const active = settings.active_provider;
3209
+ const config = settings.providers[active];
3210
+ let checks = `Super Agent Doctor \uD83E\uDE7A
3211
+
3212
+ `;
3213
+ checks += `✅ Active Provider: ${active}
3214
+ `;
3215
+ checks += config ? `✅ Configuration found
3216
+ ` : `❌ Configuration MISSING
3217
+ `;
3218
+ checks += config?.api_key ? `✅ API Key set
3219
+ ` : `❌ API Key MISSING
3220
+ `;
3221
+ if (active === "workers-ai") {
3222
+ checks += config?.account_id ? `✅ Account ID set
3223
+ ` : `❌ Account ID MISSING (use /provider set-account)
3224
+ `;
3225
+ }
3226
+ try {
3227
+ const checkAgent = agent;
3228
+ const models = await checkAgent.listModels();
3229
+ checks += `✅ Connection check: OK (${models.length} models found)
3230
+ `;
3231
+ } catch (e) {
3232
+ checks += `❌ Connection check: FAILED (${e.message})
3233
+ `;
3234
+ }
3235
+ setChatHistory((prev) => [
3236
+ ...prev,
3237
+ {
3238
+ type: "assistant",
3239
+ content: checks,
3240
+ timestamp: new Date
3241
+ }
3242
+ ]);
3243
+ setIsProcessing(false);
3244
+ clearInput();
3245
+ return true;
3246
+ }
3247
+ if (trimmedInput === "/commands") {
3248
+ setChatHistory((prev) => [
3249
+ ...prev,
3250
+ {
3251
+ type: "assistant",
3252
+ content: "Usage: /commands <add|remove|list> [name] [prompt]",
3253
+ timestamp: new Date
3254
+ }
3255
+ ]);
3256
+ clearInput();
3257
+ return true;
3258
+ }
3259
+ if (trimmedInput.startsWith("/commands ")) {
3260
+ setChatHistory((prev) => [
3261
+ ...prev,
3262
+ {
3263
+ type: "assistant",
3264
+ content: "\uD83D\uDEA7 Custom commands support implies storing them. Feature placeholder.",
3265
+ timestamp: new Date
3266
+ }
3267
+ ]);
3268
+ clearInput();
3269
+ return true;
3270
+ }
2890
3271
  if (trimmedInput === "/config") {
2891
3272
  setShowConfigViewer(true);
2892
3273
  clearInput();
@@ -2898,6 +3279,64 @@ Config Commands:
2898
3279
  clearInput();
2899
3280
  return true;
2900
3281
  }
3282
+ if (trimmedInput === "/provider config") {
3283
+ setChatHistory((prev) => [
3284
+ ...prev,
3285
+ {
3286
+ type: "assistant",
3287
+ content: "⚠️ Interactive configuration cannot be run inside the chat session.\n\nPlease run `super-agent provider config` in a separate terminal, or use:\n`/provider set-key <provider> <key>` to set an API key directly.",
3288
+ timestamp: new Date
3289
+ }
3290
+ ]);
3291
+ clearInput();
3292
+ return true;
3293
+ }
3294
+ if (trimmedInput.startsWith("/provider set-key ")) {
3295
+ const args = trimmedInput.replace("/provider set-key ", "").trim().split(" ");
3296
+ const providerId = args[0];
3297
+ const key = args.slice(1).join(" ");
3298
+ if (!providerId || !key) {
3299
+ setChatHistory((prev) => [
3300
+ ...prev,
3301
+ {
3302
+ type: "assistant",
3303
+ content: "❌ Usage: /provider set-key <provider> <api_key>",
3304
+ timestamp: new Date
3305
+ }
3306
+ ]);
3307
+ clearInput();
3308
+ return true;
3309
+ }
3310
+ const manager = getSettingsManager();
3311
+ const settings = manager.loadUserSettings();
3312
+ if (settings.providers && settings.providers[providerId]) {
3313
+ const newProviders = { ...settings.providers };
3314
+ newProviders[providerId] = {
3315
+ ...newProviders[providerId],
3316
+ api_key: key
3317
+ };
3318
+ manager.updateUserSetting("providers", newProviders);
3319
+ setChatHistory((prev) => [
3320
+ ...prev,
3321
+ {
3322
+ type: "assistant",
3323
+ content: `✅ API Key for ${providerId} updated.`,
3324
+ timestamp: new Date
3325
+ }
3326
+ ]);
3327
+ } else {
3328
+ setChatHistory((prev) => [
3329
+ ...prev,
3330
+ {
3331
+ type: "assistant",
3332
+ content: `❌ Provider '${providerId}' not found.`,
3333
+ timestamp: new Date
3334
+ }
3335
+ ]);
3336
+ }
3337
+ clearInput();
3338
+ return true;
3339
+ }
2901
3340
  if (trimmedInput.startsWith("/provider use ")) {
2902
3341
  const providerId = trimmedInput.replace("/provider use ", "").trim();
2903
3342
  const manager = getSettingsManager();
@@ -2938,6 +3377,57 @@ Config Commands:
2938
3377
  clearInput();
2939
3378
  return true;
2940
3379
  }
3380
+ if (trimmedInput.startsWith("/provider set-account ")) {
3381
+ const args = trimmedInput.replace("/provider set-account ", "").trim().split(" ");
3382
+ const providerId = args[0];
3383
+ const accountId = args[1];
3384
+ if (!providerId || !accountId) {
3385
+ setChatHistory((prev) => [
3386
+ ...prev,
3387
+ {
3388
+ type: "assistant",
3389
+ content: "❌ Usage: /provider set-account <provider> <account_id>",
3390
+ timestamp: new Date
3391
+ }
3392
+ ]);
3393
+ clearInput();
3394
+ return true;
3395
+ }
3396
+ const manager = getSettingsManager();
3397
+ const settings = manager.loadUserSettings();
3398
+ if (settings.providers && settings.providers[providerId]) {
3399
+ const newProviders = { ...settings.providers };
3400
+ newProviders[providerId] = {
3401
+ ...newProviders[providerId],
3402
+ account_id: accountId
3403
+ };
3404
+ manager.updateUserSetting("providers", newProviders);
3405
+ setChatHistory((prev) => [
3406
+ ...prev,
3407
+ {
3408
+ type: "assistant",
3409
+ content: `✅ Account ID for ${providerId} updated.`,
3410
+ timestamp: new Date
3411
+ }
3412
+ ]);
3413
+ if (providerId === activeProvider) {
3414
+ try {
3415
+ agent.setProvider(providerId);
3416
+ } catch (e) {}
3417
+ }
3418
+ } else {
3419
+ setChatHistory((prev) => [
3420
+ ...prev,
3421
+ {
3422
+ type: "assistant",
3423
+ content: `❌ Provider '${providerId}' not found.`,
3424
+ timestamp: new Date
3425
+ }
3426
+ ]);
3427
+ }
3428
+ clearInput();
3429
+ return true;
3430
+ }
2941
3431
  if (trimmedInput.startsWith("/model set ")) {
2942
3432
  const modelId = trimmedInput.replace("/model set ", "").trim();
2943
3433
  if (modelId) {
@@ -3071,6 +3561,149 @@ ${chats.length ? chats.map((c) => `- ${c}`).join(`
3071
3561
  clearInput();
3072
3562
  return true;
3073
3563
  }
3564
+ if (trimmedInput.startsWith("/import ")) {
3565
+ const args = trimmedInput.replace("/import ", "").split(" ");
3566
+ const type = args[0];
3567
+ const source = args[1];
3568
+ if (!type || !source) {
3569
+ setChatHistory((prev) => [
3570
+ ...prev,
3571
+ {
3572
+ type: "assistant",
3573
+ content: `❌ Usage: /import <type> <source>
3574
+ Types: agents, skills, hooks
3575
+ Sources: gemini, claude, kilo, or path`,
3576
+ timestamp: new Date
3577
+ }
3578
+ ]);
3579
+ clearInput();
3580
+ return true;
3581
+ }
3582
+ setIsProcessing(true);
3583
+ setChatHistory((prev) => [
3584
+ ...prev,
3585
+ {
3586
+ type: "assistant",
3587
+ content: `Importing ${type} from ${source}...`,
3588
+ timestamp: new Date
3589
+ }
3590
+ ]);
3591
+ try {
3592
+ const { resolveSourcePath: resolveSourcePath2 } = await Promise.resolve().then(() => (init_file_utils(), exports_file_utils));
3593
+ const { AgentsManager: AgentsManager2 } = await Promise.resolve().then(() => (init_manager(), exports_manager));
3594
+ const { SkillsManager: SkillsManager2 } = await Promise.resolve().then(() => (init_manager2(), exports_manager2));
3595
+ const { getSettingsManager: getSettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), exports_settings_manager));
3596
+ const fs9 = await import("fs-extra");
3597
+ const path8 = await import("path");
3598
+ const sourcePath = resolveSourcePath2(source);
3599
+ if (type === "agents") {
3600
+ const agentsDir = path8.join(sourcePath, "agents");
3601
+ if (!await fs9.pathExists(agentsDir)) {
3602
+ throw new Error(`Agents directory not found at ${agentsDir}`);
3603
+ }
3604
+ const files = await fs9.readdir(agentsDir);
3605
+ const manager = AgentsManager2.getInstance();
3606
+ let count = 0;
3607
+ for (const file of files) {
3608
+ if (file.endsWith(".json")) {
3609
+ try {
3610
+ const content = await fs9.readJson(path8.join(agentsDir, file));
3611
+ const agentConfig = {
3612
+ name: content.name || path8.parse(file).name,
3613
+ role: content.role || "Assistant",
3614
+ description: content.description || "Imported agent",
3615
+ model: content.model,
3616
+ tools: content.tools,
3617
+ temperature: content.temperature,
3618
+ systemPrompt: content.systemPrompt || content.system_prompt || content.prompt
3619
+ };
3620
+ await manager.createAgent(agentConfig);
3621
+ count++;
3622
+ } catch (e) {}
3623
+ }
3624
+ }
3625
+ setChatHistory((prev) => [
3626
+ ...prev,
3627
+ {
3628
+ type: "assistant",
3629
+ content: `✅ Imported ${count} agents.`,
3630
+ timestamp: new Date
3631
+ }
3632
+ ]);
3633
+ } else if (type === "skills") {
3634
+ const skillsDir = path8.join(sourcePath, "skills");
3635
+ if (!await fs9.pathExists(skillsDir)) {
3636
+ throw new Error(`Skills directory not found at ${skillsDir}`);
3637
+ }
3638
+ const files = await fs9.readdir(skillsDir);
3639
+ const manager = SkillsManager2.getInstance();
3640
+ let count = 0;
3641
+ for (const file of files) {
3642
+ if (file.endsWith(".ts") || file.endsWith(".js")) {
3643
+ try {
3644
+ const content = await fs9.readFile(path8.join(skillsDir, file), "utf-8");
3645
+ const name = path8.parse(file).name;
3646
+ await manager.saveSkill(name, content);
3647
+ count++;
3648
+ } catch (e) {}
3649
+ }
3650
+ }
3651
+ setChatHistory((prev) => [
3652
+ ...prev,
3653
+ {
3654
+ type: "assistant",
3655
+ content: `✅ Imported ${count} skills.`,
3656
+ timestamp: new Date
3657
+ }
3658
+ ]);
3659
+ } else if (type === "hooks") {
3660
+ const settingsFile = source.toLowerCase() === "claude" ? "settings.local.json" : "settings.json";
3661
+ const fullPath = path8.join(sourcePath, settingsFile);
3662
+ if (!await fs9.pathExists(fullPath)) {
3663
+ throw new Error(`Settings file not found at ${fullPath}`);
3664
+ }
3665
+ const settings = await fs9.readJson(fullPath);
3666
+ if (settings.hooks) {
3667
+ const manager = getSettingsManager2();
3668
+ const currentHooks = manager.getUserSetting("hooks") || {};
3669
+ const mergedHooks = { ...currentHooks, ...settings.hooks };
3670
+ manager.updateUserSetting("hooks", mergedHooks);
3671
+ setChatHistory((prev) => [
3672
+ ...prev,
3673
+ {
3674
+ type: "assistant",
3675
+ content: `✅ Imported ${Object.keys(settings.hooks).length} hooks.`,
3676
+ timestamp: new Date
3677
+ }
3678
+ ]);
3679
+ } else {
3680
+ setChatHistory((prev) => [
3681
+ ...prev,
3682
+ {
3683
+ type: "assistant",
3684
+ content: "⚠️ No hooks found in settings file.",
3685
+ timestamp: new Date
3686
+ }
3687
+ ]);
3688
+ }
3689
+ } else {
3690
+ throw new Error(`Unknown import type: ${type}`);
3691
+ }
3692
+ } catch (error) {
3693
+ setChatHistory((prev) => [
3694
+ ...prev,
3695
+ {
3696
+ type: "assistant",
3697
+ content: `❌ Import failed: ${error.message}`,
3698
+ timestamp: new Date
3699
+ }
3700
+ ]);
3701
+ } finally {
3702
+ setIsProcessing(false);
3703
+ }
3704
+ clearInput();
3705
+ return true;
3706
+ }
3074
3707
  if (trimmedInput.startsWith("/plugin ")) {
3075
3708
  const args = trimmedInput.replace("/plugin ", "").split(" ");
3076
3709
  const action = args[0];
@@ -3487,9 +4120,9 @@ ${commitMessage}`
3487
4120
  for (const mention of mentionMatches) {
3488
4121
  const filePath = mention.slice(1);
3489
4122
  try {
3490
- const stats = await fs6.stat(filePath);
4123
+ const stats = await fs8.stat(filePath);
3491
4124
  if (stats.isFile()) {
3492
- const content = await fs6.readFile(filePath, "utf-8");
4125
+ const content = await fs8.readFile(filePath, "utf-8");
3493
4126
  resolvedInput = resolvedInput.replace(mention, `
3494
4127
 
3495
4128
  --- FILE: ${filePath} ---
@@ -3640,6 +4273,7 @@ ${structure}
3640
4273
  }
3641
4274
 
3642
4275
  // src/ui/components/mention-suggestions.tsx
4276
+ init_file_utils();
3643
4277
  import { useMemo as useMemo3 } from "react";
3644
4278
  import { Box as Box2, Text as Text2 } from "ink";
3645
4279
  import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
@@ -4417,6 +5051,7 @@ function LoadingSpinner({
4417
5051
  }
4418
5052
 
4419
5053
  // src/ui/components/command-palette.tsx
5054
+ init_file_utils();
4420
5055
  import { useMemo as useMemo4 } from "react";
4421
5056
  import { Box as Box9, Text as Text8 } from "ink";
4422
5057
  import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
@@ -5055,8 +5690,8 @@ class ConfirmationTool {
5055
5690
  }
5056
5691
  }
5057
5692
  // src/tools/morph-editor.ts
5058
- import * as path6 from "path";
5059
- import fs7 from "fs-extra";
5693
+ import * as path8 from "path";
5694
+ import fs9 from "fs-extra";
5060
5695
  import axios2 from "axios";
5061
5696
 
5062
5697
  class MorphEditorTool {
@@ -5071,8 +5706,8 @@ class MorphEditorTool {
5071
5706
  }
5072
5707
  async editFile(targetFile, instructions, codeEdit) {
5073
5708
  try {
5074
- const resolvedPath = path6.resolve(targetFile);
5075
- if (!await fs7.pathExists(resolvedPath)) {
5709
+ const resolvedPath = path8.resolve(targetFile);
5710
+ if (!await fs9.pathExists(resolvedPath)) {
5076
5711
  return {
5077
5712
  success: false,
5078
5713
  error: `File not found: ${targetFile}`
@@ -5084,7 +5719,7 @@ class MorphEditorTool {
5084
5719
  error: "MORPH_API_KEY not configured. Please set your Morph API key."
5085
5720
  };
5086
5721
  }
5087
- const initialCode = await fs7.readFile(resolvedPath, "utf-8");
5722
+ const initialCode = await fs9.readFile(resolvedPath, "utf-8");
5088
5723
  const sessionFlags = this.confirmationService.getSessionFlags();
5089
5724
  if (!sessionFlags.fileOperations && !sessionFlags.allOperations) {
5090
5725
  const confirmationResult = await this.confirmationService.requestConfirmation({
@@ -5104,7 +5739,7 @@ ${codeEdit}`
5104
5739
  }
5105
5740
  }
5106
5741
  const mergedCode = await this.callMorphApply(instructions, initialCode, codeEdit);
5107
- await fs7.writeFile(resolvedPath, mergedCode, "utf-8");
5742
+ await fs9.writeFile(resolvedPath, mergedCode, "utf-8");
5108
5743
  const oldLines = initialCode.split(`
5109
5744
  `);
5110
5745
  const newLines = mergedCode.split(`
@@ -5287,11 +5922,11 @@ ${codeEdit}`
5287
5922
  }
5288
5923
  async view(filePath, viewRange) {
5289
5924
  try {
5290
- const resolvedPath = path6.resolve(filePath);
5291
- if (await fs7.pathExists(resolvedPath)) {
5292
- const stats = await fs7.stat(resolvedPath);
5925
+ const resolvedPath = path8.resolve(filePath);
5926
+ if (await fs9.pathExists(resolvedPath)) {
5927
+ const stats = await fs9.stat(resolvedPath);
5293
5928
  if (stats.isDirectory()) {
5294
- const files = await fs7.readdir(resolvedPath);
5929
+ const files = await fs9.readdir(resolvedPath);
5295
5930
  return {
5296
5931
  success: true,
5297
5932
  output: `Directory contents of ${filePath}:
@@ -5299,7 +5934,7 @@ ${files.join(`
5299
5934
  `)}`
5300
5935
  };
5301
5936
  }
5302
- const content = await fs7.readFile(resolvedPath, "utf-8");
5937
+ const content = await fs9.readFile(resolvedPath, "utf-8");
5303
5938
  const lines = content.split(`
5304
5939
  `);
5305
5940
  if (viewRange) {
@@ -5345,8 +5980,8 @@ ${numberedLines}${additionalLinesMessage}`
5345
5980
  }
5346
5981
  }
5347
5982
  // src/tools/project-map.ts
5348
- import * as path7 from "path";
5349
- import fs8 from "fs-extra";
5983
+ import * as path9 from "path";
5984
+ import fs10 from "fs-extra";
5350
5985
 
5351
5986
  class ProjectMapTool {
5352
5987
  currentDirectory = process.cwd();
@@ -5380,7 +6015,7 @@ Important Files:
5380
6015
  }
5381
6016
  let result = "";
5382
6017
  try {
5383
- const entries = await fs8.readdir(dir, { withFileTypes: true });
6018
+ const entries = await fs10.readdir(dir, { withFileTypes: true });
5384
6019
  const sortedEntries = entries.sort((a, b) => {
5385
6020
  if (a.isDirectory() && !b.isDirectory()) {
5386
6021
  return -1;
@@ -5408,7 +6043,7 @@ Important Files:
5408
6043
  if (entry.isDirectory()) {
5409
6044
  result += `${indent}\uD83D\uDCC1 ${entry.name}/
5410
6045
  `;
5411
- result += await this.generateTree(path7.join(dir, entry.name), maxDepth, currentDepth + 1);
6046
+ result += await this.generateTree(path9.join(dir, entry.name), maxDepth, currentDepth + 1);
5412
6047
  } else {
5413
6048
  result += `${indent}\uD83D\uDCC4 ${entry.name}
5414
6049
  `;
@@ -5430,8 +6065,8 @@ Important Files:
5430
6065
  ];
5431
6066
  const found = [];
5432
6067
  for (const pattern of importantPatterns) {
5433
- const fullPath = path7.join(this.currentDirectory, pattern);
5434
- if (await fs8.pathExists(fullPath)) {
6068
+ const fullPath = path9.join(this.currentDirectory, pattern);
6069
+ if (await fs10.pathExists(fullPath)) {
5435
6070
  found.push(pattern);
5436
6071
  }
5437
6072
  }
@@ -5444,8 +6079,8 @@ Important Files:
5444
6079
  // src/tools/search.ts
5445
6080
  init_indexer();
5446
6081
  import { spawn } from "child_process";
5447
- import * as path9 from "path";
5448
- import fs10 from "fs-extra";
6082
+ import * as path11 from "path";
6083
+ import fs12 from "fs-extra";
5449
6084
 
5450
6085
  class SearchTool {
5451
6086
  confirmationService = ConfirmationService.getInstance();
@@ -5474,7 +6109,7 @@ class SearchTool {
5474
6109
  const searchPattern = query.toLowerCase();
5475
6110
  fileResults = entries.filter((e) => e.path.toLowerCase().includes(searchPattern)).map((e) => ({
5476
6111
  path: e.path,
5477
- name: path9.basename(e.path),
6112
+ name: path11.basename(e.path),
5478
6113
  score: 10
5479
6114
  }));
5480
6115
  } else {
@@ -5598,13 +6233,13 @@ class SearchTool {
5598
6233
  return;
5599
6234
  }
5600
6235
  try {
5601
- const entries = await fs10.readdir(dir, { withFileTypes: true });
6236
+ const entries = await fs12.readdir(dir, { withFileTypes: true });
5602
6237
  for (const entry of entries) {
5603
6238
  if (files.length >= maxResults) {
5604
6239
  break;
5605
6240
  }
5606
- const fullPath = path9.join(dir, entry.name);
5607
- const relativePath = path9.relative(this.currentDirectory, fullPath);
6241
+ const fullPath = path11.join(dir, entry.name);
6242
+ const relativePath = path11.relative(this.currentDirectory, fullPath);
5608
6243
  if (!options.includeHidden && entry.name.startsWith(".")) {
5609
6244
  continue;
5610
6245
  }
@@ -5703,19 +6338,19 @@ class SearchTool {
5703
6338
  }
5704
6339
  // src/tools/text-editor.ts
5705
6340
  import { writeFile as writeFilePromise } from "fs/promises";
5706
- import * as path10 from "path";
5707
- import fs11 from "fs-extra";
6341
+ import * as path12 from "path";
6342
+ import fs13 from "fs-extra";
5708
6343
 
5709
6344
  class TextEditorTool {
5710
6345
  editHistory = [];
5711
6346
  confirmationService = ConfirmationService.getInstance();
5712
6347
  async view(filePath, viewRange) {
5713
6348
  try {
5714
- const resolvedPath = path10.resolve(filePath);
5715
- if (await fs11.pathExists(resolvedPath)) {
5716
- const stats = await fs11.stat(resolvedPath);
6349
+ const resolvedPath = path12.resolve(filePath);
6350
+ if (await fs13.pathExists(resolvedPath)) {
6351
+ const stats = await fs13.stat(resolvedPath);
5717
6352
  if (stats.isDirectory()) {
5718
- const files = await fs11.readdir(resolvedPath);
6353
+ const files = await fs13.readdir(resolvedPath);
5719
6354
  return {
5720
6355
  success: true,
5721
6356
  output: `Directory contents of ${filePath}:
@@ -5723,7 +6358,7 @@ ${files.join(`
5723
6358
  `)}`
5724
6359
  };
5725
6360
  }
5726
- const content = await fs11.readFile(resolvedPath, "utf-8");
6361
+ const content = await fs13.readFile(resolvedPath, "utf-8");
5727
6362
  const lines = content.split(`
5728
6363
  `);
5729
6364
  if (viewRange) {
@@ -5763,14 +6398,14 @@ ${numberedLines}${additionalLinesMessage}`
5763
6398
  }
5764
6399
  async strReplace(filePath, oldStr, newStr, replaceAll = false) {
5765
6400
  try {
5766
- const resolvedPath = path10.resolve(filePath);
5767
- if (!await fs11.pathExists(resolvedPath)) {
6401
+ const resolvedPath = path12.resolve(filePath);
6402
+ if (!await fs13.pathExists(resolvedPath)) {
5768
6403
  return {
5769
6404
  success: false,
5770
6405
  error: `File not found: ${filePath}`
5771
6406
  };
5772
6407
  }
5773
- const content = await fs11.readFile(resolvedPath, "utf-8");
6408
+ const content = await fs13.readFile(resolvedPath, "utf-8");
5774
6409
  if (!content.includes(oldStr)) {
5775
6410
  if (oldStr.includes(`
5776
6411
  `)) {
@@ -5838,7 +6473,7 @@ ${numberedLines}${additionalLinesMessage}`
5838
6473
  }
5839
6474
  async create(filePath, content) {
5840
6475
  try {
5841
- const resolvedPath = path10.resolve(filePath);
6476
+ const resolvedPath = path12.resolve(filePath);
5842
6477
  const sessionFlags = this.confirmationService.getSessionFlags();
5843
6478
  if (!sessionFlags.fileOperations && !sessionFlags.allOperations) {
5844
6479
  const contentLines = content.split(`
@@ -5864,8 +6499,8 @@ ${numberedLines}${additionalLinesMessage}`
5864
6499
  };
5865
6500
  }
5866
6501
  }
5867
- const dir = path10.dirname(resolvedPath);
5868
- await fs11.ensureDir(dir);
6502
+ const dir = path12.dirname(resolvedPath);
6503
+ await fs13.ensureDir(dir);
5869
6504
  await writeFilePromise(resolvedPath, content, "utf-8");
5870
6505
  this.editHistory.push({
5871
6506
  command: "create",
@@ -5889,14 +6524,14 @@ ${numberedLines}${additionalLinesMessage}`
5889
6524
  }
5890
6525
  async replaceLines(filePath, startLine, endLine, newContent) {
5891
6526
  try {
5892
- const resolvedPath = path10.resolve(filePath);
5893
- if (!await fs11.pathExists(resolvedPath)) {
6527
+ const resolvedPath = path12.resolve(filePath);
6528
+ if (!await fs13.pathExists(resolvedPath)) {
5894
6529
  return {
5895
6530
  success: false,
5896
6531
  error: `File not found: ${filePath}`
5897
6532
  };
5898
6533
  }
5899
- const fileContent = await fs11.readFile(resolvedPath, "utf-8");
6534
+ const fileContent = await fs13.readFile(resolvedPath, "utf-8");
5900
6535
  const lines = fileContent.split(`
5901
6536
  `);
5902
6537
  if (startLine < 1 || startLine > lines.length) {
@@ -5959,14 +6594,14 @@ ${numberedLines}${additionalLinesMessage}`
5959
6594
  }
5960
6595
  async insert(filePath, insertLine, content) {
5961
6596
  try {
5962
- const resolvedPath = path10.resolve(filePath);
5963
- if (!await fs11.pathExists(resolvedPath)) {
6597
+ const resolvedPath = path12.resolve(filePath);
6598
+ if (!await fs13.pathExists(resolvedPath)) {
5964
6599
  return {
5965
6600
  success: false,
5966
6601
  error: `File not found: ${filePath}`
5967
6602
  };
5968
6603
  }
5969
- const fileContent = await fs11.readFile(resolvedPath, "utf-8");
6604
+ const fileContent = await fs13.readFile(resolvedPath, "utf-8");
5970
6605
  const lines = fileContent.split(`
5971
6606
  `);
5972
6607
  lines.splice(insertLine - 1, 0, content);
@@ -6002,19 +6637,19 @@ ${numberedLines}${additionalLinesMessage}`
6002
6637
  switch (lastEdit.command) {
6003
6638
  case "str_replace":
6004
6639
  if (lastEdit.path && lastEdit.old_str && lastEdit.new_str) {
6005
- const content = await fs11.readFile(lastEdit.path, "utf-8");
6640
+ const content = await fs13.readFile(lastEdit.path, "utf-8");
6006
6641
  const revertedContent = content.replace(lastEdit.new_str, lastEdit.old_str);
6007
6642
  await writeFilePromise(lastEdit.path, revertedContent, "utf-8");
6008
6643
  }
6009
6644
  break;
6010
6645
  case "create":
6011
6646
  if (lastEdit.path) {
6012
- await fs11.remove(lastEdit.path);
6647
+ await fs13.remove(lastEdit.path);
6013
6648
  }
6014
6649
  break;
6015
6650
  case "insert":
6016
6651
  if (lastEdit.path && lastEdit.insert_line) {
6017
- const content = await fs11.readFile(lastEdit.path, "utf-8");
6652
+ const content = await fs13.readFile(lastEdit.path, "utf-8");
6018
6653
  const lines = content.split(`
6019
6654
  `);
6020
6655
  lines.splice(lastEdit.insert_line - 1, 1);
@@ -6456,22 +7091,30 @@ class OpenAICompatibleProvider {
6456
7091
  throw new Error(`${this.name} API error: ${error.message}`);
6457
7092
  }
6458
7093
  }
7094
+ async listModels() {
7095
+ try {
7096
+ const response = await this.client.models.list();
7097
+ return response.data.map((m) => m.id);
7098
+ } catch (error) {
7099
+ return [];
7100
+ }
7101
+ }
6459
7102
  }
6460
7103
 
6461
7104
  // src/utils/custom-instructions.ts
6462
- import * as path11 from "path";
6463
- import * as os2 from "os";
6464
- import * as fs12 from "fs";
7105
+ import * as path13 from "path";
7106
+ import * as os3 from "os";
7107
+ import * as fs14 from "fs";
6465
7108
  function loadCustomInstructions(workingDirectory = process.cwd()) {
6466
7109
  try {
6467
- let instructionsPath = path11.join(workingDirectory, ".super-agent", "SUPER_AGENT.md");
6468
- if (fs12.existsSync(instructionsPath)) {
6469
- const customInstructions = fs12.readFileSync(instructionsPath, "utf-8");
7110
+ let instructionsPath = path13.join(workingDirectory, ".super-agent", "SUPER_AGENT.md");
7111
+ if (fs14.existsSync(instructionsPath)) {
7112
+ const customInstructions = fs14.readFileSync(instructionsPath, "utf-8");
6470
7113
  return customInstructions.trim();
6471
7114
  }
6472
- instructionsPath = path11.join(os2.homedir(), ".super-agent", "SUPER_AGENT.md");
6473
- if (fs12.existsSync(instructionsPath)) {
6474
- const customInstructions = fs12.readFileSync(instructionsPath, "utf-8");
7115
+ instructionsPath = path13.join(os3.homedir(), ".super-agent", "SUPER_AGENT.md");
7116
+ if (fs14.existsSync(instructionsPath)) {
7117
+ const customInstructions = fs14.readFileSync(instructionsPath, "utf-8");
6475
7118
  return customInstructions.trim();
6476
7119
  }
6477
7120
  return null;
@@ -6547,6 +7190,14 @@ class OpenAIProvider {
6547
7190
  throw new Error(`OpenAI API error: ${error.message}`);
6548
7191
  }
6549
7192
  }
7193
+ async listModels() {
7194
+ try {
7195
+ const response = await this.client.models.list();
7196
+ return response.data.map((m) => m.id);
7197
+ } catch (error) {
7198
+ return [];
7199
+ }
7200
+ }
6550
7201
  }
6551
7202
 
6552
7203
  // src/core/providers/gemini.ts
@@ -6710,6 +7361,9 @@ class GeminiProvider {
6710
7361
  throw new Error(`Gemini API error: ${error.message}`);
6711
7362
  }
6712
7363
  }
7364
+ async listModels() {
7365
+ return [];
7366
+ }
6713
7367
  }
6714
7368
 
6715
7369
  // src/core/providers/grok.ts
@@ -6778,7 +7432,15 @@ class GrokProvider {
6778
7432
  yield chunk;
6779
7433
  }
6780
7434
  } catch (error) {
6781
- throw new Error(`Grok API error: ${error.message}`);
7435
+ throw new Error(`Grok API error: ${error.message}`);
7436
+ }
7437
+ }
7438
+ async listModels() {
7439
+ try {
7440
+ const response = await this.client.models.list();
7441
+ return response.data.map((m) => m.id);
7442
+ } catch (error) {
7443
+ return [];
6782
7444
  }
6783
7445
  }
6784
7446
  }
@@ -6814,7 +7476,12 @@ class SuperAgent extends EventEmitter4 {
6814
7476
  const providerConfig = settings.providers[activeProviderId];
6815
7477
  const providerType = providerConfig?.provider || activeProviderId;
6816
7478
  const effectiveApiKey = apiKey || providerConfig?.api_key || "";
6817
- const effectiveBaseURL = baseURL || (providerConfig?.base_url ? providerConfig.base_url : undefined);
7479
+ let effectiveBaseURL = baseURL || (providerConfig?.base_url ? providerConfig.base_url : undefined);
7480
+ if (providerConfig?.provider === "workers-ai" && effectiveBaseURL?.includes("{ACCOUNT_ID}")) {
7481
+ if (providerConfig.account_id) {
7482
+ effectiveBaseURL = effectiveBaseURL.replace("{ACCOUNT_ID}", providerConfig.account_id);
7483
+ }
7484
+ }
6818
7485
  const effectiveModel = model || providerConfig?.model || providerConfig?.default_model || "grok-code-fast-1";
6819
7486
  this.maxToolRounds = maxToolRounds || 400;
6820
7487
  if (providerType === "openai") {
@@ -6919,7 +7586,12 @@ Current working directory: ${process.cwd()}`
6919
7586
  }
6920
7587
  const providerType = providerConfig.provider || activeProviderId;
6921
7588
  const effectiveApiKey = providerConfig.api_key || "";
6922
- const effectiveBaseURL = providerConfig.base_url || undefined;
7589
+ let effectiveBaseURL = providerConfig.base_url || undefined;
7590
+ if (providerConfig.provider === "workers-ai" && effectiveBaseURL?.includes("{ACCOUNT_ID}")) {
7591
+ if (providerConfig.account_id) {
7592
+ effectiveBaseURL = effectiveBaseURL.replace("{ACCOUNT_ID}", providerConfig.account_id);
7593
+ }
7594
+ }
6923
7595
  const effectiveModel = providerConfig.model || providerConfig.default_model || "grok-code-fast-1";
6924
7596
  if (providerType === "openai") {
6925
7597
  this.superAgentClient = new OpenAIProvider(effectiveApiKey, effectiveBaseURL, effectiveModel);
@@ -6932,6 +7604,12 @@ Current working directory: ${process.cwd()}`
6932
7604
  }
6933
7605
  this.tokenCounter = createTokenCounter(effectiveModel);
6934
7606
  }
7607
+ async listModels() {
7608
+ if (this.superAgentClient.listModels) {
7609
+ return this.superAgentClient.listModels();
7610
+ }
7611
+ return [];
7612
+ }
6935
7613
  async initializeMCP() {
6936
7614
  Promise.resolve().then(async () => {
6937
7615
  try {
@@ -8180,8 +8858,8 @@ init_settings_manager();
8180
8858
  // src/web/server.ts
8181
8859
  import { createServer } from "http";
8182
8860
  import { WebSocketServer } from "ws";
8183
- import * as fs15 from "fs-extra";
8184
- import * as path14 from "path";
8861
+ import * as fs17 from "fs-extra";
8862
+ import * as path16 from "path";
8185
8863
  import open from "open";
8186
8864
  import mime from "mime";
8187
8865
  var __dirname = "/home/runner/work/super-agent-cli/super-agent-cli/src/web";
@@ -8209,21 +8887,21 @@ class WebServer {
8209
8887
  const url = req.url || "/";
8210
8888
  const requestedPath = url === "/" ? "index.html" : url;
8211
8889
  const sanitizedPath = requestedPath.split("?")[0].split("#")[0];
8212
- const clientDir = path14.join(__dirname, "../web/client");
8213
- const absolutePath = path14.resolve(clientDir, sanitizedPath.substring(1));
8890
+ const clientDir = path16.join(__dirname, "../web/client");
8891
+ const absolutePath = path16.resolve(clientDir, sanitizedPath.substring(1));
8214
8892
  if (!absolutePath.startsWith(clientDir)) {
8215
8893
  res.writeHead(403, { "Content-Type": "text/plain" });
8216
8894
  res.end("Forbidden");
8217
8895
  return;
8218
8896
  }
8219
8897
  try {
8220
- if (await fs15.pathExists(absolutePath)) {
8221
- const stat5 = await fs15.stat(absolutePath);
8898
+ if (await fs17.pathExists(absolutePath)) {
8899
+ const stat5 = await fs17.stat(absolutePath);
8222
8900
  let filePath = absolutePath;
8223
8901
  if (stat5.isDirectory()) {
8224
- filePath = path14.join(absolutePath, "index.html");
8902
+ filePath = path16.join(absolutePath, "index.html");
8225
8903
  }
8226
- const content = await fs15.readFile(filePath);
8904
+ const content = await fs17.readFile(filePath);
8227
8905
  const mimeType = mime.getType(filePath) || "application/octet-stream";
8228
8906
  res.writeHead(200, { "Content-Type": mimeType });
8229
8907
  res.end(content);
@@ -8311,7 +8989,7 @@ class WebServer {
8311
8989
  }
8312
8990
  const tree = index.entries.filter((e) => !e.path.includes("node_modules") && !e.path.startsWith(".")).map((e) => ({
8313
8991
  path: e.path,
8314
- name: path14.basename(e.path),
8992
+ name: path16.basename(e.path),
8315
8993
  isDirectory: e.isDirectory,
8316
8994
  size: e.size
8317
8995
  })).slice(0, 500);
@@ -8322,11 +9000,11 @@ class WebServer {
8322
9000
  }
8323
9001
  async handleGetFileContent(filePath, ws) {
8324
9002
  try {
8325
- const fullPath = path14.join(process.cwd(), filePath);
9003
+ const fullPath = path16.join(process.cwd(), filePath);
8326
9004
  if (!fullPath.startsWith(process.cwd())) {
8327
9005
  throw new Error("Access denied");
8328
9006
  }
8329
- const content = await fs15.readFile(fullPath, "utf-8");
9007
+ const content = await fs17.readFile(fullPath, "utf-8");
8330
9008
  ws.send(JSON.stringify({
8331
9009
  type: "file_content",
8332
9010
  path: filePath,
@@ -8480,12 +9158,133 @@ function createServeCommand() {
8480
9158
  return serveCommand;
8481
9159
  }
8482
9160
 
8483
- // src/commands/index-cmd.ts
9161
+ // src/commands/provider.ts
9162
+ init_settings_manager();
8484
9163
  import { Command as Command2 } from "commander";
8485
- import fs16 from "fs/promises";
8486
- import ignore from "ignore";
9164
+ import inquirer from "inquirer";
8487
9165
  import chalk2 from "chalk";
8488
- import path15 from "path";
9166
+ function createProviderCommand() {
9167
+ const cmd = new Command2("provider").description("Manage LLM provider configuration");
9168
+ cmd.command("config").description("Interactive provider configuration").action(async () => {
9169
+ const manager = getSettingsManager();
9170
+ const settings = manager.loadUserSettings();
9171
+ const providers = Object.keys(settings.providers);
9172
+ const { selectedProvider } = await inquirer.prompt([
9173
+ {
9174
+ type: "list",
9175
+ name: "selectedProvider",
9176
+ message: "Select a provider to configure:",
9177
+ choices: providers,
9178
+ default: settings.active_provider
9179
+ }
9180
+ ]);
9181
+ const currentConfig = settings.providers[selectedProvider];
9182
+ if (!currentConfig) {
9183
+ console.error(chalk2.red(`Configuration for ${selectedProvider} not found.`));
9184
+ return;
9185
+ }
9186
+ const models = PROVIDER_MODELS[currentConfig.provider] || [];
9187
+ const { apiKey } = await inquirer.prompt([
9188
+ {
9189
+ type: "password",
9190
+ name: "apiKey",
9191
+ message: `Enter API Key for ${selectedProvider} (leave empty to keep current):`,
9192
+ mask: "*"
9193
+ }
9194
+ ]);
9195
+ let selectedModel = currentConfig.model;
9196
+ if (models.length > 0) {
9197
+ const { model } = await inquirer.prompt([
9198
+ {
9199
+ type: "list",
9200
+ name: "model",
9201
+ message: "Select default model:",
9202
+ choices: [...models, "Custom..."],
9203
+ default: currentConfig.model
9204
+ }
9205
+ ]);
9206
+ selectedModel = model;
9207
+ }
9208
+ if (selectedModel === "Custom..." || models.length === 0) {
9209
+ const { customModel } = await inquirer.prompt([
9210
+ {
9211
+ type: "input",
9212
+ name: "customModel",
9213
+ message: "Enter model ID:",
9214
+ default: currentConfig.model
9215
+ }
9216
+ ]);
9217
+ selectedModel = customModel;
9218
+ }
9219
+ const { baseURL } = await inquirer.prompt([
9220
+ {
9221
+ type: "input",
9222
+ name: "baseURL",
9223
+ message: "Enter Base URL (optional, leave empty for default):",
9224
+ default: currentConfig.base_url
9225
+ }
9226
+ ]);
9227
+ console.log(chalk2.blue(`
9228
+ New Configuration:`));
9229
+ console.log(`Provider: ${chalk2.bold(selectedProvider)}`);
9230
+ console.log(`Model: ${chalk2.bold(selectedModel)}`);
9231
+ console.log(`Base URL: ${baseURL || "Default"}`);
9232
+ const { confirm } = await inquirer.prompt([
9233
+ {
9234
+ type: "confirm",
9235
+ name: "confirm",
9236
+ message: "Save these settings?",
9237
+ default: true
9238
+ }
9239
+ ]);
9240
+ if (confirm) {
9241
+ const newProviders = { ...settings.providers };
9242
+ newProviders[selectedProvider] = {
9243
+ ...currentConfig,
9244
+ model: selectedModel,
9245
+ base_url: baseURL || currentConfig.base_url
9246
+ };
9247
+ if (apiKey) {
9248
+ newProviders[selectedProvider].api_key = apiKey;
9249
+ }
9250
+ if (baseURL !== undefined && baseURL !== currentConfig.base_url) {
9251
+ newProviders[selectedProvider].base_url = baseURL;
9252
+ }
9253
+ manager.updateUserSetting("providers", newProviders);
9254
+ if (settings.active_provider !== selectedProvider) {
9255
+ const { makeActive } = await inquirer.prompt([
9256
+ {
9257
+ type: "confirm",
9258
+ name: "makeActive",
9259
+ message: `Set ${selectedProvider} as active provider?`,
9260
+ default: true
9261
+ }
9262
+ ]);
9263
+ if (makeActive) {
9264
+ manager.updateUserSetting("active_provider", selectedProvider);
9265
+ console.log(chalk2.green(`
9266
+ ✅ Settings saved and ${selectedProvider} is now active.`));
9267
+ } else {
9268
+ console.log(chalk2.green(`
9269
+ ✅ Settings saved.`));
9270
+ }
9271
+ } else {
9272
+ console.log(chalk2.green(`
9273
+ ✅ Settings saved.`));
9274
+ }
9275
+ } else {
9276
+ console.log(chalk2.yellow("Configuration cancelled."));
9277
+ }
9278
+ });
9279
+ return cmd;
9280
+ }
9281
+
9282
+ // src/commands/index-cmd.ts
9283
+ import { Command as Command3 } from "commander";
9284
+ import fs18 from "fs/promises";
9285
+ import ignore from "ignore";
9286
+ import chalk3 from "chalk";
9287
+ import path17 from "path";
8489
9288
  var DEFAULT_IGNORES = [
8490
9289
  "node_modules",
8491
9290
  ".git",
@@ -8498,17 +9297,17 @@ var DEFAULT_IGNORES = [
8498
9297
  "Thumbs.db"
8499
9298
  ];
8500
9299
  function createIndexCommand() {
8501
- const indexCommand = new Command2("index").description(" recursively index a directory and save to a file").argument("[directory]", "Directory to index", ".").option("-o, --output <file>", "Output file path (default: index.md)").option("--no-ignore", "Disable .gitignore respecting").option("-d, --depth <depth>", "Max depth to traverse", "10").action(async (directory, options) => {
9300
+ const indexCommand = new Command3("index").description(" recursively index a directory and save to a file").argument("[directory]", "Directory to index", ".").option("-o, --output <file>", "Output file path (default: index.md)").option("--no-ignore", "Disable .gitignore respecting").option("-d, --depth <depth>", "Max depth to traverse", "10").action(async (directory, options) => {
8502
9301
  try {
8503
- const rootDir = path15.resolve(directory);
8504
- const outputFile2 = options.output ? path15.resolve(options.output) : path15.join(rootDir, "index.md");
9302
+ const rootDir = path17.resolve(directory);
9303
+ const outputFile2 = options.output ? path17.resolve(options.output) : path17.join(rootDir, "index.md");
8505
9304
  const maxDepth = parseInt(options.depth);
8506
- console.log(chalk2.blue(`Indexing directory: ${rootDir}`));
9305
+ console.log(chalk3.blue(`Indexing directory: ${rootDir}`));
8507
9306
  const ig = ignore().add(DEFAULT_IGNORES);
8508
9307
  if (options.ignore !== false) {
8509
9308
  try {
8510
- const gitignorePath = path15.join(rootDir, ".gitignore");
8511
- const gitignoreContent = await fs16.readFile(gitignorePath, "utf-8");
9309
+ const gitignorePath = path17.join(rootDir, ".gitignore");
9310
+ const gitignoreContent = await fs18.readFile(gitignorePath, "utf-8");
8512
9311
  ig.add(gitignoreContent);
8513
9312
  } catch (e) {}
8514
9313
  }
@@ -8523,19 +9322,19 @@ Date: ${new Date().toISOString()}
8523
9322
  if (depth > maxDepth) {
8524
9323
  return;
8525
9324
  }
8526
- const relativePath = path15.relative(rootDir, currentPath);
9325
+ const relativePath = path17.relative(rootDir, currentPath);
8527
9326
  if (relativePath && ig.ignores(relativePath)) {
8528
9327
  return;
8529
9328
  }
8530
- const stats = await fs16.stat(currentPath);
9329
+ const stats = await fs18.stat(currentPath);
8531
9330
  const isDir = stats.isDirectory();
8532
- const name = path15.basename(currentPath);
9331
+ const name = path17.basename(currentPath);
8533
9332
  if (isDir) {
8534
9333
  if (relativePath) {
8535
9334
  outputContent += `${prefix}${name}/
8536
9335
  `;
8537
9336
  }
8538
- const entries = await fs16.readdir(currentPath, {
9337
+ const entries = await fs18.readdir(currentPath, {
8539
9338
  withFileTypes: true
8540
9339
  });
8541
9340
  const sortedEntries = entries.sort((a, b) => {
@@ -8551,7 +9350,7 @@ Date: ${new Date().toISOString()}
8551
9350
  const entry = sortedEntries[i];
8552
9351
  const isLast = i === sortedEntries.length - 1;
8553
9352
  const newPrefix = relativePath ? prefix + " " : "";
8554
- await buildTree(path15.join(currentPath, entry.name), depth + 1, newPrefix);
9353
+ await buildTree(path17.join(currentPath, entry.name), depth + 1, newPrefix);
8555
9354
  }
8556
9355
  } else {
8557
9356
  outputContent += `${prefix}${name}
@@ -8563,10 +9362,10 @@ Date: ${new Date().toISOString()}
8563
9362
  if (currentDepth > maxDepth) {
8564
9363
  return;
8565
9364
  }
8566
- const entries = await fs16.readdir(dir, { withFileTypes: true });
9365
+ const entries = await fs18.readdir(dir, { withFileTypes: true });
8567
9366
  for (const entry of entries) {
8568
- const fullPath = path15.join(dir, entry.name);
8569
- const relPath = path15.relative(rootDir, fullPath);
9367
+ const fullPath = path17.join(dir, entry.name);
9368
+ const relPath = path17.relative(rootDir, fullPath);
8570
9369
  if (ig.ignores(relPath)) {
8571
9370
  continue;
8572
9371
  }
@@ -8578,8 +9377,8 @@ Date: ${new Date().toISOString()}
8578
9377
  }
8579
9378
  }
8580
9379
  await walk(rootDir, 0);
8581
- console.log(chalk2.blue(`Found ${files.length} files.`));
8582
- outputContent = `# Project Index: ${path15.basename(rootDir)}
9380
+ console.log(chalk3.blue(`Found ${files.length} files.`));
9381
+ outputContent = `# Project Index: ${path17.basename(rootDir)}
8583
9382
 
8584
9383
  `;
8585
9384
  outputContent += `Total Files: ${files.length}
@@ -8591,17 +9390,17 @@ Date: ${new Date().toISOString()}
8591
9390
  for (const file of files) {
8592
9391
  outputContent += `### ${file}
8593
9392
  `;
8594
- const stats = await fs16.stat(path15.join(rootDir, file));
9393
+ const stats = await fs18.stat(path17.join(rootDir, file));
8595
9394
  outputContent += `- Size: ${stats.size} bytes
8596
9395
  `;
8597
9396
  outputContent += `- Modified: ${stats.mtime.toISOString()}
8598
9397
 
8599
9398
  `;
8600
9399
  }
8601
- await fs16.writeFile(outputFile2, outputContent);
8602
- console.log(chalk2.green(`✓ Index generated at: ${outputFile2}`));
9400
+ await fs18.writeFile(outputFile2, outputContent);
9401
+ console.log(chalk3.green(`✓ Index generated at: ${outputFile2}`));
8603
9402
  } catch (error) {
8604
- console.error(chalk2.red(`Error indexing directory: ${error.message}`));
9403
+ console.error(chalk3.red(`Error indexing directory: ${error.message}`));
8605
9404
  process.exit(1);
8606
9405
  }
8607
9406
  });
@@ -8610,9 +9409,9 @@ Date: ${new Date().toISOString()}
8610
9409
 
8611
9410
  // src/commands/plugins.ts
8612
9411
  init_settings_manager();
8613
- import { Command as Command3 } from "commander";
9412
+ import { Command as Command4 } from "commander";
8614
9413
  function createPluginsCommand() {
8615
- const pluginsCommand = new Command3("plugins").description("Manage plugins for Super Agent CLI").argument("[action]", "Action to perform (list, install, uninstall)").argument("[target]", "Plugin name or path");
9414
+ const pluginsCommand = new Command4("plugins").description("Manage plugins for Super Agent CLI").argument("[action]", "Action to perform (list, install, uninstall)").argument("[target]", "Plugin name or path");
8616
9415
  pluginsCommand.command("list").description("List installed plugins").action(() => {
8617
9416
  const manager = getSettingsManager();
8618
9417
  const settings = manager.loadUserSettings();
@@ -8624,22 +9423,22 @@ function createPluginsCommand() {
8624
9423
  console.log("Installed plugins:");
8625
9424
  plugins.forEach((p) => console.log(`- ${p}`));
8626
9425
  });
8627
- pluginsCommand.command("install <path>").description("Install a plugin from a path, GitHub URL, or registry").action(async (path16) => {
9426
+ pluginsCommand.command("install <path>").description("Install a plugin from a path, GitHub URL, or registry").action(async (path18) => {
8628
9427
  try {
8629
9428
  const manager = PluginManager.getInstance();
8630
- console.log(`Installing plugin from: ${path16}...`);
8631
- const installedPath = await manager.installPlugin(path16);
9429
+ console.log(`Installing plugin from: ${path18}...`);
9430
+ const installedPath = await manager.installPlugin(path18);
8632
9431
  console.log(`✅ Plugin installed successfully: ${installedPath}`);
8633
9432
  } catch (error) {
8634
9433
  console.error(`❌ Error installing plugin: ${error.message}`);
8635
9434
  process.exit(1);
8636
9435
  }
8637
9436
  });
8638
- pluginsCommand.command("uninstall <path>").description("Uninstall a plugin").action(async (path16) => {
9437
+ pluginsCommand.command("uninstall <path>").description("Uninstall a plugin").action(async (path18) => {
8639
9438
  try {
8640
9439
  const manager = PluginManager.getInstance();
8641
- await manager.removePlugin(path16);
8642
- console.log(`✅ Plugin uninstalled: ${path16}`);
9440
+ await manager.removePlugin(path18);
9441
+ console.log(`✅ Plugin uninstalled: ${path18}`);
8643
9442
  } catch (error) {
8644
9443
  console.error(`❌ Error uninstalling plugin: ${error.message}`);
8645
9444
  process.exit(1);
@@ -8650,109 +9449,12 @@ function createPluginsCommand() {
8650
9449
 
8651
9450
  // src/commands/skills.ts
8652
9451
  init_settings_manager();
8653
-
8654
- // src/skills/manager.ts
8655
- init_settings_manager();
8656
- import fs17 from "fs/promises";
8657
- import path16 from "path";
8658
-
8659
- class SkillsManager {
8660
- static instance;
8661
- skillsPath;
8662
- constructor() {
8663
- this.skillsPath = path16.join(getSettingsManager().getStorageDirectory(), "skills");
8664
- }
8665
- static getInstance() {
8666
- if (!SkillsManager.instance) {
8667
- SkillsManager.instance = new SkillsManager;
8668
- }
8669
- return SkillsManager.instance;
8670
- }
8671
- async ensureSkillsDirectory() {
8672
- try {
8673
- await fs17.mkdir(this.skillsPath, { recursive: true });
8674
- } catch (error) {}
8675
- }
8676
- async listSkills() {
8677
- await this.ensureSkillsDirectory();
8678
- try {
8679
- const files = await fs17.readdir(this.skillsPath);
8680
- return files.filter((file) => file.endsWith(".ts") || file.endsWith(".js") || file.endsWith(".json")).map((file) => path16.parse(file).name);
8681
- } catch (error) {
8682
- return [];
8683
- }
8684
- }
8685
- async getSkillPath(name) {
8686
- const extensions = [".ts", ".js", ".json"];
8687
- for (const ext of extensions) {
8688
- const fullPath = path16.join(this.skillsPath, `${name}${ext}`);
8689
- try {
8690
- await fs17.access(fullPath);
8691
- return fullPath;
8692
- } catch {
8693
- continue;
8694
- }
8695
- }
8696
- throw new Error(`Skill '${name}' not found`);
8697
- }
8698
- async getSkillContent(name) {
8699
- const skillPath = await this.getSkillPath(name);
8700
- return await fs17.readFile(skillPath, "utf-8");
8701
- }
8702
- async createSkill(name, description, agent) {
8703
- await this.ensureSkillsDirectory();
8704
- const prompt = `Create a robust TypeScript skill for the Super Agent CLI named "${name}".
8705
-
8706
- Description: ${description}
8707
-
8708
- The skill should be a module that exports a default function or class that implements the desired functionality.
8709
- It should valid standalone TypeScript code.
8710
- Include comments explaining how it works.
8711
-
8712
- Structure:
8713
- \`\`\`typescript
8714
- // ${name} skill
8715
- export default async function(args: any) {
8716
- // implementation
8717
- }
8718
- \`\`\`
8719
-
8720
- Return ONLY the code block.`;
8721
- const response = await agent.processUserMessage(prompt);
8722
- let code = "";
8723
- for (const entry of response) {
8724
- if (entry.type === "assistant") {
8725
- const match = entry.content.match(/```(?:typescript|ts)?\n([\s\S]*?)```/);
8726
- if (match) {
8727
- code = match[1];
8728
- break;
8729
- } else {
8730
- code = entry.content;
8731
- }
8732
- }
8733
- }
8734
- if (!code) {
8735
- throw new Error("Failed to generate skill code");
8736
- }
8737
- const filePath = path16.join(this.skillsPath, `${name}.ts`);
8738
- await fs17.writeFile(filePath, code);
8739
- }
8740
- async deleteSkill(name) {
8741
- try {
8742
- const skillPath = await this.getSkillPath(name);
8743
- await fs17.unlink(skillPath);
8744
- } catch (error) {
8745
- throw new Error(`Failed to delete skill '${name}': ${error.message}`);
8746
- }
8747
- }
8748
- }
8749
-
8750
- // src/commands/skills.ts
8751
- import { Command as Command4 } from "commander";
8752
- import inquirer from "inquirer";
8753
- import chalk3 from "chalk";
9452
+ init_manager2();
9453
+ import { Command as Command5 } from "commander";
9454
+ import inquirer2 from "inquirer";
9455
+ import chalk4 from "chalk";
8754
9456
  function createSkillsCommand() {
8755
- const skillsCommand = new Command4("skills").description("Manage AI skills");
9457
+ const skillsCommand = new Command5("skills").description("Manage AI skills");
8756
9458
  skillsCommand.command("list").description("List available skills").action(async () => {
8757
9459
  const manager = SkillsManager.getInstance();
8758
9460
  const skills = await manager.listSkills();
@@ -8769,7 +9471,7 @@ function createSkillsCommand() {
8769
9471
  const settingsManager = getSettingsManager();
8770
9472
  let description = options.description;
8771
9473
  if (!description) {
8772
- const answer = await inquirer.prompt([
9474
+ const answer = await inquirer2.prompt([
8773
9475
  {
8774
9476
  type: "input",
8775
9477
  name: "description",
@@ -8778,146 +9480,136 @@ function createSkillsCommand() {
8778
9480
  ]);
8779
9481
  description = answer.description;
8780
9482
  }
8781
- console.log(chalk3.blue(`Generating skill '${name}' based on description: "${description}"...`));
9483
+ console.log(chalk4.blue(`Generating skill '${name}' based on description: "${description}"...`));
8782
9484
  const apiKey = settingsManager.getApiKey();
8783
9485
  const baseURL = settingsManager.getBaseURL();
8784
9486
  const model = settingsManager.getCurrentModel();
8785
9487
  if (!apiKey) {
8786
- console.error(chalk3.red("API Key not found. Please configure it first."));
9488
+ console.error(chalk4.red("API Key not found. Please configure it first."));
8787
9489
  return;
8788
9490
  }
8789
9491
  const agent = new SuperAgent(apiKey, baseURL, model);
8790
9492
  await manager.createSkill(name, description, agent);
8791
- console.log(chalk3.green(`✓ Skill '${name}' created successfully.`));
9493
+ console.log(chalk4.green(`✓ Skill '${name}' created successfully.`));
8792
9494
  } catch (error) {
8793
- console.error(chalk3.red(`Error creating skill: ${error.message}`));
9495
+ console.error(chalk4.red(`Error creating skill: ${error.message}`));
8794
9496
  }
8795
9497
  });
8796
9498
  skillsCommand.command("delete <name>").description("Delete a skill").action(async (name) => {
8797
9499
  try {
8798
9500
  const manager = SkillsManager.getInstance();
8799
9501
  await manager.deleteSkill(name);
8800
- console.log(chalk3.green(`✓ Skill '${name}' deleted.`));
9502
+ console.log(chalk4.green(`✓ Skill '${name}' deleted.`));
8801
9503
  } catch (error) {
8802
- console.error(chalk3.red(`Error deleting skill: ${error.message}`));
9504
+ console.error(chalk4.red(`Error deleting skill: ${error.message}`));
8803
9505
  }
8804
9506
  });
8805
9507
  return skillsCommand;
8806
9508
  }
8807
9509
 
8808
- // src/commands/agents.ts
8809
- init_settings_manager();
8810
-
8811
- // src/agents/manager.ts
9510
+ // src/commands/import.ts
8812
9511
  init_settings_manager();
8813
- import fs18 from "fs/promises";
8814
- import path17 from "path";
8815
-
8816
- class AgentsManager {
8817
- static instance;
8818
- agentsPath;
8819
- constructor() {
8820
- this.agentsPath = path17.join(getSettingsManager().getStorageDirectory(), "agents");
8821
- }
8822
- static getInstance() {
8823
- if (!AgentsManager.instance) {
8824
- AgentsManager.instance = new AgentsManager;
9512
+ init_file_utils();
9513
+ init_manager2();
9514
+ init_manager();
9515
+ import { Command as Command6 } from "commander";
9516
+ import fs19 from "fs-extra";
9517
+ import chalk5 from "chalk";
9518
+ import path18 from "path";
9519
+ function createImportCommand() {
9520
+ const cmd = new Command6("import").description("Import resources from other AI assistants");
9521
+ cmd.command("agents <source>").description("Import agents from source (gemini, claude, kilo)").action(async (source) => {
9522
+ const sourcePath = resolveSourcePath(source);
9523
+ const agentsDir = path18.join(sourcePath, "agents");
9524
+ if (!await fs19.pathExists(agentsDir)) {
9525
+ console.error(chalk5.red(`Agents directory not found at ${agentsDir}`));
9526
+ return;
8825
9527
  }
8826
- return AgentsManager.instance;
8827
- }
8828
- async ensureAgentsDirectory() {
8829
- try {
8830
- await fs18.mkdir(this.agentsPath, { recursive: true });
8831
- } catch (error) {}
8832
- }
8833
- async listAgents() {
8834
- await this.ensureAgentsDirectory();
8835
- try {
8836
- const files = await fs18.readdir(this.agentsPath);
8837
- const agents = [];
8838
- for (const file of files) {
8839
- if (file.endsWith(".json")) {
8840
- try {
8841
- const content = await fs18.readFile(path17.join(this.agentsPath, file), "utf-8");
8842
- agents.push(JSON.parse(content));
8843
- } catch (e) {}
9528
+ const files = await fs19.readdir(agentsDir);
9529
+ const manager = AgentsManager.getInstance();
9530
+ let count = 0;
9531
+ for (const file of files) {
9532
+ if (file.endsWith(".json")) {
9533
+ try {
9534
+ const content = await fs19.readJson(path18.join(agentsDir, file));
9535
+ const agentConfig = {
9536
+ name: content.name || path18.parse(file).name,
9537
+ role: content.role || "Assistant",
9538
+ description: content.description || "Imported agent",
9539
+ model: content.model,
9540
+ tools: content.tools,
9541
+ temperature: content.temperature,
9542
+ systemPrompt: content.systemPrompt || content.system_prompt || content.prompt
9543
+ };
9544
+ await manager.createAgent(agentConfig);
9545
+ console.log(chalk5.green(`Imported agent: ${agentConfig.name}`));
9546
+ count++;
9547
+ } catch (error) {
9548
+ console.warn(chalk5.yellow(`Failed to import ${file}: ${error.message}`));
8844
9549
  }
8845
9550
  }
8846
- return agents;
8847
- } catch (error) {
8848
- return [];
8849
- }
8850
- }
8851
- async getAgent(name) {
8852
- try {
8853
- const content = await fs18.readFile(path17.join(this.agentsPath, `${name}.json`), "utf-8");
8854
- return JSON.parse(content);
8855
- } catch (error) {
8856
- return null;
8857
9551
  }
8858
- }
8859
- async createAgent(config) {
8860
- await this.ensureAgentsDirectory();
8861
- const filePath = path17.join(this.agentsPath, `${config.name}.json`);
8862
- await fs18.writeFile(filePath, JSON.stringify(config, null, 2));
8863
- }
8864
- async generateAgent(name, description, agent) {
8865
- const prompt = `Create a configuration for an AI agent named "${name}" based on this description: "${description}".
8866
-
8867
- The configuration should be a JSON object matching this interface:
8868
- interface AgentConfig {
8869
- name: string;
8870
- role: string;
8871
- description: string;
8872
- model?: string; // suggest a model if appropriate, or leave undefined
8873
- tools?: string[]; // suggest relevant tools/skills names
8874
- temperature?: number;
8875
- systemPrompt?: string; // a detailed system prompt for this agent
9552
+ console.log(chalk5.bold(`Imported ${count} agents.`));
9553
+ });
9554
+ cmd.command("skills <source>").description("Import skills from source (gemini, claude, kilo)").action(async (source) => {
9555
+ const sourcePath = resolveSourcePath(source);
9556
+ const skillsDir = path18.join(sourcePath, "skills");
9557
+ if (!await fs19.pathExists(skillsDir)) {
9558
+ console.error(chalk5.red(`Skills directory not found at ${skillsDir}`));
9559
+ return;
8876
9560
  }
8877
-
8878
- Return ONLY the JSON object.`;
8879
- const response = await agent.processUserMessage(prompt);
8880
- let jsonData = "";
8881
- for (const entry of response) {
8882
- if (entry.type === "assistant") {
8883
- const match = entry.content.match(/```(?:json)?\n([\s\S]*?)```/);
8884
- if (match) {
8885
- jsonData = match[1];
8886
- break;
8887
- } else {
8888
- if (entry.content.trim().startsWith("{")) {
8889
- jsonData = entry.content;
8890
- }
9561
+ const files = await fs19.readdir(skillsDir);
9562
+ const manager = SkillsManager.getInstance();
9563
+ let count = 0;
9564
+ for (const file of files) {
9565
+ if (file.endsWith(".ts") || file.endsWith(".js")) {
9566
+ try {
9567
+ const content = await fs19.readFile(path18.join(skillsDir, file), "utf-8");
9568
+ const name = path18.parse(file).name;
9569
+ await manager.saveSkill(name, content);
9570
+ console.log(chalk5.green(`Imported skill: ${name}`));
9571
+ count++;
9572
+ } catch (error) {
9573
+ console.warn(chalk5.yellow(`Failed to import ${file}: ${error.message}`));
8891
9574
  }
8892
9575
  }
8893
9576
  }
8894
- if (!jsonData) {
8895
- throw new Error("Failed to generate agent configuration");
8896
- }
8897
- try {
8898
- const config = JSON.parse(jsonData);
8899
- config.name = name;
8900
- await this.createAgent(config);
8901
- } catch (e) {
8902
- throw new Error(`Failed to parse generated agent config: ${e.message}`);
9577
+ console.log(chalk5.bold(`Imported ${count} skills.`));
9578
+ });
9579
+ cmd.command("hooks <source>").description("Import hooks from source settings").action(async (source) => {
9580
+ const sourcePath = resolveSourcePath(source);
9581
+ const settingsFile = source.toLowerCase() === "claude" ? "settings.local.json" : "settings.json";
9582
+ const fullPath = path18.join(sourcePath, settingsFile);
9583
+ if (!await fs19.pathExists(fullPath)) {
9584
+ console.error(chalk5.red(`Settings file not found at ${fullPath}`));
9585
+ return;
8903
9586
  }
8904
- }
8905
- async deleteAgent(name) {
8906
9587
  try {
8907
- const filePath = path17.join(this.agentsPath, `${name}.json`);
8908
- await fs18.unlink(filePath);
9588
+ const settings = await fs19.readJson(fullPath);
9589
+ if (settings.hooks) {
9590
+ const manager = getSettingsManager();
9591
+ const currentHooks = manager.getUserSetting("hooks") || {};
9592
+ const mergedHooks = { ...currentHooks, ...settings.hooks };
9593
+ manager.updateUserSetting("hooks", mergedHooks);
9594
+ console.log(chalk5.green(`Imported ${Object.keys(settings.hooks).length} hooks.`));
9595
+ } else {
9596
+ console.log(chalk5.yellow("No hooks found in settings file."));
9597
+ }
8909
9598
  } catch (error) {
8910
- throw new Error(`Failed to delete agent '${name}'`);
9599
+ console.error(chalk5.red(`Failed to import hooks: ${error.message}`));
8911
9600
  }
8912
- }
9601
+ });
9602
+ return cmd;
8913
9603
  }
8914
9604
 
8915
9605
  // src/commands/agents.ts
8916
- import { Command as Command5 } from "commander";
8917
- import inquirer2 from "inquirer";
8918
- import chalk4 from "chalk";
9606
+ init_settings_manager();
9607
+ init_manager();
9608
+ import { Command as Command7 } from "commander";
9609
+ import inquirer3 from "inquirer";
9610
+ import chalk6 from "chalk";
8919
9611
  function createAgentsCommand() {
8920
- const agentsCommand = new Command5("agents").description("Manage AI agents");
9612
+ const agentsCommand = new Command7("agents").description("Manage AI agents");
8921
9613
  agentsCommand.command("list").description("List available agents").action(async () => {
8922
9614
  const manager = AgentsManager.getInstance();
8923
9615
  const agents = await manager.listAgents();
@@ -8926,8 +9618,8 @@ function createAgentsCommand() {
8926
9618
  } else {
8927
9619
  console.log("Available agents:");
8928
9620
  agents.forEach((agent) => {
8929
- console.log(`- ${chalk4.bold(agent.name)} (${agent.role})`);
8930
- console.log(` ${chalk4.dim(agent.description)}`);
9621
+ console.log(`- ${chalk6.bold(agent.name)} (${agent.role})`);
9622
+ console.log(` ${chalk6.dim(agent.description)}`);
8931
9623
  });
8932
9624
  }
8933
9625
  });
@@ -8937,7 +9629,7 @@ function createAgentsCommand() {
8937
9629
  const settingsManager = getSettingsManager();
8938
9630
  let description = options.description;
8939
9631
  if (!description) {
8940
- const answer = await inquirer2.prompt([
9632
+ const answer = await inquirer3.prompt([
8941
9633
  {
8942
9634
  type: "input",
8943
9635
  name: "description",
@@ -8946,28 +9638,28 @@ function createAgentsCommand() {
8946
9638
  ]);
8947
9639
  description = answer.description;
8948
9640
  }
8949
- console.log(chalk4.blue(`Generating agent configuration for '${name}'...`));
9641
+ console.log(chalk6.blue(`Generating agent configuration for '${name}'...`));
8950
9642
  const apiKey = settingsManager.getApiKey();
8951
9643
  const baseURL = settingsManager.getBaseURL();
8952
9644
  const model = settingsManager.getCurrentModel();
8953
9645
  if (!apiKey) {
8954
- console.error(chalk4.red("API Key not found. Please configure it first."));
9646
+ console.error(chalk6.red("API Key not found. Please configure it first."));
8955
9647
  return;
8956
9648
  }
8957
9649
  const agent = new SuperAgent(apiKey, baseURL, model);
8958
9650
  await manager.generateAgent(name, description, agent);
8959
- console.log(chalk4.green(`✓ Agent '${name}' created successfully.`));
9651
+ console.log(chalk6.green(`✓ Agent '${name}' created successfully.`));
8960
9652
  } catch (error) {
8961
- console.error(chalk4.red(`Error creating agent: ${error.message}`));
9653
+ console.error(chalk6.red(`Error creating agent: ${error.message}`));
8962
9654
  }
8963
9655
  });
8964
9656
  agentsCommand.command("delete <name>").description("Delete an agent").action(async (name) => {
8965
9657
  try {
8966
9658
  const manager = AgentsManager.getInstance();
8967
9659
  await manager.deleteAgent(name);
8968
- console.log(chalk4.green(`✓ Agent '${name}' deleted.`));
9660
+ console.log(chalk6.green(`✓ Agent '${name}' deleted.`));
8969
9661
  } catch (error) {
8970
- console.error(chalk4.red(`Error deleting agent: ${error.message}`));
9662
+ console.error(chalk6.red(`Error deleting agent: ${error.message}`));
8971
9663
  }
8972
9664
  });
8973
9665
  return agentsCommand;
@@ -8975,37 +9667,37 @@ function createAgentsCommand() {
8975
9667
 
8976
9668
  // src/commands/mcp.ts
8977
9669
  init_config();
8978
- import { Command as Command6 } from "commander";
8979
- import chalk5 from "chalk";
9670
+ import { Command as Command8 } from "commander";
9671
+ import chalk7 from "chalk";
8980
9672
  function createMCPCommand() {
8981
- const mcpCommand = new Command6("mcp");
9673
+ const mcpCommand = new Command8("mcp");
8982
9674
  mcpCommand.description("Manage MCP (Model Context Protocol) servers");
8983
9675
  mcpCommand.command("add <name>").description("Add an MCP server").option("-t, --transport <type>", "Transport type (stdio, http, sse, streamable_http)", "stdio").option("-c, --command <command>", "Command to run the server (for stdio transport)").option("-a, --args [args...]", "Arguments for the server command (for stdio transport)", []).option("-u, --url <url>", "URL for HTTP/SSE transport").option("-h, --headers [headers...]", "HTTP headers (key=value format)", []).option("-e, --env [env...]", "Environment variables (key=value format)", []).action(async (name, options) => {
8984
9676
  try {
8985
9677
  if (PREDEFINED_SERVERS[name]) {
8986
9678
  const config2 = PREDEFINED_SERVERS[name];
8987
9679
  addMCPServer(config2);
8988
- console.log(chalk5.green(`✓ Added predefined MCP server: ${name}`));
9680
+ console.log(chalk7.green(`✓ Added predefined MCP server: ${name}`));
8989
9681
  const manager2 = getMCPManager();
8990
9682
  await manager2.addServer(config2);
8991
- console.log(chalk5.green(`✓ Connected to MCP server: ${name}`));
9683
+ console.log(chalk7.green(`✓ Connected to MCP server: ${name}`));
8992
9684
  const tools2 = manager2.getTools().filter((t) => t.serverName === name);
8993
- console.log(chalk5.blue(` Available tools: ${tools2.length}`));
9685
+ console.log(chalk7.blue(` Available tools: ${tools2.length}`));
8994
9686
  return;
8995
9687
  }
8996
9688
  const transportType = options.transport.toLowerCase();
8997
9689
  if (transportType === "stdio") {
8998
9690
  if (!options.command) {
8999
- console.error(chalk5.red("Error: --command is required for stdio transport"));
9691
+ console.error(chalk7.red("Error: --command is required for stdio transport"));
9000
9692
  process.exit(1);
9001
9693
  }
9002
9694
  } else if (transportType === "http" || transportType === "sse" || transportType === "streamable_http") {
9003
9695
  if (!options.url) {
9004
- console.error(chalk5.red(`Error: --url is required for ${transportType} transport`));
9696
+ console.error(chalk7.red(`Error: --url is required for ${transportType} transport`));
9005
9697
  process.exit(1);
9006
9698
  }
9007
9699
  } else {
9008
- console.error(chalk5.red("Error: Transport type must be stdio, http, sse, or streamable_http"));
9700
+ console.error(chalk7.red("Error: Transport type must be stdio, http, sse, or streamable_http"));
9009
9701
  process.exit(1);
9010
9702
  }
9011
9703
  const env = {};
@@ -9034,14 +9726,14 @@ function createMCPCommand() {
9034
9726
  }
9035
9727
  };
9036
9728
  addMCPServer(config);
9037
- console.log(chalk5.green(`✓ Added MCP server: ${name}`));
9729
+ console.log(chalk7.green(`✓ Added MCP server: ${name}`));
9038
9730
  const manager = getMCPManager();
9039
9731
  await manager.addServer(config);
9040
- console.log(chalk5.green(`✓ Connected to MCP server: ${name}`));
9732
+ console.log(chalk7.green(`✓ Connected to MCP server: ${name}`));
9041
9733
  const tools = manager.getTools().filter((t) => t.serverName === name);
9042
- console.log(chalk5.blue(` Available tools: ${tools.length}`));
9734
+ console.log(chalk7.blue(` Available tools: ${tools.length}`));
9043
9735
  } catch (error) {
9044
- console.error(chalk5.red(`Error adding MCP server: ${error.message}`));
9736
+ console.error(chalk7.red(`Error adding MCP server: ${error.message}`));
9045
9737
  process.exit(1);
9046
9738
  }
9047
9739
  });
@@ -9051,7 +9743,7 @@ function createMCPCommand() {
9051
9743
  try {
9052
9744
  config = JSON.parse(jsonConfig);
9053
9745
  } catch (error) {
9054
- console.error(chalk5.red("Error: Invalid JSON configuration"));
9746
+ console.error(chalk7.red("Error: Invalid JSON configuration"));
9055
9747
  process.exit(1);
9056
9748
  }
9057
9749
  const serverConfig = {
@@ -9076,14 +9768,14 @@ function createMCPCommand() {
9076
9768
  }
9077
9769
  }
9078
9770
  addMCPServer(serverConfig);
9079
- console.log(chalk5.green(`✓ Added MCP server: ${name}`));
9771
+ console.log(chalk7.green(`✓ Added MCP server: ${name}`));
9080
9772
  const manager = getMCPManager();
9081
9773
  await manager.addServer(serverConfig);
9082
- console.log(chalk5.green(`✓ Connected to MCP server: ${name}`));
9774
+ console.log(chalk7.green(`✓ Connected to MCP server: ${name}`));
9083
9775
  const tools = manager.getTools().filter((t) => t.serverName === name);
9084
- console.log(chalk5.blue(` Available tools: ${tools.length}`));
9776
+ console.log(chalk7.blue(` Available tools: ${tools.length}`));
9085
9777
  } catch (error) {
9086
- console.error(chalk5.red(`Error adding MCP server: ${error.message}`));
9778
+ console.error(chalk7.red(`Error adding MCP server: ${error.message}`));
9087
9779
  process.exit(1);
9088
9780
  }
9089
9781
  });
@@ -9092,9 +9784,9 @@ function createMCPCommand() {
9092
9784
  const manager = getMCPManager();
9093
9785
  await manager.removeServer(name);
9094
9786
  removeMCPServer(name);
9095
- console.log(chalk5.green(`✓ Removed MCP server: ${name}`));
9787
+ console.log(chalk7.green(`✓ Removed MCP server: ${name}`));
9096
9788
  } catch (error) {
9097
- console.error(chalk5.red(`Error removing MCP server: ${error.message}`));
9789
+ console.error(chalk7.red(`Error removing MCP server: ${error.message}`));
9098
9790
  process.exit(1);
9099
9791
  }
9100
9792
  });
@@ -9102,15 +9794,15 @@ function createMCPCommand() {
9102
9794
  const config = loadMCPConfig();
9103
9795
  const manager = getMCPManager();
9104
9796
  if (config.servers.length === 0) {
9105
- console.log(chalk5.yellow("No MCP servers configured"));
9797
+ console.log(chalk7.yellow("No MCP servers configured"));
9106
9798
  return;
9107
9799
  }
9108
- console.log(chalk5.bold("Configured MCP servers:"));
9800
+ console.log(chalk7.bold("Configured MCP servers:"));
9109
9801
  console.log();
9110
9802
  for (const server of config.servers) {
9111
9803
  const isConnected = manager.getServers().includes(server.name);
9112
- const status = isConnected ? chalk5.green("✓ Connected") : chalk5.red("✗ Disconnected");
9113
- console.log(`${chalk5.bold(server.name)}: ${status}`);
9804
+ const status = isConnected ? chalk7.green("✓ Connected") : chalk7.red("✗ Disconnected");
9805
+ console.log(`${chalk7.bold(server.name)}: ${status}`);
9114
9806
  if (server.transport) {
9115
9807
  console.log(` Transport: ${server.transport.type}`);
9116
9808
  if (server.transport.type === "stdio") {
@@ -9143,15 +9835,15 @@ function createMCPCommand() {
9143
9835
  const config = loadMCPConfig();
9144
9836
  const serverConfig = config.servers.find((s) => s.name === name);
9145
9837
  if (!serverConfig) {
9146
- console.error(chalk5.red(`Server ${name} not found`));
9838
+ console.error(chalk7.red(`Server ${name} not found`));
9147
9839
  process.exit(1);
9148
9840
  }
9149
- console.log(chalk5.blue(`Testing connection to ${name}...`));
9841
+ console.log(chalk7.blue(`Testing connection to ${name}...`));
9150
9842
  const manager = getMCPManager();
9151
9843
  await manager.addServer(serverConfig);
9152
9844
  const tools = manager.getTools().filter((t) => t.serverName === name);
9153
- console.log(chalk5.green(`✓ Successfully connected to ${name}`));
9154
- console.log(chalk5.blue(` Available tools: ${tools.length}`));
9845
+ console.log(chalk7.green(`✓ Successfully connected to ${name}`));
9846
+ console.log(chalk7.blue(` Available tools: ${tools.length}`));
9155
9847
  if (tools.length > 0) {
9156
9848
  console.log(" Tools:");
9157
9849
  tools.forEach((tool) => {
@@ -9160,7 +9852,7 @@ function createMCPCommand() {
9160
9852
  });
9161
9853
  }
9162
9854
  } catch (error) {
9163
- console.error(chalk5.red(`✗ Failed to connect to ${name}: ${error.message}`));
9855
+ console.error(chalk7.red(`✗ Failed to connect to ${name}: ${error.message}`));
9164
9856
  process.exit(1);
9165
9857
  }
9166
9858
  });
@@ -9169,7 +9861,7 @@ function createMCPCommand() {
9169
9861
 
9170
9862
  // src/commands/git.ts
9171
9863
  init_settings_manager();
9172
- import { Command as Command7 } from "commander";
9864
+ import { Command as Command9 } from "commander";
9173
9865
  async function loadApiKey() {
9174
9866
  const manager = getSettingsManager();
9175
9867
  return manager.getApiKey();
@@ -9273,7 +9965,7 @@ Respond with ONLY the commit message, no additional text.`;
9273
9965
  }
9274
9966
  }
9275
9967
  function createGitCommand() {
9276
- const gitCommand = new Command7("git").description("Git operations with AI assistance");
9968
+ const gitCommand = new Command9("git").description("Git operations with AI assistance");
9277
9969
  gitCommand.command("commit-and-push").description("Generate AI commit message and push to remote").option("-d, --directory <dir>", "set working directory", process.cwd()).option("-k, --api-key <key>", "Super Agent API key (or set SUPER_AGENT_API_KEY env var)").option("-u, --base-url <url>", "Super Agent API base URL (or set SUPER_AGENT_BASE_URL env var)").option("-m, --model <model>", "AI model to use (e.g., GLM-4.7) (or set SUPER_AGENT_MODEL env var)").option("--max-tool-rounds <rounds>", "maximum number of tool execution rounds (default: 400)", "400").action(async (options) => {
9278
9970
  if (options.directory) {
9279
9971
  try {
@@ -9313,6 +10005,8 @@ function registerCommands(program) {
9313
10005
  program.addCommand(createServeCommand());
9314
10006
  program.addCommand(createSkillsCommand());
9315
10007
  program.addCommand(createAgentsCommand());
10008
+ program.addCommand(createImportCommand());
10009
+ program.addCommand(createProviderCommand());
9316
10010
  program.addCommand(createIndexCommand());
9317
10011
  }
9318
10012