@involvex/super-agent-cli 0.0.62 → 0.0.63
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 +958 -447
- package/dist/super-agent-cli.exe +0 -0
- package/package.json +5 -2
- package/tsc_output.txt +0 -2
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
|
-
|
|
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
|
|
422
|
-
import * as
|
|
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 =
|
|
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 (
|
|
444
|
-
const content = await
|
|
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
|
|
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
|
|
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 =
|
|
494
|
-
const relativePath =
|
|
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
|
|
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
|
|
546
|
-
import * as
|
|
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 =
|
|
555
|
-
|
|
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 =
|
|
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
|
|
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
|
|
575
|
-
const session = await
|
|
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 ||
|
|
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
|
|
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
|
|
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
|
|
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
|
|
623
|
-
await
|
|
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
|
|
633
|
-
const session = await
|
|
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.
|
|
981
|
+
version: "0.0.63",
|
|
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
|
-
"
|
|
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
|
|
762
|
-
import * as
|
|
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 =
|
|
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
|
|
783
|
-
const cache = await
|
|
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
|
|
1124
|
+
await fs16.outputJson(this.cacheFile, info);
|
|
795
1125
|
} catch (error) {}
|
|
796
1126
|
}
|
|
797
1127
|
compareVersions(v1, v2) {
|
|
@@ -992,69 +1322,8 @@ class ConfirmationService extends EventEmitter {
|
|
|
992
1322
|
// src/index.ts
|
|
993
1323
|
init_settings_manager();
|
|
994
1324
|
|
|
995
|
-
// src/
|
|
996
|
-
|
|
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);
|
|
1057
|
-
}
|
|
1325
|
+
// src/hooks/use-input-handler.ts
|
|
1326
|
+
init_file_utils();
|
|
1058
1327
|
|
|
1059
1328
|
// src/utils/text-utils.ts
|
|
1060
1329
|
function isWordBoundary(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
|
|
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,13 +3114,17 @@ 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
|
});
|
|
2834
3126
|
const availableModels = useMemo2(() => {
|
|
2835
|
-
return loadModelConfig();
|
|
3127
|
+
return loadModelConfig(activeProvider);
|
|
2836
3128
|
}, [activeProvider]);
|
|
2837
3129
|
const handleDirectCommand = async (input2) => {
|
|
2838
3130
|
const trimmedInput = input2.trim();
|
|
@@ -2898,6 +3190,64 @@ Config Commands:
|
|
|
2898
3190
|
clearInput();
|
|
2899
3191
|
return true;
|
|
2900
3192
|
}
|
|
3193
|
+
if (trimmedInput === "/provider config") {
|
|
3194
|
+
setChatHistory((prev) => [
|
|
3195
|
+
...prev,
|
|
3196
|
+
{
|
|
3197
|
+
type: "assistant",
|
|
3198
|
+
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.",
|
|
3199
|
+
timestamp: new Date
|
|
3200
|
+
}
|
|
3201
|
+
]);
|
|
3202
|
+
clearInput();
|
|
3203
|
+
return true;
|
|
3204
|
+
}
|
|
3205
|
+
if (trimmedInput.startsWith("/provider set-key ")) {
|
|
3206
|
+
const args = trimmedInput.replace("/provider set-key ", "").trim().split(" ");
|
|
3207
|
+
const providerId = args[0];
|
|
3208
|
+
const key = args.slice(1).join(" ");
|
|
3209
|
+
if (!providerId || !key) {
|
|
3210
|
+
setChatHistory((prev) => [
|
|
3211
|
+
...prev,
|
|
3212
|
+
{
|
|
3213
|
+
type: "assistant",
|
|
3214
|
+
content: "❌ Usage: /provider set-key <provider> <api_key>",
|
|
3215
|
+
timestamp: new Date
|
|
3216
|
+
}
|
|
3217
|
+
]);
|
|
3218
|
+
clearInput();
|
|
3219
|
+
return true;
|
|
3220
|
+
}
|
|
3221
|
+
const manager = getSettingsManager();
|
|
3222
|
+
const settings = manager.loadUserSettings();
|
|
3223
|
+
if (settings.providers && settings.providers[providerId]) {
|
|
3224
|
+
const newProviders = { ...settings.providers };
|
|
3225
|
+
newProviders[providerId] = {
|
|
3226
|
+
...newProviders[providerId],
|
|
3227
|
+
api_key: key
|
|
3228
|
+
};
|
|
3229
|
+
manager.updateUserSetting("providers", newProviders);
|
|
3230
|
+
setChatHistory((prev) => [
|
|
3231
|
+
...prev,
|
|
3232
|
+
{
|
|
3233
|
+
type: "assistant",
|
|
3234
|
+
content: `✅ API Key for ${providerId} updated.`,
|
|
3235
|
+
timestamp: new Date
|
|
3236
|
+
}
|
|
3237
|
+
]);
|
|
3238
|
+
} else {
|
|
3239
|
+
setChatHistory((prev) => [
|
|
3240
|
+
...prev,
|
|
3241
|
+
{
|
|
3242
|
+
type: "assistant",
|
|
3243
|
+
content: `❌ Provider '${providerId}' not found.`,
|
|
3244
|
+
timestamp: new Date
|
|
3245
|
+
}
|
|
3246
|
+
]);
|
|
3247
|
+
}
|
|
3248
|
+
clearInput();
|
|
3249
|
+
return true;
|
|
3250
|
+
}
|
|
2901
3251
|
if (trimmedInput.startsWith("/provider use ")) {
|
|
2902
3252
|
const providerId = trimmedInput.replace("/provider use ", "").trim();
|
|
2903
3253
|
const manager = getSettingsManager();
|
|
@@ -3071,6 +3421,149 @@ ${chats.length ? chats.map((c) => `- ${c}`).join(`
|
|
|
3071
3421
|
clearInput();
|
|
3072
3422
|
return true;
|
|
3073
3423
|
}
|
|
3424
|
+
if (trimmedInput.startsWith("/import ")) {
|
|
3425
|
+
const args = trimmedInput.replace("/import ", "").split(" ");
|
|
3426
|
+
const type = args[0];
|
|
3427
|
+
const source = args[1];
|
|
3428
|
+
if (!type || !source) {
|
|
3429
|
+
setChatHistory((prev) => [
|
|
3430
|
+
...prev,
|
|
3431
|
+
{
|
|
3432
|
+
type: "assistant",
|
|
3433
|
+
content: `❌ Usage: /import <type> <source>
|
|
3434
|
+
Types: agents, skills, hooks
|
|
3435
|
+
Sources: gemini, claude, kilo, or path`,
|
|
3436
|
+
timestamp: new Date
|
|
3437
|
+
}
|
|
3438
|
+
]);
|
|
3439
|
+
clearInput();
|
|
3440
|
+
return true;
|
|
3441
|
+
}
|
|
3442
|
+
setIsProcessing(true);
|
|
3443
|
+
setChatHistory((prev) => [
|
|
3444
|
+
...prev,
|
|
3445
|
+
{
|
|
3446
|
+
type: "assistant",
|
|
3447
|
+
content: `Importing ${type} from ${source}...`,
|
|
3448
|
+
timestamp: new Date
|
|
3449
|
+
}
|
|
3450
|
+
]);
|
|
3451
|
+
try {
|
|
3452
|
+
const { resolveSourcePath: resolveSourcePath2 } = await Promise.resolve().then(() => (init_file_utils(), exports_file_utils));
|
|
3453
|
+
const { AgentsManager: AgentsManager2 } = await Promise.resolve().then(() => (init_manager(), exports_manager));
|
|
3454
|
+
const { SkillsManager: SkillsManager2 } = await Promise.resolve().then(() => (init_manager2(), exports_manager2));
|
|
3455
|
+
const { getSettingsManager: getSettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), exports_settings_manager));
|
|
3456
|
+
const fs9 = await import("fs-extra");
|
|
3457
|
+
const path8 = await import("path");
|
|
3458
|
+
const sourcePath = resolveSourcePath2(source);
|
|
3459
|
+
if (type === "agents") {
|
|
3460
|
+
const agentsDir = path8.join(sourcePath, "agents");
|
|
3461
|
+
if (!await fs9.pathExists(agentsDir)) {
|
|
3462
|
+
throw new Error(`Agents directory not found at ${agentsDir}`);
|
|
3463
|
+
}
|
|
3464
|
+
const files = await fs9.readdir(agentsDir);
|
|
3465
|
+
const manager = AgentsManager2.getInstance();
|
|
3466
|
+
let count = 0;
|
|
3467
|
+
for (const file of files) {
|
|
3468
|
+
if (file.endsWith(".json")) {
|
|
3469
|
+
try {
|
|
3470
|
+
const content = await fs9.readJson(path8.join(agentsDir, file));
|
|
3471
|
+
const agentConfig = {
|
|
3472
|
+
name: content.name || path8.parse(file).name,
|
|
3473
|
+
role: content.role || "Assistant",
|
|
3474
|
+
description: content.description || "Imported agent",
|
|
3475
|
+
model: content.model,
|
|
3476
|
+
tools: content.tools,
|
|
3477
|
+
temperature: content.temperature,
|
|
3478
|
+
systemPrompt: content.systemPrompt || content.system_prompt || content.prompt
|
|
3479
|
+
};
|
|
3480
|
+
await manager.createAgent(agentConfig);
|
|
3481
|
+
count++;
|
|
3482
|
+
} catch (e) {}
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3485
|
+
setChatHistory((prev) => [
|
|
3486
|
+
...prev,
|
|
3487
|
+
{
|
|
3488
|
+
type: "assistant",
|
|
3489
|
+
content: `✅ Imported ${count} agents.`,
|
|
3490
|
+
timestamp: new Date
|
|
3491
|
+
}
|
|
3492
|
+
]);
|
|
3493
|
+
} else if (type === "skills") {
|
|
3494
|
+
const skillsDir = path8.join(sourcePath, "skills");
|
|
3495
|
+
if (!await fs9.pathExists(skillsDir)) {
|
|
3496
|
+
throw new Error(`Skills directory not found at ${skillsDir}`);
|
|
3497
|
+
}
|
|
3498
|
+
const files = await fs9.readdir(skillsDir);
|
|
3499
|
+
const manager = SkillsManager2.getInstance();
|
|
3500
|
+
let count = 0;
|
|
3501
|
+
for (const file of files) {
|
|
3502
|
+
if (file.endsWith(".ts") || file.endsWith(".js")) {
|
|
3503
|
+
try {
|
|
3504
|
+
const content = await fs9.readFile(path8.join(skillsDir, file), "utf-8");
|
|
3505
|
+
const name = path8.parse(file).name;
|
|
3506
|
+
await manager.saveSkill(name, content);
|
|
3507
|
+
count++;
|
|
3508
|
+
} catch (e) {}
|
|
3509
|
+
}
|
|
3510
|
+
}
|
|
3511
|
+
setChatHistory((prev) => [
|
|
3512
|
+
...prev,
|
|
3513
|
+
{
|
|
3514
|
+
type: "assistant",
|
|
3515
|
+
content: `✅ Imported ${count} skills.`,
|
|
3516
|
+
timestamp: new Date
|
|
3517
|
+
}
|
|
3518
|
+
]);
|
|
3519
|
+
} else if (type === "hooks") {
|
|
3520
|
+
const settingsFile = source.toLowerCase() === "claude" ? "settings.local.json" : "settings.json";
|
|
3521
|
+
const fullPath = path8.join(sourcePath, settingsFile);
|
|
3522
|
+
if (!await fs9.pathExists(fullPath)) {
|
|
3523
|
+
throw new Error(`Settings file not found at ${fullPath}`);
|
|
3524
|
+
}
|
|
3525
|
+
const settings = await fs9.readJson(fullPath);
|
|
3526
|
+
if (settings.hooks) {
|
|
3527
|
+
const manager = getSettingsManager2();
|
|
3528
|
+
const currentHooks = manager.getUserSetting("hooks") || {};
|
|
3529
|
+
const mergedHooks = { ...currentHooks, ...settings.hooks };
|
|
3530
|
+
manager.updateUserSetting("hooks", mergedHooks);
|
|
3531
|
+
setChatHistory((prev) => [
|
|
3532
|
+
...prev,
|
|
3533
|
+
{
|
|
3534
|
+
type: "assistant",
|
|
3535
|
+
content: `✅ Imported ${Object.keys(settings.hooks).length} hooks.`,
|
|
3536
|
+
timestamp: new Date
|
|
3537
|
+
}
|
|
3538
|
+
]);
|
|
3539
|
+
} else {
|
|
3540
|
+
setChatHistory((prev) => [
|
|
3541
|
+
...prev,
|
|
3542
|
+
{
|
|
3543
|
+
type: "assistant",
|
|
3544
|
+
content: "⚠️ No hooks found in settings file.",
|
|
3545
|
+
timestamp: new Date
|
|
3546
|
+
}
|
|
3547
|
+
]);
|
|
3548
|
+
}
|
|
3549
|
+
} else {
|
|
3550
|
+
throw new Error(`Unknown import type: ${type}`);
|
|
3551
|
+
}
|
|
3552
|
+
} catch (error) {
|
|
3553
|
+
setChatHistory((prev) => [
|
|
3554
|
+
...prev,
|
|
3555
|
+
{
|
|
3556
|
+
type: "assistant",
|
|
3557
|
+
content: `❌ Import failed: ${error.message}`,
|
|
3558
|
+
timestamp: new Date
|
|
3559
|
+
}
|
|
3560
|
+
]);
|
|
3561
|
+
} finally {
|
|
3562
|
+
setIsProcessing(false);
|
|
3563
|
+
}
|
|
3564
|
+
clearInput();
|
|
3565
|
+
return true;
|
|
3566
|
+
}
|
|
3074
3567
|
if (trimmedInput.startsWith("/plugin ")) {
|
|
3075
3568
|
const args = trimmedInput.replace("/plugin ", "").split(" ");
|
|
3076
3569
|
const action = args[0];
|
|
@@ -3487,9 +3980,9 @@ ${commitMessage}`
|
|
|
3487
3980
|
for (const mention of mentionMatches) {
|
|
3488
3981
|
const filePath = mention.slice(1);
|
|
3489
3982
|
try {
|
|
3490
|
-
const stats = await
|
|
3983
|
+
const stats = await fs8.stat(filePath);
|
|
3491
3984
|
if (stats.isFile()) {
|
|
3492
|
-
const content = await
|
|
3985
|
+
const content = await fs8.readFile(filePath, "utf-8");
|
|
3493
3986
|
resolvedInput = resolvedInput.replace(mention, `
|
|
3494
3987
|
|
|
3495
3988
|
--- FILE: ${filePath} ---
|
|
@@ -3640,6 +4133,7 @@ ${structure}
|
|
|
3640
4133
|
}
|
|
3641
4134
|
|
|
3642
4135
|
// src/ui/components/mention-suggestions.tsx
|
|
4136
|
+
init_file_utils();
|
|
3643
4137
|
import { useMemo as useMemo3 } from "react";
|
|
3644
4138
|
import { Box as Box2, Text as Text2 } from "ink";
|
|
3645
4139
|
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
@@ -4417,6 +4911,7 @@ function LoadingSpinner({
|
|
|
4417
4911
|
}
|
|
4418
4912
|
|
|
4419
4913
|
// src/ui/components/command-palette.tsx
|
|
4914
|
+
init_file_utils();
|
|
4420
4915
|
import { useMemo as useMemo4 } from "react";
|
|
4421
4916
|
import { Box as Box9, Text as Text8 } from "ink";
|
|
4422
4917
|
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
@@ -5055,8 +5550,8 @@ class ConfirmationTool {
|
|
|
5055
5550
|
}
|
|
5056
5551
|
}
|
|
5057
5552
|
// src/tools/morph-editor.ts
|
|
5058
|
-
import * as
|
|
5059
|
-
import
|
|
5553
|
+
import * as path8 from "path";
|
|
5554
|
+
import fs9 from "fs-extra";
|
|
5060
5555
|
import axios2 from "axios";
|
|
5061
5556
|
|
|
5062
5557
|
class MorphEditorTool {
|
|
@@ -5071,8 +5566,8 @@ class MorphEditorTool {
|
|
|
5071
5566
|
}
|
|
5072
5567
|
async editFile(targetFile, instructions, codeEdit) {
|
|
5073
5568
|
try {
|
|
5074
|
-
const resolvedPath =
|
|
5075
|
-
if (!await
|
|
5569
|
+
const resolvedPath = path8.resolve(targetFile);
|
|
5570
|
+
if (!await fs9.pathExists(resolvedPath)) {
|
|
5076
5571
|
return {
|
|
5077
5572
|
success: false,
|
|
5078
5573
|
error: `File not found: ${targetFile}`
|
|
@@ -5084,7 +5579,7 @@ class MorphEditorTool {
|
|
|
5084
5579
|
error: "MORPH_API_KEY not configured. Please set your Morph API key."
|
|
5085
5580
|
};
|
|
5086
5581
|
}
|
|
5087
|
-
const initialCode = await
|
|
5582
|
+
const initialCode = await fs9.readFile(resolvedPath, "utf-8");
|
|
5088
5583
|
const sessionFlags = this.confirmationService.getSessionFlags();
|
|
5089
5584
|
if (!sessionFlags.fileOperations && !sessionFlags.allOperations) {
|
|
5090
5585
|
const confirmationResult = await this.confirmationService.requestConfirmation({
|
|
@@ -5104,7 +5599,7 @@ ${codeEdit}`
|
|
|
5104
5599
|
}
|
|
5105
5600
|
}
|
|
5106
5601
|
const mergedCode = await this.callMorphApply(instructions, initialCode, codeEdit);
|
|
5107
|
-
await
|
|
5602
|
+
await fs9.writeFile(resolvedPath, mergedCode, "utf-8");
|
|
5108
5603
|
const oldLines = initialCode.split(`
|
|
5109
5604
|
`);
|
|
5110
5605
|
const newLines = mergedCode.split(`
|
|
@@ -5287,11 +5782,11 @@ ${codeEdit}`
|
|
|
5287
5782
|
}
|
|
5288
5783
|
async view(filePath, viewRange) {
|
|
5289
5784
|
try {
|
|
5290
|
-
const resolvedPath =
|
|
5291
|
-
if (await
|
|
5292
|
-
const stats = await
|
|
5785
|
+
const resolvedPath = path8.resolve(filePath);
|
|
5786
|
+
if (await fs9.pathExists(resolvedPath)) {
|
|
5787
|
+
const stats = await fs9.stat(resolvedPath);
|
|
5293
5788
|
if (stats.isDirectory()) {
|
|
5294
|
-
const files = await
|
|
5789
|
+
const files = await fs9.readdir(resolvedPath);
|
|
5295
5790
|
return {
|
|
5296
5791
|
success: true,
|
|
5297
5792
|
output: `Directory contents of ${filePath}:
|
|
@@ -5299,7 +5794,7 @@ ${files.join(`
|
|
|
5299
5794
|
`)}`
|
|
5300
5795
|
};
|
|
5301
5796
|
}
|
|
5302
|
-
const content = await
|
|
5797
|
+
const content = await fs9.readFile(resolvedPath, "utf-8");
|
|
5303
5798
|
const lines = content.split(`
|
|
5304
5799
|
`);
|
|
5305
5800
|
if (viewRange) {
|
|
@@ -5345,8 +5840,8 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
5345
5840
|
}
|
|
5346
5841
|
}
|
|
5347
5842
|
// src/tools/project-map.ts
|
|
5348
|
-
import * as
|
|
5349
|
-
import
|
|
5843
|
+
import * as path9 from "path";
|
|
5844
|
+
import fs10 from "fs-extra";
|
|
5350
5845
|
|
|
5351
5846
|
class ProjectMapTool {
|
|
5352
5847
|
currentDirectory = process.cwd();
|
|
@@ -5380,7 +5875,7 @@ Important Files:
|
|
|
5380
5875
|
}
|
|
5381
5876
|
let result = "";
|
|
5382
5877
|
try {
|
|
5383
|
-
const entries = await
|
|
5878
|
+
const entries = await fs10.readdir(dir, { withFileTypes: true });
|
|
5384
5879
|
const sortedEntries = entries.sort((a, b) => {
|
|
5385
5880
|
if (a.isDirectory() && !b.isDirectory()) {
|
|
5386
5881
|
return -1;
|
|
@@ -5408,7 +5903,7 @@ Important Files:
|
|
|
5408
5903
|
if (entry.isDirectory()) {
|
|
5409
5904
|
result += `${indent}\uD83D\uDCC1 ${entry.name}/
|
|
5410
5905
|
`;
|
|
5411
|
-
result += await this.generateTree(
|
|
5906
|
+
result += await this.generateTree(path9.join(dir, entry.name), maxDepth, currentDepth + 1);
|
|
5412
5907
|
} else {
|
|
5413
5908
|
result += `${indent}\uD83D\uDCC4 ${entry.name}
|
|
5414
5909
|
`;
|
|
@@ -5430,8 +5925,8 @@ Important Files:
|
|
|
5430
5925
|
];
|
|
5431
5926
|
const found = [];
|
|
5432
5927
|
for (const pattern of importantPatterns) {
|
|
5433
|
-
const fullPath =
|
|
5434
|
-
if (await
|
|
5928
|
+
const fullPath = path9.join(this.currentDirectory, pattern);
|
|
5929
|
+
if (await fs10.pathExists(fullPath)) {
|
|
5435
5930
|
found.push(pattern);
|
|
5436
5931
|
}
|
|
5437
5932
|
}
|
|
@@ -5444,8 +5939,8 @@ Important Files:
|
|
|
5444
5939
|
// src/tools/search.ts
|
|
5445
5940
|
init_indexer();
|
|
5446
5941
|
import { spawn } from "child_process";
|
|
5447
|
-
import * as
|
|
5448
|
-
import
|
|
5942
|
+
import * as path11 from "path";
|
|
5943
|
+
import fs12 from "fs-extra";
|
|
5449
5944
|
|
|
5450
5945
|
class SearchTool {
|
|
5451
5946
|
confirmationService = ConfirmationService.getInstance();
|
|
@@ -5474,7 +5969,7 @@ class SearchTool {
|
|
|
5474
5969
|
const searchPattern = query.toLowerCase();
|
|
5475
5970
|
fileResults = entries.filter((e) => e.path.toLowerCase().includes(searchPattern)).map((e) => ({
|
|
5476
5971
|
path: e.path,
|
|
5477
|
-
name:
|
|
5972
|
+
name: path11.basename(e.path),
|
|
5478
5973
|
score: 10
|
|
5479
5974
|
}));
|
|
5480
5975
|
} else {
|
|
@@ -5598,13 +6093,13 @@ class SearchTool {
|
|
|
5598
6093
|
return;
|
|
5599
6094
|
}
|
|
5600
6095
|
try {
|
|
5601
|
-
const entries = await
|
|
6096
|
+
const entries = await fs12.readdir(dir, { withFileTypes: true });
|
|
5602
6097
|
for (const entry of entries) {
|
|
5603
6098
|
if (files.length >= maxResults) {
|
|
5604
6099
|
break;
|
|
5605
6100
|
}
|
|
5606
|
-
const fullPath =
|
|
5607
|
-
const relativePath =
|
|
6101
|
+
const fullPath = path11.join(dir, entry.name);
|
|
6102
|
+
const relativePath = path11.relative(this.currentDirectory, fullPath);
|
|
5608
6103
|
if (!options.includeHidden && entry.name.startsWith(".")) {
|
|
5609
6104
|
continue;
|
|
5610
6105
|
}
|
|
@@ -5703,19 +6198,19 @@ class SearchTool {
|
|
|
5703
6198
|
}
|
|
5704
6199
|
// src/tools/text-editor.ts
|
|
5705
6200
|
import { writeFile as writeFilePromise } from "fs/promises";
|
|
5706
|
-
import * as
|
|
5707
|
-
import
|
|
6201
|
+
import * as path12 from "path";
|
|
6202
|
+
import fs13 from "fs-extra";
|
|
5708
6203
|
|
|
5709
6204
|
class TextEditorTool {
|
|
5710
6205
|
editHistory = [];
|
|
5711
6206
|
confirmationService = ConfirmationService.getInstance();
|
|
5712
6207
|
async view(filePath, viewRange) {
|
|
5713
6208
|
try {
|
|
5714
|
-
const resolvedPath =
|
|
5715
|
-
if (await
|
|
5716
|
-
const stats = await
|
|
6209
|
+
const resolvedPath = path12.resolve(filePath);
|
|
6210
|
+
if (await fs13.pathExists(resolvedPath)) {
|
|
6211
|
+
const stats = await fs13.stat(resolvedPath);
|
|
5717
6212
|
if (stats.isDirectory()) {
|
|
5718
|
-
const files = await
|
|
6213
|
+
const files = await fs13.readdir(resolvedPath);
|
|
5719
6214
|
return {
|
|
5720
6215
|
success: true,
|
|
5721
6216
|
output: `Directory contents of ${filePath}:
|
|
@@ -5723,7 +6218,7 @@ ${files.join(`
|
|
|
5723
6218
|
`)}`
|
|
5724
6219
|
};
|
|
5725
6220
|
}
|
|
5726
|
-
const content = await
|
|
6221
|
+
const content = await fs13.readFile(resolvedPath, "utf-8");
|
|
5727
6222
|
const lines = content.split(`
|
|
5728
6223
|
`);
|
|
5729
6224
|
if (viewRange) {
|
|
@@ -5763,14 +6258,14 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
5763
6258
|
}
|
|
5764
6259
|
async strReplace(filePath, oldStr, newStr, replaceAll = false) {
|
|
5765
6260
|
try {
|
|
5766
|
-
const resolvedPath =
|
|
5767
|
-
if (!await
|
|
6261
|
+
const resolvedPath = path12.resolve(filePath);
|
|
6262
|
+
if (!await fs13.pathExists(resolvedPath)) {
|
|
5768
6263
|
return {
|
|
5769
6264
|
success: false,
|
|
5770
6265
|
error: `File not found: ${filePath}`
|
|
5771
6266
|
};
|
|
5772
6267
|
}
|
|
5773
|
-
const content = await
|
|
6268
|
+
const content = await fs13.readFile(resolvedPath, "utf-8");
|
|
5774
6269
|
if (!content.includes(oldStr)) {
|
|
5775
6270
|
if (oldStr.includes(`
|
|
5776
6271
|
`)) {
|
|
@@ -5838,7 +6333,7 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
5838
6333
|
}
|
|
5839
6334
|
async create(filePath, content) {
|
|
5840
6335
|
try {
|
|
5841
|
-
const resolvedPath =
|
|
6336
|
+
const resolvedPath = path12.resolve(filePath);
|
|
5842
6337
|
const sessionFlags = this.confirmationService.getSessionFlags();
|
|
5843
6338
|
if (!sessionFlags.fileOperations && !sessionFlags.allOperations) {
|
|
5844
6339
|
const contentLines = content.split(`
|
|
@@ -5864,8 +6359,8 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
5864
6359
|
};
|
|
5865
6360
|
}
|
|
5866
6361
|
}
|
|
5867
|
-
const dir =
|
|
5868
|
-
await
|
|
6362
|
+
const dir = path12.dirname(resolvedPath);
|
|
6363
|
+
await fs13.ensureDir(dir);
|
|
5869
6364
|
await writeFilePromise(resolvedPath, content, "utf-8");
|
|
5870
6365
|
this.editHistory.push({
|
|
5871
6366
|
command: "create",
|
|
@@ -5889,14 +6384,14 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
5889
6384
|
}
|
|
5890
6385
|
async replaceLines(filePath, startLine, endLine, newContent) {
|
|
5891
6386
|
try {
|
|
5892
|
-
const resolvedPath =
|
|
5893
|
-
if (!await
|
|
6387
|
+
const resolvedPath = path12.resolve(filePath);
|
|
6388
|
+
if (!await fs13.pathExists(resolvedPath)) {
|
|
5894
6389
|
return {
|
|
5895
6390
|
success: false,
|
|
5896
6391
|
error: `File not found: ${filePath}`
|
|
5897
6392
|
};
|
|
5898
6393
|
}
|
|
5899
|
-
const fileContent = await
|
|
6394
|
+
const fileContent = await fs13.readFile(resolvedPath, "utf-8");
|
|
5900
6395
|
const lines = fileContent.split(`
|
|
5901
6396
|
`);
|
|
5902
6397
|
if (startLine < 1 || startLine > lines.length) {
|
|
@@ -5959,14 +6454,14 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
5959
6454
|
}
|
|
5960
6455
|
async insert(filePath, insertLine, content) {
|
|
5961
6456
|
try {
|
|
5962
|
-
const resolvedPath =
|
|
5963
|
-
if (!await
|
|
6457
|
+
const resolvedPath = path12.resolve(filePath);
|
|
6458
|
+
if (!await fs13.pathExists(resolvedPath)) {
|
|
5964
6459
|
return {
|
|
5965
6460
|
success: false,
|
|
5966
6461
|
error: `File not found: ${filePath}`
|
|
5967
6462
|
};
|
|
5968
6463
|
}
|
|
5969
|
-
const fileContent = await
|
|
6464
|
+
const fileContent = await fs13.readFile(resolvedPath, "utf-8");
|
|
5970
6465
|
const lines = fileContent.split(`
|
|
5971
6466
|
`);
|
|
5972
6467
|
lines.splice(insertLine - 1, 0, content);
|
|
@@ -6002,19 +6497,19 @@ ${numberedLines}${additionalLinesMessage}`
|
|
|
6002
6497
|
switch (lastEdit.command) {
|
|
6003
6498
|
case "str_replace":
|
|
6004
6499
|
if (lastEdit.path && lastEdit.old_str && lastEdit.new_str) {
|
|
6005
|
-
const content = await
|
|
6500
|
+
const content = await fs13.readFile(lastEdit.path, "utf-8");
|
|
6006
6501
|
const revertedContent = content.replace(lastEdit.new_str, lastEdit.old_str);
|
|
6007
6502
|
await writeFilePromise(lastEdit.path, revertedContent, "utf-8");
|
|
6008
6503
|
}
|
|
6009
6504
|
break;
|
|
6010
6505
|
case "create":
|
|
6011
6506
|
if (lastEdit.path) {
|
|
6012
|
-
await
|
|
6507
|
+
await fs13.remove(lastEdit.path);
|
|
6013
6508
|
}
|
|
6014
6509
|
break;
|
|
6015
6510
|
case "insert":
|
|
6016
6511
|
if (lastEdit.path && lastEdit.insert_line) {
|
|
6017
|
-
const content = await
|
|
6512
|
+
const content = await fs13.readFile(lastEdit.path, "utf-8");
|
|
6018
6513
|
const lines = content.split(`
|
|
6019
6514
|
`);
|
|
6020
6515
|
lines.splice(lastEdit.insert_line - 1, 1);
|
|
@@ -6459,19 +6954,19 @@ class OpenAICompatibleProvider {
|
|
|
6459
6954
|
}
|
|
6460
6955
|
|
|
6461
6956
|
// src/utils/custom-instructions.ts
|
|
6462
|
-
import * as
|
|
6463
|
-
import * as
|
|
6464
|
-
import * as
|
|
6957
|
+
import * as path13 from "path";
|
|
6958
|
+
import * as os3 from "os";
|
|
6959
|
+
import * as fs14 from "fs";
|
|
6465
6960
|
function loadCustomInstructions(workingDirectory = process.cwd()) {
|
|
6466
6961
|
try {
|
|
6467
|
-
let instructionsPath =
|
|
6468
|
-
if (
|
|
6469
|
-
const customInstructions =
|
|
6962
|
+
let instructionsPath = path13.join(workingDirectory, ".super-agent", "SUPER_AGENT.md");
|
|
6963
|
+
if (fs14.existsSync(instructionsPath)) {
|
|
6964
|
+
const customInstructions = fs14.readFileSync(instructionsPath, "utf-8");
|
|
6470
6965
|
return customInstructions.trim();
|
|
6471
6966
|
}
|
|
6472
|
-
instructionsPath =
|
|
6473
|
-
if (
|
|
6474
|
-
const customInstructions =
|
|
6967
|
+
instructionsPath = path13.join(os3.homedir(), ".super-agent", "SUPER_AGENT.md");
|
|
6968
|
+
if (fs14.existsSync(instructionsPath)) {
|
|
6969
|
+
const customInstructions = fs14.readFileSync(instructionsPath, "utf-8");
|
|
6475
6970
|
return customInstructions.trim();
|
|
6476
6971
|
}
|
|
6477
6972
|
return null;
|
|
@@ -8180,8 +8675,8 @@ init_settings_manager();
|
|
|
8180
8675
|
// src/web/server.ts
|
|
8181
8676
|
import { createServer } from "http";
|
|
8182
8677
|
import { WebSocketServer } from "ws";
|
|
8183
|
-
import * as
|
|
8184
|
-
import * as
|
|
8678
|
+
import * as fs17 from "fs-extra";
|
|
8679
|
+
import * as path16 from "path";
|
|
8185
8680
|
import open from "open";
|
|
8186
8681
|
import mime from "mime";
|
|
8187
8682
|
var __dirname = "/home/runner/work/super-agent-cli/super-agent-cli/src/web";
|
|
@@ -8209,21 +8704,21 @@ class WebServer {
|
|
|
8209
8704
|
const url = req.url || "/";
|
|
8210
8705
|
const requestedPath = url === "/" ? "index.html" : url;
|
|
8211
8706
|
const sanitizedPath = requestedPath.split("?")[0].split("#")[0];
|
|
8212
|
-
const clientDir =
|
|
8213
|
-
const absolutePath =
|
|
8707
|
+
const clientDir = path16.join(__dirname, "../web/client");
|
|
8708
|
+
const absolutePath = path16.resolve(clientDir, sanitizedPath.substring(1));
|
|
8214
8709
|
if (!absolutePath.startsWith(clientDir)) {
|
|
8215
8710
|
res.writeHead(403, { "Content-Type": "text/plain" });
|
|
8216
8711
|
res.end("Forbidden");
|
|
8217
8712
|
return;
|
|
8218
8713
|
}
|
|
8219
8714
|
try {
|
|
8220
|
-
if (await
|
|
8221
|
-
const stat5 = await
|
|
8715
|
+
if (await fs17.pathExists(absolutePath)) {
|
|
8716
|
+
const stat5 = await fs17.stat(absolutePath);
|
|
8222
8717
|
let filePath = absolutePath;
|
|
8223
8718
|
if (stat5.isDirectory()) {
|
|
8224
|
-
filePath =
|
|
8719
|
+
filePath = path16.join(absolutePath, "index.html");
|
|
8225
8720
|
}
|
|
8226
|
-
const content = await
|
|
8721
|
+
const content = await fs17.readFile(filePath);
|
|
8227
8722
|
const mimeType = mime.getType(filePath) || "application/octet-stream";
|
|
8228
8723
|
res.writeHead(200, { "Content-Type": mimeType });
|
|
8229
8724
|
res.end(content);
|
|
@@ -8311,7 +8806,7 @@ class WebServer {
|
|
|
8311
8806
|
}
|
|
8312
8807
|
const tree = index.entries.filter((e) => !e.path.includes("node_modules") && !e.path.startsWith(".")).map((e) => ({
|
|
8313
8808
|
path: e.path,
|
|
8314
|
-
name:
|
|
8809
|
+
name: path16.basename(e.path),
|
|
8315
8810
|
isDirectory: e.isDirectory,
|
|
8316
8811
|
size: e.size
|
|
8317
8812
|
})).slice(0, 500);
|
|
@@ -8322,11 +8817,11 @@ class WebServer {
|
|
|
8322
8817
|
}
|
|
8323
8818
|
async handleGetFileContent(filePath, ws) {
|
|
8324
8819
|
try {
|
|
8325
|
-
const fullPath =
|
|
8820
|
+
const fullPath = path16.join(process.cwd(), filePath);
|
|
8326
8821
|
if (!fullPath.startsWith(process.cwd())) {
|
|
8327
8822
|
throw new Error("Access denied");
|
|
8328
8823
|
}
|
|
8329
|
-
const content = await
|
|
8824
|
+
const content = await fs17.readFile(fullPath, "utf-8");
|
|
8330
8825
|
ws.send(JSON.stringify({
|
|
8331
8826
|
type: "file_content",
|
|
8332
8827
|
path: filePath,
|
|
@@ -8480,12 +8975,133 @@ function createServeCommand() {
|
|
|
8480
8975
|
return serveCommand;
|
|
8481
8976
|
}
|
|
8482
8977
|
|
|
8483
|
-
// src/commands/
|
|
8978
|
+
// src/commands/provider.ts
|
|
8979
|
+
init_settings_manager();
|
|
8484
8980
|
import { Command as Command2 } from "commander";
|
|
8485
|
-
import
|
|
8486
|
-
import ignore from "ignore";
|
|
8981
|
+
import inquirer from "inquirer";
|
|
8487
8982
|
import chalk2 from "chalk";
|
|
8488
|
-
|
|
8983
|
+
function createProviderCommand() {
|
|
8984
|
+
const cmd = new Command2("provider").description("Manage LLM provider configuration");
|
|
8985
|
+
cmd.command("config").description("Interactive provider configuration").action(async () => {
|
|
8986
|
+
const manager = getSettingsManager();
|
|
8987
|
+
const settings = manager.loadUserSettings();
|
|
8988
|
+
const providers = Object.keys(settings.providers);
|
|
8989
|
+
const { selectedProvider } = await inquirer.prompt([
|
|
8990
|
+
{
|
|
8991
|
+
type: "list",
|
|
8992
|
+
name: "selectedProvider",
|
|
8993
|
+
message: "Select a provider to configure:",
|
|
8994
|
+
choices: providers,
|
|
8995
|
+
default: settings.active_provider
|
|
8996
|
+
}
|
|
8997
|
+
]);
|
|
8998
|
+
const currentConfig = settings.providers[selectedProvider];
|
|
8999
|
+
if (!currentConfig) {
|
|
9000
|
+
console.error(chalk2.red(`Configuration for ${selectedProvider} not found.`));
|
|
9001
|
+
return;
|
|
9002
|
+
}
|
|
9003
|
+
const models = PROVIDER_MODELS[currentConfig.provider] || [];
|
|
9004
|
+
const { apiKey } = await inquirer.prompt([
|
|
9005
|
+
{
|
|
9006
|
+
type: "password",
|
|
9007
|
+
name: "apiKey",
|
|
9008
|
+
message: `Enter API Key for ${selectedProvider} (leave empty to keep current):`,
|
|
9009
|
+
mask: "*"
|
|
9010
|
+
}
|
|
9011
|
+
]);
|
|
9012
|
+
let selectedModel = currentConfig.model;
|
|
9013
|
+
if (models.length > 0) {
|
|
9014
|
+
const { model } = await inquirer.prompt([
|
|
9015
|
+
{
|
|
9016
|
+
type: "list",
|
|
9017
|
+
name: "model",
|
|
9018
|
+
message: "Select default model:",
|
|
9019
|
+
choices: [...models, "Custom..."],
|
|
9020
|
+
default: currentConfig.model
|
|
9021
|
+
}
|
|
9022
|
+
]);
|
|
9023
|
+
selectedModel = model;
|
|
9024
|
+
}
|
|
9025
|
+
if (selectedModel === "Custom..." || models.length === 0) {
|
|
9026
|
+
const { customModel } = await inquirer.prompt([
|
|
9027
|
+
{
|
|
9028
|
+
type: "input",
|
|
9029
|
+
name: "customModel",
|
|
9030
|
+
message: "Enter model ID:",
|
|
9031
|
+
default: currentConfig.model
|
|
9032
|
+
}
|
|
9033
|
+
]);
|
|
9034
|
+
selectedModel = customModel;
|
|
9035
|
+
}
|
|
9036
|
+
const { baseURL } = await inquirer.prompt([
|
|
9037
|
+
{
|
|
9038
|
+
type: "input",
|
|
9039
|
+
name: "baseURL",
|
|
9040
|
+
message: "Enter Base URL (optional, leave empty for default):",
|
|
9041
|
+
default: currentConfig.base_url
|
|
9042
|
+
}
|
|
9043
|
+
]);
|
|
9044
|
+
console.log(chalk2.blue(`
|
|
9045
|
+
New Configuration:`));
|
|
9046
|
+
console.log(`Provider: ${chalk2.bold(selectedProvider)}`);
|
|
9047
|
+
console.log(`Model: ${chalk2.bold(selectedModel)}`);
|
|
9048
|
+
console.log(`Base URL: ${baseURL || "Default"}`);
|
|
9049
|
+
const { confirm } = await inquirer.prompt([
|
|
9050
|
+
{
|
|
9051
|
+
type: "confirm",
|
|
9052
|
+
name: "confirm",
|
|
9053
|
+
message: "Save these settings?",
|
|
9054
|
+
default: true
|
|
9055
|
+
}
|
|
9056
|
+
]);
|
|
9057
|
+
if (confirm) {
|
|
9058
|
+
const newProviders = { ...settings.providers };
|
|
9059
|
+
newProviders[selectedProvider] = {
|
|
9060
|
+
...currentConfig,
|
|
9061
|
+
model: selectedModel,
|
|
9062
|
+
base_url: baseURL || currentConfig.base_url
|
|
9063
|
+
};
|
|
9064
|
+
if (apiKey) {
|
|
9065
|
+
newProviders[selectedProvider].api_key = apiKey;
|
|
9066
|
+
}
|
|
9067
|
+
if (baseURL !== undefined && baseURL !== currentConfig.base_url) {
|
|
9068
|
+
newProviders[selectedProvider].base_url = baseURL;
|
|
9069
|
+
}
|
|
9070
|
+
manager.updateUserSetting("providers", newProviders);
|
|
9071
|
+
if (settings.active_provider !== selectedProvider) {
|
|
9072
|
+
const { makeActive } = await inquirer.prompt([
|
|
9073
|
+
{
|
|
9074
|
+
type: "confirm",
|
|
9075
|
+
name: "makeActive",
|
|
9076
|
+
message: `Set ${selectedProvider} as active provider?`,
|
|
9077
|
+
default: true
|
|
9078
|
+
}
|
|
9079
|
+
]);
|
|
9080
|
+
if (makeActive) {
|
|
9081
|
+
manager.updateUserSetting("active_provider", selectedProvider);
|
|
9082
|
+
console.log(chalk2.green(`
|
|
9083
|
+
✅ Settings saved and ${selectedProvider} is now active.`));
|
|
9084
|
+
} else {
|
|
9085
|
+
console.log(chalk2.green(`
|
|
9086
|
+
✅ Settings saved.`));
|
|
9087
|
+
}
|
|
9088
|
+
} else {
|
|
9089
|
+
console.log(chalk2.green(`
|
|
9090
|
+
✅ Settings saved.`));
|
|
9091
|
+
}
|
|
9092
|
+
} else {
|
|
9093
|
+
console.log(chalk2.yellow("Configuration cancelled."));
|
|
9094
|
+
}
|
|
9095
|
+
});
|
|
9096
|
+
return cmd;
|
|
9097
|
+
}
|
|
9098
|
+
|
|
9099
|
+
// src/commands/index-cmd.ts
|
|
9100
|
+
import { Command as Command3 } from "commander";
|
|
9101
|
+
import fs18 from "fs/promises";
|
|
9102
|
+
import ignore from "ignore";
|
|
9103
|
+
import chalk3 from "chalk";
|
|
9104
|
+
import path17 from "path";
|
|
8489
9105
|
var DEFAULT_IGNORES = [
|
|
8490
9106
|
"node_modules",
|
|
8491
9107
|
".git",
|
|
@@ -8498,17 +9114,17 @@ var DEFAULT_IGNORES = [
|
|
|
8498
9114
|
"Thumbs.db"
|
|
8499
9115
|
];
|
|
8500
9116
|
function createIndexCommand() {
|
|
8501
|
-
const indexCommand = new
|
|
9117
|
+
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
9118
|
try {
|
|
8503
|
-
const rootDir =
|
|
8504
|
-
const outputFile2 = options.output ?
|
|
9119
|
+
const rootDir = path17.resolve(directory);
|
|
9120
|
+
const outputFile2 = options.output ? path17.resolve(options.output) : path17.join(rootDir, "index.md");
|
|
8505
9121
|
const maxDepth = parseInt(options.depth);
|
|
8506
|
-
console.log(
|
|
9122
|
+
console.log(chalk3.blue(`Indexing directory: ${rootDir}`));
|
|
8507
9123
|
const ig = ignore().add(DEFAULT_IGNORES);
|
|
8508
9124
|
if (options.ignore !== false) {
|
|
8509
9125
|
try {
|
|
8510
|
-
const gitignorePath =
|
|
8511
|
-
const gitignoreContent = await
|
|
9126
|
+
const gitignorePath = path17.join(rootDir, ".gitignore");
|
|
9127
|
+
const gitignoreContent = await fs18.readFile(gitignorePath, "utf-8");
|
|
8512
9128
|
ig.add(gitignoreContent);
|
|
8513
9129
|
} catch (e) {}
|
|
8514
9130
|
}
|
|
@@ -8523,19 +9139,19 @@ Date: ${new Date().toISOString()}
|
|
|
8523
9139
|
if (depth > maxDepth) {
|
|
8524
9140
|
return;
|
|
8525
9141
|
}
|
|
8526
|
-
const relativePath =
|
|
9142
|
+
const relativePath = path17.relative(rootDir, currentPath);
|
|
8527
9143
|
if (relativePath && ig.ignores(relativePath)) {
|
|
8528
9144
|
return;
|
|
8529
9145
|
}
|
|
8530
|
-
const stats = await
|
|
9146
|
+
const stats = await fs18.stat(currentPath);
|
|
8531
9147
|
const isDir = stats.isDirectory();
|
|
8532
|
-
const name =
|
|
9148
|
+
const name = path17.basename(currentPath);
|
|
8533
9149
|
if (isDir) {
|
|
8534
9150
|
if (relativePath) {
|
|
8535
9151
|
outputContent += `${prefix}${name}/
|
|
8536
9152
|
`;
|
|
8537
9153
|
}
|
|
8538
|
-
const entries = await
|
|
9154
|
+
const entries = await fs18.readdir(currentPath, {
|
|
8539
9155
|
withFileTypes: true
|
|
8540
9156
|
});
|
|
8541
9157
|
const sortedEntries = entries.sort((a, b) => {
|
|
@@ -8551,7 +9167,7 @@ Date: ${new Date().toISOString()}
|
|
|
8551
9167
|
const entry = sortedEntries[i];
|
|
8552
9168
|
const isLast = i === sortedEntries.length - 1;
|
|
8553
9169
|
const newPrefix = relativePath ? prefix + " " : "";
|
|
8554
|
-
await buildTree(
|
|
9170
|
+
await buildTree(path17.join(currentPath, entry.name), depth + 1, newPrefix);
|
|
8555
9171
|
}
|
|
8556
9172
|
} else {
|
|
8557
9173
|
outputContent += `${prefix}${name}
|
|
@@ -8563,10 +9179,10 @@ Date: ${new Date().toISOString()}
|
|
|
8563
9179
|
if (currentDepth > maxDepth) {
|
|
8564
9180
|
return;
|
|
8565
9181
|
}
|
|
8566
|
-
const entries = await
|
|
9182
|
+
const entries = await fs18.readdir(dir, { withFileTypes: true });
|
|
8567
9183
|
for (const entry of entries) {
|
|
8568
|
-
const fullPath =
|
|
8569
|
-
const relPath =
|
|
9184
|
+
const fullPath = path17.join(dir, entry.name);
|
|
9185
|
+
const relPath = path17.relative(rootDir, fullPath);
|
|
8570
9186
|
if (ig.ignores(relPath)) {
|
|
8571
9187
|
continue;
|
|
8572
9188
|
}
|
|
@@ -8578,8 +9194,8 @@ Date: ${new Date().toISOString()}
|
|
|
8578
9194
|
}
|
|
8579
9195
|
}
|
|
8580
9196
|
await walk(rootDir, 0);
|
|
8581
|
-
console.log(
|
|
8582
|
-
outputContent = `# Project Index: ${
|
|
9197
|
+
console.log(chalk3.blue(`Found ${files.length} files.`));
|
|
9198
|
+
outputContent = `# Project Index: ${path17.basename(rootDir)}
|
|
8583
9199
|
|
|
8584
9200
|
`;
|
|
8585
9201
|
outputContent += `Total Files: ${files.length}
|
|
@@ -8591,17 +9207,17 @@ Date: ${new Date().toISOString()}
|
|
|
8591
9207
|
for (const file of files) {
|
|
8592
9208
|
outputContent += `### ${file}
|
|
8593
9209
|
`;
|
|
8594
|
-
const stats = await
|
|
9210
|
+
const stats = await fs18.stat(path17.join(rootDir, file));
|
|
8595
9211
|
outputContent += `- Size: ${stats.size} bytes
|
|
8596
9212
|
`;
|
|
8597
9213
|
outputContent += `- Modified: ${stats.mtime.toISOString()}
|
|
8598
9214
|
|
|
8599
9215
|
`;
|
|
8600
9216
|
}
|
|
8601
|
-
await
|
|
8602
|
-
console.log(
|
|
9217
|
+
await fs18.writeFile(outputFile2, outputContent);
|
|
9218
|
+
console.log(chalk3.green(`✓ Index generated at: ${outputFile2}`));
|
|
8603
9219
|
} catch (error) {
|
|
8604
|
-
console.error(
|
|
9220
|
+
console.error(chalk3.red(`Error indexing directory: ${error.message}`));
|
|
8605
9221
|
process.exit(1);
|
|
8606
9222
|
}
|
|
8607
9223
|
});
|
|
@@ -8610,9 +9226,9 @@ Date: ${new Date().toISOString()}
|
|
|
8610
9226
|
|
|
8611
9227
|
// src/commands/plugins.ts
|
|
8612
9228
|
init_settings_manager();
|
|
8613
|
-
import { Command as
|
|
9229
|
+
import { Command as Command4 } from "commander";
|
|
8614
9230
|
function createPluginsCommand() {
|
|
8615
|
-
const pluginsCommand = new
|
|
9231
|
+
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
9232
|
pluginsCommand.command("list").description("List installed plugins").action(() => {
|
|
8617
9233
|
const manager = getSettingsManager();
|
|
8618
9234
|
const settings = manager.loadUserSettings();
|
|
@@ -8624,22 +9240,22 @@ function createPluginsCommand() {
|
|
|
8624
9240
|
console.log("Installed plugins:");
|
|
8625
9241
|
plugins.forEach((p) => console.log(`- ${p}`));
|
|
8626
9242
|
});
|
|
8627
|
-
pluginsCommand.command("install <path>").description("Install a plugin from a path, GitHub URL, or registry").action(async (
|
|
9243
|
+
pluginsCommand.command("install <path>").description("Install a plugin from a path, GitHub URL, or registry").action(async (path18) => {
|
|
8628
9244
|
try {
|
|
8629
9245
|
const manager = PluginManager.getInstance();
|
|
8630
|
-
console.log(`Installing plugin from: ${
|
|
8631
|
-
const installedPath = await manager.installPlugin(
|
|
9246
|
+
console.log(`Installing plugin from: ${path18}...`);
|
|
9247
|
+
const installedPath = await manager.installPlugin(path18);
|
|
8632
9248
|
console.log(`✅ Plugin installed successfully: ${installedPath}`);
|
|
8633
9249
|
} catch (error) {
|
|
8634
9250
|
console.error(`❌ Error installing plugin: ${error.message}`);
|
|
8635
9251
|
process.exit(1);
|
|
8636
9252
|
}
|
|
8637
9253
|
});
|
|
8638
|
-
pluginsCommand.command("uninstall <path>").description("Uninstall a plugin").action(async (
|
|
9254
|
+
pluginsCommand.command("uninstall <path>").description("Uninstall a plugin").action(async (path18) => {
|
|
8639
9255
|
try {
|
|
8640
9256
|
const manager = PluginManager.getInstance();
|
|
8641
|
-
await manager.removePlugin(
|
|
8642
|
-
console.log(`✅ Plugin uninstalled: ${
|
|
9257
|
+
await manager.removePlugin(path18);
|
|
9258
|
+
console.log(`✅ Plugin uninstalled: ${path18}`);
|
|
8643
9259
|
} catch (error) {
|
|
8644
9260
|
console.error(`❌ Error uninstalling plugin: ${error.message}`);
|
|
8645
9261
|
process.exit(1);
|
|
@@ -8650,109 +9266,12 @@ function createPluginsCommand() {
|
|
|
8650
9266
|
|
|
8651
9267
|
// src/commands/skills.ts
|
|
8652
9268
|
init_settings_manager();
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
8656
|
-
import
|
|
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";
|
|
9269
|
+
init_manager2();
|
|
9270
|
+
import { Command as Command5 } from "commander";
|
|
9271
|
+
import inquirer2 from "inquirer";
|
|
9272
|
+
import chalk4 from "chalk";
|
|
8754
9273
|
function createSkillsCommand() {
|
|
8755
|
-
const skillsCommand = new
|
|
9274
|
+
const skillsCommand = new Command5("skills").description("Manage AI skills");
|
|
8756
9275
|
skillsCommand.command("list").description("List available skills").action(async () => {
|
|
8757
9276
|
const manager = SkillsManager.getInstance();
|
|
8758
9277
|
const skills = await manager.listSkills();
|
|
@@ -8769,7 +9288,7 @@ function createSkillsCommand() {
|
|
|
8769
9288
|
const settingsManager = getSettingsManager();
|
|
8770
9289
|
let description = options.description;
|
|
8771
9290
|
if (!description) {
|
|
8772
|
-
const answer = await
|
|
9291
|
+
const answer = await inquirer2.prompt([
|
|
8773
9292
|
{
|
|
8774
9293
|
type: "input",
|
|
8775
9294
|
name: "description",
|
|
@@ -8778,146 +9297,136 @@ function createSkillsCommand() {
|
|
|
8778
9297
|
]);
|
|
8779
9298
|
description = answer.description;
|
|
8780
9299
|
}
|
|
8781
|
-
console.log(
|
|
9300
|
+
console.log(chalk4.blue(`Generating skill '${name}' based on description: "${description}"...`));
|
|
8782
9301
|
const apiKey = settingsManager.getApiKey();
|
|
8783
9302
|
const baseURL = settingsManager.getBaseURL();
|
|
8784
9303
|
const model = settingsManager.getCurrentModel();
|
|
8785
9304
|
if (!apiKey) {
|
|
8786
|
-
console.error(
|
|
9305
|
+
console.error(chalk4.red("API Key not found. Please configure it first."));
|
|
8787
9306
|
return;
|
|
8788
9307
|
}
|
|
8789
9308
|
const agent = new SuperAgent(apiKey, baseURL, model);
|
|
8790
9309
|
await manager.createSkill(name, description, agent);
|
|
8791
|
-
console.log(
|
|
9310
|
+
console.log(chalk4.green(`✓ Skill '${name}' created successfully.`));
|
|
8792
9311
|
} catch (error) {
|
|
8793
|
-
console.error(
|
|
9312
|
+
console.error(chalk4.red(`Error creating skill: ${error.message}`));
|
|
8794
9313
|
}
|
|
8795
9314
|
});
|
|
8796
9315
|
skillsCommand.command("delete <name>").description("Delete a skill").action(async (name) => {
|
|
8797
9316
|
try {
|
|
8798
9317
|
const manager = SkillsManager.getInstance();
|
|
8799
9318
|
await manager.deleteSkill(name);
|
|
8800
|
-
console.log(
|
|
9319
|
+
console.log(chalk4.green(`✓ Skill '${name}' deleted.`));
|
|
8801
9320
|
} catch (error) {
|
|
8802
|
-
console.error(
|
|
9321
|
+
console.error(chalk4.red(`Error deleting skill: ${error.message}`));
|
|
8803
9322
|
}
|
|
8804
9323
|
});
|
|
8805
9324
|
return skillsCommand;
|
|
8806
9325
|
}
|
|
8807
9326
|
|
|
8808
|
-
// src/commands/
|
|
8809
|
-
init_settings_manager();
|
|
8810
|
-
|
|
8811
|
-
// src/agents/manager.ts
|
|
9327
|
+
// src/commands/import.ts
|
|
8812
9328
|
init_settings_manager();
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
|
|
8817
|
-
|
|
8818
|
-
|
|
8819
|
-
|
|
8820
|
-
|
|
8821
|
-
|
|
8822
|
-
|
|
8823
|
-
|
|
8824
|
-
|
|
9329
|
+
init_file_utils();
|
|
9330
|
+
init_manager2();
|
|
9331
|
+
init_manager();
|
|
9332
|
+
import { Command as Command6 } from "commander";
|
|
9333
|
+
import fs19 from "fs-extra";
|
|
9334
|
+
import chalk5 from "chalk";
|
|
9335
|
+
import path18 from "path";
|
|
9336
|
+
function createImportCommand() {
|
|
9337
|
+
const cmd = new Command6("import").description("Import resources from other AI assistants");
|
|
9338
|
+
cmd.command("agents <source>").description("Import agents from source (gemini, claude, kilo)").action(async (source) => {
|
|
9339
|
+
const sourcePath = resolveSourcePath(source);
|
|
9340
|
+
const agentsDir = path18.join(sourcePath, "agents");
|
|
9341
|
+
if (!await fs19.pathExists(agentsDir)) {
|
|
9342
|
+
console.error(chalk5.red(`Agents directory not found at ${agentsDir}`));
|
|
9343
|
+
return;
|
|
8825
9344
|
}
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
|
|
8835
|
-
|
|
8836
|
-
|
|
8837
|
-
|
|
8838
|
-
|
|
8839
|
-
|
|
8840
|
-
|
|
8841
|
-
|
|
8842
|
-
|
|
8843
|
-
|
|
9345
|
+
const files = await fs19.readdir(agentsDir);
|
|
9346
|
+
const manager = AgentsManager.getInstance();
|
|
9347
|
+
let count = 0;
|
|
9348
|
+
for (const file of files) {
|
|
9349
|
+
if (file.endsWith(".json")) {
|
|
9350
|
+
try {
|
|
9351
|
+
const content = await fs19.readJson(path18.join(agentsDir, file));
|
|
9352
|
+
const agentConfig = {
|
|
9353
|
+
name: content.name || path18.parse(file).name,
|
|
9354
|
+
role: content.role || "Assistant",
|
|
9355
|
+
description: content.description || "Imported agent",
|
|
9356
|
+
model: content.model,
|
|
9357
|
+
tools: content.tools,
|
|
9358
|
+
temperature: content.temperature,
|
|
9359
|
+
systemPrompt: content.systemPrompt || content.system_prompt || content.prompt
|
|
9360
|
+
};
|
|
9361
|
+
await manager.createAgent(agentConfig);
|
|
9362
|
+
console.log(chalk5.green(`Imported agent: ${agentConfig.name}`));
|
|
9363
|
+
count++;
|
|
9364
|
+
} catch (error) {
|
|
9365
|
+
console.warn(chalk5.yellow(`Failed to import ${file}: ${error.message}`));
|
|
8844
9366
|
}
|
|
8845
9367
|
}
|
|
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
9368
|
}
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
const
|
|
8862
|
-
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
|
|
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
|
|
9369
|
+
console.log(chalk5.bold(`Imported ${count} agents.`));
|
|
9370
|
+
});
|
|
9371
|
+
cmd.command("skills <source>").description("Import skills from source (gemini, claude, kilo)").action(async (source) => {
|
|
9372
|
+
const sourcePath = resolveSourcePath(source);
|
|
9373
|
+
const skillsDir = path18.join(sourcePath, "skills");
|
|
9374
|
+
if (!await fs19.pathExists(skillsDir)) {
|
|
9375
|
+
console.error(chalk5.red(`Skills directory not found at ${skillsDir}`));
|
|
9376
|
+
return;
|
|
8876
9377
|
}
|
|
8877
|
-
|
|
8878
|
-
|
|
8879
|
-
|
|
8880
|
-
|
|
8881
|
-
|
|
8882
|
-
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
|
|
8887
|
-
|
|
8888
|
-
|
|
8889
|
-
|
|
8890
|
-
}
|
|
9378
|
+
const files = await fs19.readdir(skillsDir);
|
|
9379
|
+
const manager = SkillsManager.getInstance();
|
|
9380
|
+
let count = 0;
|
|
9381
|
+
for (const file of files) {
|
|
9382
|
+
if (file.endsWith(".ts") || file.endsWith(".js")) {
|
|
9383
|
+
try {
|
|
9384
|
+
const content = await fs19.readFile(path18.join(skillsDir, file), "utf-8");
|
|
9385
|
+
const name = path18.parse(file).name;
|
|
9386
|
+
await manager.saveSkill(name, content);
|
|
9387
|
+
console.log(chalk5.green(`Imported skill: ${name}`));
|
|
9388
|
+
count++;
|
|
9389
|
+
} catch (error) {
|
|
9390
|
+
console.warn(chalk5.yellow(`Failed to import ${file}: ${error.message}`));
|
|
8891
9391
|
}
|
|
8892
9392
|
}
|
|
8893
9393
|
}
|
|
8894
|
-
|
|
8895
|
-
|
|
8896
|
-
|
|
8897
|
-
|
|
8898
|
-
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
|
|
8902
|
-
|
|
9394
|
+
console.log(chalk5.bold(`Imported ${count} skills.`));
|
|
9395
|
+
});
|
|
9396
|
+
cmd.command("hooks <source>").description("Import hooks from source settings").action(async (source) => {
|
|
9397
|
+
const sourcePath = resolveSourcePath(source);
|
|
9398
|
+
const settingsFile = source.toLowerCase() === "claude" ? "settings.local.json" : "settings.json";
|
|
9399
|
+
const fullPath = path18.join(sourcePath, settingsFile);
|
|
9400
|
+
if (!await fs19.pathExists(fullPath)) {
|
|
9401
|
+
console.error(chalk5.red(`Settings file not found at ${fullPath}`));
|
|
9402
|
+
return;
|
|
8903
9403
|
}
|
|
8904
|
-
}
|
|
8905
|
-
async deleteAgent(name) {
|
|
8906
9404
|
try {
|
|
8907
|
-
const
|
|
8908
|
-
|
|
9405
|
+
const settings = await fs19.readJson(fullPath);
|
|
9406
|
+
if (settings.hooks) {
|
|
9407
|
+
const manager = getSettingsManager();
|
|
9408
|
+
const currentHooks = manager.getUserSetting("hooks") || {};
|
|
9409
|
+
const mergedHooks = { ...currentHooks, ...settings.hooks };
|
|
9410
|
+
manager.updateUserSetting("hooks", mergedHooks);
|
|
9411
|
+
console.log(chalk5.green(`Imported ${Object.keys(settings.hooks).length} hooks.`));
|
|
9412
|
+
} else {
|
|
9413
|
+
console.log(chalk5.yellow("No hooks found in settings file."));
|
|
9414
|
+
}
|
|
8909
9415
|
} catch (error) {
|
|
8910
|
-
|
|
9416
|
+
console.error(chalk5.red(`Failed to import hooks: ${error.message}`));
|
|
8911
9417
|
}
|
|
8912
|
-
}
|
|
9418
|
+
});
|
|
9419
|
+
return cmd;
|
|
8913
9420
|
}
|
|
8914
9421
|
|
|
8915
9422
|
// src/commands/agents.ts
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
import
|
|
9423
|
+
init_settings_manager();
|
|
9424
|
+
init_manager();
|
|
9425
|
+
import { Command as Command7 } from "commander";
|
|
9426
|
+
import inquirer3 from "inquirer";
|
|
9427
|
+
import chalk6 from "chalk";
|
|
8919
9428
|
function createAgentsCommand() {
|
|
8920
|
-
const agentsCommand = new
|
|
9429
|
+
const agentsCommand = new Command7("agents").description("Manage AI agents");
|
|
8921
9430
|
agentsCommand.command("list").description("List available agents").action(async () => {
|
|
8922
9431
|
const manager = AgentsManager.getInstance();
|
|
8923
9432
|
const agents = await manager.listAgents();
|
|
@@ -8926,8 +9435,8 @@ function createAgentsCommand() {
|
|
|
8926
9435
|
} else {
|
|
8927
9436
|
console.log("Available agents:");
|
|
8928
9437
|
agents.forEach((agent) => {
|
|
8929
|
-
console.log(`- ${
|
|
8930
|
-
console.log(` ${
|
|
9438
|
+
console.log(`- ${chalk6.bold(agent.name)} (${agent.role})`);
|
|
9439
|
+
console.log(` ${chalk6.dim(agent.description)}`);
|
|
8931
9440
|
});
|
|
8932
9441
|
}
|
|
8933
9442
|
});
|
|
@@ -8937,7 +9446,7 @@ function createAgentsCommand() {
|
|
|
8937
9446
|
const settingsManager = getSettingsManager();
|
|
8938
9447
|
let description = options.description;
|
|
8939
9448
|
if (!description) {
|
|
8940
|
-
const answer = await
|
|
9449
|
+
const answer = await inquirer3.prompt([
|
|
8941
9450
|
{
|
|
8942
9451
|
type: "input",
|
|
8943
9452
|
name: "description",
|
|
@@ -8946,28 +9455,28 @@ function createAgentsCommand() {
|
|
|
8946
9455
|
]);
|
|
8947
9456
|
description = answer.description;
|
|
8948
9457
|
}
|
|
8949
|
-
console.log(
|
|
9458
|
+
console.log(chalk6.blue(`Generating agent configuration for '${name}'...`));
|
|
8950
9459
|
const apiKey = settingsManager.getApiKey();
|
|
8951
9460
|
const baseURL = settingsManager.getBaseURL();
|
|
8952
9461
|
const model = settingsManager.getCurrentModel();
|
|
8953
9462
|
if (!apiKey) {
|
|
8954
|
-
console.error(
|
|
9463
|
+
console.error(chalk6.red("API Key not found. Please configure it first."));
|
|
8955
9464
|
return;
|
|
8956
9465
|
}
|
|
8957
9466
|
const agent = new SuperAgent(apiKey, baseURL, model);
|
|
8958
9467
|
await manager.generateAgent(name, description, agent);
|
|
8959
|
-
console.log(
|
|
9468
|
+
console.log(chalk6.green(`✓ Agent '${name}' created successfully.`));
|
|
8960
9469
|
} catch (error) {
|
|
8961
|
-
console.error(
|
|
9470
|
+
console.error(chalk6.red(`Error creating agent: ${error.message}`));
|
|
8962
9471
|
}
|
|
8963
9472
|
});
|
|
8964
9473
|
agentsCommand.command("delete <name>").description("Delete an agent").action(async (name) => {
|
|
8965
9474
|
try {
|
|
8966
9475
|
const manager = AgentsManager.getInstance();
|
|
8967
9476
|
await manager.deleteAgent(name);
|
|
8968
|
-
console.log(
|
|
9477
|
+
console.log(chalk6.green(`✓ Agent '${name}' deleted.`));
|
|
8969
9478
|
} catch (error) {
|
|
8970
|
-
console.error(
|
|
9479
|
+
console.error(chalk6.red(`Error deleting agent: ${error.message}`));
|
|
8971
9480
|
}
|
|
8972
9481
|
});
|
|
8973
9482
|
return agentsCommand;
|
|
@@ -8975,37 +9484,37 @@ function createAgentsCommand() {
|
|
|
8975
9484
|
|
|
8976
9485
|
// src/commands/mcp.ts
|
|
8977
9486
|
init_config();
|
|
8978
|
-
import { Command as
|
|
8979
|
-
import
|
|
9487
|
+
import { Command as Command8 } from "commander";
|
|
9488
|
+
import chalk7 from "chalk";
|
|
8980
9489
|
function createMCPCommand() {
|
|
8981
|
-
const mcpCommand = new
|
|
9490
|
+
const mcpCommand = new Command8("mcp");
|
|
8982
9491
|
mcpCommand.description("Manage MCP (Model Context Protocol) servers");
|
|
8983
9492
|
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
9493
|
try {
|
|
8985
9494
|
if (PREDEFINED_SERVERS[name]) {
|
|
8986
9495
|
const config2 = PREDEFINED_SERVERS[name];
|
|
8987
9496
|
addMCPServer(config2);
|
|
8988
|
-
console.log(
|
|
9497
|
+
console.log(chalk7.green(`✓ Added predefined MCP server: ${name}`));
|
|
8989
9498
|
const manager2 = getMCPManager();
|
|
8990
9499
|
await manager2.addServer(config2);
|
|
8991
|
-
console.log(
|
|
9500
|
+
console.log(chalk7.green(`✓ Connected to MCP server: ${name}`));
|
|
8992
9501
|
const tools2 = manager2.getTools().filter((t) => t.serverName === name);
|
|
8993
|
-
console.log(
|
|
9502
|
+
console.log(chalk7.blue(` Available tools: ${tools2.length}`));
|
|
8994
9503
|
return;
|
|
8995
9504
|
}
|
|
8996
9505
|
const transportType = options.transport.toLowerCase();
|
|
8997
9506
|
if (transportType === "stdio") {
|
|
8998
9507
|
if (!options.command) {
|
|
8999
|
-
console.error(
|
|
9508
|
+
console.error(chalk7.red("Error: --command is required for stdio transport"));
|
|
9000
9509
|
process.exit(1);
|
|
9001
9510
|
}
|
|
9002
9511
|
} else if (transportType === "http" || transportType === "sse" || transportType === "streamable_http") {
|
|
9003
9512
|
if (!options.url) {
|
|
9004
|
-
console.error(
|
|
9513
|
+
console.error(chalk7.red(`Error: --url is required for ${transportType} transport`));
|
|
9005
9514
|
process.exit(1);
|
|
9006
9515
|
}
|
|
9007
9516
|
} else {
|
|
9008
|
-
console.error(
|
|
9517
|
+
console.error(chalk7.red("Error: Transport type must be stdio, http, sse, or streamable_http"));
|
|
9009
9518
|
process.exit(1);
|
|
9010
9519
|
}
|
|
9011
9520
|
const env = {};
|
|
@@ -9034,14 +9543,14 @@ function createMCPCommand() {
|
|
|
9034
9543
|
}
|
|
9035
9544
|
};
|
|
9036
9545
|
addMCPServer(config);
|
|
9037
|
-
console.log(
|
|
9546
|
+
console.log(chalk7.green(`✓ Added MCP server: ${name}`));
|
|
9038
9547
|
const manager = getMCPManager();
|
|
9039
9548
|
await manager.addServer(config);
|
|
9040
|
-
console.log(
|
|
9549
|
+
console.log(chalk7.green(`✓ Connected to MCP server: ${name}`));
|
|
9041
9550
|
const tools = manager.getTools().filter((t) => t.serverName === name);
|
|
9042
|
-
console.log(
|
|
9551
|
+
console.log(chalk7.blue(` Available tools: ${tools.length}`));
|
|
9043
9552
|
} catch (error) {
|
|
9044
|
-
console.error(
|
|
9553
|
+
console.error(chalk7.red(`Error adding MCP server: ${error.message}`));
|
|
9045
9554
|
process.exit(1);
|
|
9046
9555
|
}
|
|
9047
9556
|
});
|
|
@@ -9051,7 +9560,7 @@ function createMCPCommand() {
|
|
|
9051
9560
|
try {
|
|
9052
9561
|
config = JSON.parse(jsonConfig);
|
|
9053
9562
|
} catch (error) {
|
|
9054
|
-
console.error(
|
|
9563
|
+
console.error(chalk7.red("Error: Invalid JSON configuration"));
|
|
9055
9564
|
process.exit(1);
|
|
9056
9565
|
}
|
|
9057
9566
|
const serverConfig = {
|
|
@@ -9076,14 +9585,14 @@ function createMCPCommand() {
|
|
|
9076
9585
|
}
|
|
9077
9586
|
}
|
|
9078
9587
|
addMCPServer(serverConfig);
|
|
9079
|
-
console.log(
|
|
9588
|
+
console.log(chalk7.green(`✓ Added MCP server: ${name}`));
|
|
9080
9589
|
const manager = getMCPManager();
|
|
9081
9590
|
await manager.addServer(serverConfig);
|
|
9082
|
-
console.log(
|
|
9591
|
+
console.log(chalk7.green(`✓ Connected to MCP server: ${name}`));
|
|
9083
9592
|
const tools = manager.getTools().filter((t) => t.serverName === name);
|
|
9084
|
-
console.log(
|
|
9593
|
+
console.log(chalk7.blue(` Available tools: ${tools.length}`));
|
|
9085
9594
|
} catch (error) {
|
|
9086
|
-
console.error(
|
|
9595
|
+
console.error(chalk7.red(`Error adding MCP server: ${error.message}`));
|
|
9087
9596
|
process.exit(1);
|
|
9088
9597
|
}
|
|
9089
9598
|
});
|
|
@@ -9092,9 +9601,9 @@ function createMCPCommand() {
|
|
|
9092
9601
|
const manager = getMCPManager();
|
|
9093
9602
|
await manager.removeServer(name);
|
|
9094
9603
|
removeMCPServer(name);
|
|
9095
|
-
console.log(
|
|
9604
|
+
console.log(chalk7.green(`✓ Removed MCP server: ${name}`));
|
|
9096
9605
|
} catch (error) {
|
|
9097
|
-
console.error(
|
|
9606
|
+
console.error(chalk7.red(`Error removing MCP server: ${error.message}`));
|
|
9098
9607
|
process.exit(1);
|
|
9099
9608
|
}
|
|
9100
9609
|
});
|
|
@@ -9102,15 +9611,15 @@ function createMCPCommand() {
|
|
|
9102
9611
|
const config = loadMCPConfig();
|
|
9103
9612
|
const manager = getMCPManager();
|
|
9104
9613
|
if (config.servers.length === 0) {
|
|
9105
|
-
console.log(
|
|
9614
|
+
console.log(chalk7.yellow("No MCP servers configured"));
|
|
9106
9615
|
return;
|
|
9107
9616
|
}
|
|
9108
|
-
console.log(
|
|
9617
|
+
console.log(chalk7.bold("Configured MCP servers:"));
|
|
9109
9618
|
console.log();
|
|
9110
9619
|
for (const server of config.servers) {
|
|
9111
9620
|
const isConnected = manager.getServers().includes(server.name);
|
|
9112
|
-
const status = isConnected ?
|
|
9113
|
-
console.log(`${
|
|
9621
|
+
const status = isConnected ? chalk7.green("✓ Connected") : chalk7.red("✗ Disconnected");
|
|
9622
|
+
console.log(`${chalk7.bold(server.name)}: ${status}`);
|
|
9114
9623
|
if (server.transport) {
|
|
9115
9624
|
console.log(` Transport: ${server.transport.type}`);
|
|
9116
9625
|
if (server.transport.type === "stdio") {
|
|
@@ -9143,15 +9652,15 @@ function createMCPCommand() {
|
|
|
9143
9652
|
const config = loadMCPConfig();
|
|
9144
9653
|
const serverConfig = config.servers.find((s) => s.name === name);
|
|
9145
9654
|
if (!serverConfig) {
|
|
9146
|
-
console.error(
|
|
9655
|
+
console.error(chalk7.red(`Server ${name} not found`));
|
|
9147
9656
|
process.exit(1);
|
|
9148
9657
|
}
|
|
9149
|
-
console.log(
|
|
9658
|
+
console.log(chalk7.blue(`Testing connection to ${name}...`));
|
|
9150
9659
|
const manager = getMCPManager();
|
|
9151
9660
|
await manager.addServer(serverConfig);
|
|
9152
9661
|
const tools = manager.getTools().filter((t) => t.serverName === name);
|
|
9153
|
-
console.log(
|
|
9154
|
-
console.log(
|
|
9662
|
+
console.log(chalk7.green(`✓ Successfully connected to ${name}`));
|
|
9663
|
+
console.log(chalk7.blue(` Available tools: ${tools.length}`));
|
|
9155
9664
|
if (tools.length > 0) {
|
|
9156
9665
|
console.log(" Tools:");
|
|
9157
9666
|
tools.forEach((tool) => {
|
|
@@ -9160,7 +9669,7 @@ function createMCPCommand() {
|
|
|
9160
9669
|
});
|
|
9161
9670
|
}
|
|
9162
9671
|
} catch (error) {
|
|
9163
|
-
console.error(
|
|
9672
|
+
console.error(chalk7.red(`✗ Failed to connect to ${name}: ${error.message}`));
|
|
9164
9673
|
process.exit(1);
|
|
9165
9674
|
}
|
|
9166
9675
|
});
|
|
@@ -9169,7 +9678,7 @@ function createMCPCommand() {
|
|
|
9169
9678
|
|
|
9170
9679
|
// src/commands/git.ts
|
|
9171
9680
|
init_settings_manager();
|
|
9172
|
-
import { Command as
|
|
9681
|
+
import { Command as Command9 } from "commander";
|
|
9173
9682
|
async function loadApiKey() {
|
|
9174
9683
|
const manager = getSettingsManager();
|
|
9175
9684
|
return manager.getApiKey();
|
|
@@ -9273,7 +9782,7 @@ Respond with ONLY the commit message, no additional text.`;
|
|
|
9273
9782
|
}
|
|
9274
9783
|
}
|
|
9275
9784
|
function createGitCommand() {
|
|
9276
|
-
const gitCommand = new
|
|
9785
|
+
const gitCommand = new Command9("git").description("Git operations with AI assistance");
|
|
9277
9786
|
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
9787
|
if (options.directory) {
|
|
9279
9788
|
try {
|
|
@@ -9313,6 +9822,8 @@ function registerCommands(program) {
|
|
|
9313
9822
|
program.addCommand(createServeCommand());
|
|
9314
9823
|
program.addCommand(createSkillsCommand());
|
|
9315
9824
|
program.addCommand(createAgentsCommand());
|
|
9825
|
+
program.addCommand(createImportCommand());
|
|
9826
|
+
program.addCommand(createProviderCommand());
|
|
9316
9827
|
program.addCommand(createIndexCommand());
|
|
9317
9828
|
}
|
|
9318
9829
|
|