@stan-chen/simple-cli 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +62 -63
  2. package/dist/anyllm.py +62 -0
  3. package/dist/builtins.d.ts +726 -0
  4. package/dist/builtins.js +481 -0
  5. package/dist/cli.d.ts +0 -4
  6. package/dist/cli.js +34 -493
  7. package/dist/engine.d.ts +33 -0
  8. package/dist/engine.js +138 -0
  9. package/dist/learnings.d.ts +15 -0
  10. package/dist/learnings.js +54 -0
  11. package/dist/llm.d.ts +18 -0
  12. package/dist/llm.js +73 -0
  13. package/dist/mcp.d.ts +132 -0
  14. package/dist/mcp.js +43 -0
  15. package/dist/skills.d.ts +5 -16
  16. package/dist/skills.js +91 -253
  17. package/dist/tui.d.ts +1 -0
  18. package/dist/tui.js +15 -0
  19. package/package.json +10 -6
  20. package/dist/claw/jit.d.ts +0 -5
  21. package/dist/claw/jit.js +0 -138
  22. package/dist/claw/management.d.ts +0 -3
  23. package/dist/claw/management.js +0 -107
  24. package/dist/commands/add.d.ts +0 -9
  25. package/dist/commands/add.js +0 -50
  26. package/dist/commands/git/commit.d.ts +0 -12
  27. package/dist/commands/git/commit.js +0 -98
  28. package/dist/commands/git/status.d.ts +0 -6
  29. package/dist/commands/git/status.js +0 -42
  30. package/dist/commands/index.d.ts +0 -16
  31. package/dist/commands/index.js +0 -377
  32. package/dist/commands/mcp/status.d.ts +0 -6
  33. package/dist/commands/mcp/status.js +0 -31
  34. package/dist/commands/swarm.d.ts +0 -36
  35. package/dist/commands/swarm.js +0 -236
  36. package/dist/commands.d.ts +0 -32
  37. package/dist/commands.js +0 -427
  38. package/dist/context.d.ts +0 -116
  39. package/dist/context.js +0 -337
  40. package/dist/index.d.ts +0 -6
  41. package/dist/index.js +0 -109
  42. package/dist/lib/agent.d.ts +0 -99
  43. package/dist/lib/agent.js +0 -313
  44. package/dist/lib/editor.d.ts +0 -74
  45. package/dist/lib/editor.js +0 -441
  46. package/dist/lib/git.d.ts +0 -164
  47. package/dist/lib/git.js +0 -356
  48. package/dist/lib/shim.d.ts +0 -4
  49. package/dist/lib/shim.js +0 -30
  50. package/dist/lib/ui.d.ts +0 -159
  51. package/dist/lib/ui.js +0 -277
  52. package/dist/mcp/client.d.ts +0 -22
  53. package/dist/mcp/client.js +0 -81
  54. package/dist/mcp/manager.d.ts +0 -186
  55. package/dist/mcp/manager.js +0 -446
  56. package/dist/prompts/provider.d.ts +0 -22
  57. package/dist/prompts/provider.js +0 -79
  58. package/dist/providers/index.d.ts +0 -31
  59. package/dist/providers/index.js +0 -93
  60. package/dist/providers/multi.d.ts +0 -12
  61. package/dist/providers/multi.js +0 -28
  62. package/dist/registry.d.ts +0 -29
  63. package/dist/registry.js +0 -443
  64. package/dist/repoMap.d.ts +0 -5
  65. package/dist/repoMap.js +0 -79
  66. package/dist/router.d.ts +0 -41
  67. package/dist/router.js +0 -118
  68. package/dist/swarm/coordinator.d.ts +0 -86
  69. package/dist/swarm/coordinator.js +0 -257
  70. package/dist/swarm/index.d.ts +0 -28
  71. package/dist/swarm/index.js +0 -29
  72. package/dist/swarm/task.d.ts +0 -104
  73. package/dist/swarm/task.js +0 -221
  74. package/dist/swarm/types.d.ts +0 -132
  75. package/dist/swarm/types.js +0 -37
  76. package/dist/swarm/worker.d.ts +0 -109
  77. package/dist/swarm/worker.js +0 -369
  78. package/dist/tools/analyzeFile.d.ts +0 -16
  79. package/dist/tools/analyzeFile.js +0 -43
  80. package/dist/tools/analyze_file.d.ts +0 -16
  81. package/dist/tools/analyze_file.js +0 -43
  82. package/dist/tools/clawBrain.d.ts +0 -23
  83. package/dist/tools/clawBrain.js +0 -136
  84. package/dist/tools/claw_brain.d.ts +0 -23
  85. package/dist/tools/claw_brain.js +0 -139
  86. package/dist/tools/deleteFile.d.ts +0 -19
  87. package/dist/tools/deleteFile.js +0 -36
  88. package/dist/tools/delete_file.d.ts +0 -19
  89. package/dist/tools/delete_file.js +0 -36
  90. package/dist/tools/fileOps.d.ts +0 -22
  91. package/dist/tools/fileOps.js +0 -43
  92. package/dist/tools/file_ops.d.ts +0 -22
  93. package/dist/tools/file_ops.js +0 -43
  94. package/dist/tools/git.d.ts +0 -40
  95. package/dist/tools/git.js +0 -236
  96. package/dist/tools/glob.d.ts +0 -34
  97. package/dist/tools/glob.js +0 -165
  98. package/dist/tools/grep.d.ts +0 -53
  99. package/dist/tools/grep.js +0 -296
  100. package/dist/tools/linter.d.ts +0 -35
  101. package/dist/tools/linter.js +0 -407
  102. package/dist/tools/listDir.d.ts +0 -29
  103. package/dist/tools/listDir.js +0 -50
  104. package/dist/tools/list_dir.d.ts +0 -29
  105. package/dist/tools/list_dir.js +0 -50
  106. package/dist/tools/memory.d.ts +0 -34
  107. package/dist/tools/memory.js +0 -215
  108. package/dist/tools/organizer.d.ts +0 -1
  109. package/dist/tools/organizer.js +0 -65
  110. package/dist/tools/readFiles.d.ts +0 -25
  111. package/dist/tools/readFiles.js +0 -31
  112. package/dist/tools/read_files.d.ts +0 -25
  113. package/dist/tools/read_files.js +0 -31
  114. package/dist/tools/reloadTools.d.ts +0 -11
  115. package/dist/tools/reloadTools.js +0 -22
  116. package/dist/tools/reload_tools.d.ts +0 -11
  117. package/dist/tools/reload_tools.js +0 -22
  118. package/dist/tools/runCommand.d.ts +0 -32
  119. package/dist/tools/runCommand.js +0 -79
  120. package/dist/tools/run_command.d.ts +0 -32
  121. package/dist/tools/run_command.js +0 -103
  122. package/dist/tools/scheduler.d.ts +0 -25
  123. package/dist/tools/scheduler.js +0 -65
  124. package/dist/tools/scraper.d.ts +0 -31
  125. package/dist/tools/scraper.js +0 -211
  126. package/dist/tools/writeFiles.d.ts +0 -63
  127. package/dist/tools/writeFiles.js +0 -87
  128. package/dist/tools/write_files.d.ts +0 -84
  129. package/dist/tools/write_files.js +0 -91
  130. package/dist/tools/write_to_file.d.ts +0 -15
  131. package/dist/tools/write_to_file.js +0 -21
  132. package/dist/ui/server.d.ts +0 -5
  133. package/dist/ui/server.js +0 -74
  134. package/dist/watcher.d.ts +0 -35
  135. package/dist/watcher.js +0 -164
  136. /package/{docs/assets → assets}/logo.jpeg +0 -0
package/dist/engine.js ADDED
@@ -0,0 +1,138 @@
1
+ import { readdir } from 'fs/promises';
2
+ import { existsSync } from 'fs';
3
+ import { join, relative } from 'path';
4
+ import { pathToFileURL } from 'url';
5
+ import pc from 'picocolors';
6
+ import { text, isCancel } from '@clack/prompts';
7
+ import { LearningManager } from './learnings.js';
8
+ async function getRepoMap(cwd) {
9
+ const files = [];
10
+ async function walk(dir) {
11
+ const entries = await readdir(dir, { withFileTypes: true });
12
+ for (const e of entries) {
13
+ if (['node_modules', '.git', 'dist'].includes(e.name))
14
+ continue;
15
+ const res = join(dir, e.name);
16
+ if (e.isDirectory())
17
+ await walk(res);
18
+ else if (['.ts', '.js', '.py', '.md'].includes(res.slice(-3)))
19
+ files.push(relative(cwd, res));
20
+ }
21
+ }
22
+ try {
23
+ await walk(cwd);
24
+ }
25
+ catch { }
26
+ return files.slice(0, 50).join('\n');
27
+ }
28
+ export class Context {
29
+ history = [];
30
+ activeFiles = new Set();
31
+ cwd;
32
+ skill;
33
+ constructor(cwd, skill) {
34
+ this.cwd = cwd;
35
+ this.skill = skill;
36
+ }
37
+ async buildPrompt(tools) {
38
+ const repoMap = await getRepoMap(this.cwd);
39
+ const toolDefs = Array.from(tools.values()).map(t => `- ${t.name}: ${t.description}`).join('\n');
40
+ return `${this.skill.systemPrompt}\n\n## Tools\n${toolDefs}\n\n## Repository\n${repoMap}\n\n## Active Files\n${Array.from(this.activeFiles).map(f => relative(this.cwd, f)).join(', ')}`;
41
+ }
42
+ }
43
+ export class Registry {
44
+ tools = new Map();
45
+ async loadProjectTools(cwd) {
46
+ const dir = join(cwd, '.agent', 'tools');
47
+ if (!existsSync(dir))
48
+ return;
49
+ for (const f of await readdir(dir)) {
50
+ if (f.endsWith('.ts') || f.endsWith('.js')) {
51
+ const mod = await import(pathToFileURL(join(dir, f)).href);
52
+ const t = mod.tool || mod.default;
53
+ if (t?.name)
54
+ this.tools.set(t.name, t);
55
+ }
56
+ }
57
+ }
58
+ }
59
+ export class Engine {
60
+ llm;
61
+ registry;
62
+ mcp;
63
+ learningManager;
64
+ constructor(llm, registry, mcp) {
65
+ this.llm = llm;
66
+ this.registry = registry;
67
+ this.mcp = mcp;
68
+ this.learningManager = new LearningManager(process.cwd());
69
+ }
70
+ async run(ctx, initialPrompt, options = { interactive: true }) {
71
+ await this.learningManager.load();
72
+ let input = initialPrompt;
73
+ await this.mcp.init();
74
+ (await this.mcp.getTools()).forEach(t => this.registry.tools.set(t.name, t));
75
+ // Ensure tools are loaded for the context cwd
76
+ await this.registry.loadProjectTools(ctx.cwd);
77
+ while (true) {
78
+ if (!input) {
79
+ if (!options.interactive)
80
+ break;
81
+ const res = await text({ message: pc.cyan('Chat') });
82
+ if (isCancel(res))
83
+ break;
84
+ input = res;
85
+ }
86
+ ctx.history.push({ role: 'user', content: input });
87
+ // RAG: Inject learnings
88
+ let prompt = await ctx.buildPrompt(this.registry.tools);
89
+ const userHistory = ctx.history.filter(m => m.role === 'user' && !['Continue.', 'Fix the error.'].includes(m.content));
90
+ const lastUserMsg = userHistory[userHistory.length - 1]?.content || '';
91
+ const query = (input && !['Continue.', 'Fix the error.'].includes(input)) ? input : lastUserMsg;
92
+ const learnings = await this.learningManager.search(query);
93
+ if (learnings.length > 0) {
94
+ prompt += `\n\n## Past Learnings\n${learnings.map(l => `- ${l}`).join('\n')}`;
95
+ }
96
+ const response = await this.llm.generate(prompt, ctx.history);
97
+ const { thought, tool, args, message } = response;
98
+ if (thought)
99
+ console.log(pc.dim(`💭 ${thought}`));
100
+ if (tool && tool !== 'none') {
101
+ const t = this.registry.tools.get(tool);
102
+ if (t) {
103
+ console.log(pc.yellow(`⚙ Executing ${tool}...`));
104
+ try {
105
+ const result = await t.execute(args);
106
+ // Reload tools if create_tool was used
107
+ if (tool === 'create_tool') {
108
+ await this.registry.loadProjectTools(ctx.cwd);
109
+ console.log(pc.magenta('🔄 Tools reloaded.'));
110
+ }
111
+ ctx.history.push({ role: 'assistant', content: JSON.stringify(response) });
112
+ ctx.history.push({ role: 'user', content: `Result: ${JSON.stringify(result)}` });
113
+ // Reflection: Learning loop
114
+ const reflectPrompt = "Analyze the previous tool execution. What went well? What failed? Summarize as a concise learning point for future reference.";
115
+ const reflection = await this.llm.generate(reflectPrompt, [...ctx.history, { role: 'user', content: reflectPrompt }]);
116
+ if (reflection.message) {
117
+ // Find the relevant task description
118
+ const userHistory = ctx.history.filter(m => m.role === 'user' && !['Continue.', 'Fix the error.'].includes(m.content));
119
+ const task = (input && !['Continue.', 'Fix the error.'].includes(input)) ? input : (userHistory[userHistory.length - 1]?.content || 'Task');
120
+ await this.learningManager.add(task, reflection.message);
121
+ console.log(pc.blue(`📝 Learning stored: ${reflection.message}`));
122
+ }
123
+ input = 'The previous tool execution was successful. Proceed with the next step.';
124
+ continue;
125
+ }
126
+ catch (e) {
127
+ ctx.history.push({ role: 'user', content: `Error: ${e.message}` });
128
+ input = 'Fix the error.';
129
+ continue;
130
+ }
131
+ }
132
+ }
133
+ console.log(`\n${pc.green('🤖')} ${message || response.raw}\n`);
134
+ ctx.history.push({ role: 'assistant', content: message || response.raw });
135
+ input = undefined;
136
+ }
137
+ }
138
+ }
@@ -0,0 +1,15 @@
1
+ export interface Learning {
2
+ id: string;
3
+ task: string;
4
+ reflection: string;
5
+ timestamp: number;
6
+ }
7
+ export declare class LearningManager {
8
+ private learnings;
9
+ private path;
10
+ constructor(cwd: string);
11
+ load(): Promise<void>;
12
+ save(): Promise<void>;
13
+ add(task: string, reflection: string): Promise<void>;
14
+ search(query: string): Promise<string[]>;
15
+ }
@@ -0,0 +1,54 @@
1
+ import { readFile, writeFile } from 'fs/promises';
2
+ import { existsSync, mkdirSync } from 'fs';
3
+ import { join } from 'path';
4
+ export class LearningManager {
5
+ learnings = [];
6
+ path;
7
+ constructor(cwd) {
8
+ const agentDir = join(cwd, '.agent');
9
+ if (!existsSync(agentDir)) {
10
+ try {
11
+ mkdirSync(agentDir, { recursive: true });
12
+ }
13
+ catch { }
14
+ }
15
+ this.path = join(agentDir, 'learnings.json');
16
+ }
17
+ async load() {
18
+ if (!existsSync(this.path))
19
+ return;
20
+ try {
21
+ const data = await readFile(this.path, 'utf-8');
22
+ this.learnings = JSON.parse(data);
23
+ }
24
+ catch {
25
+ this.learnings = [];
26
+ }
27
+ }
28
+ async save() {
29
+ await writeFile(this.path, JSON.stringify(this.learnings, null, 2));
30
+ }
31
+ async add(task, reflection) {
32
+ this.learnings.push({
33
+ id: Date.now().toString(),
34
+ task,
35
+ reflection,
36
+ timestamp: Date.now()
37
+ });
38
+ await this.save();
39
+ }
40
+ async search(query) {
41
+ if (!query)
42
+ return [];
43
+ const keywords = query.toLowerCase().split(/\s+/).filter(w => w.length > 3);
44
+ if (keywords.length === 0)
45
+ return [];
46
+ return this.learnings
47
+ .filter(l => {
48
+ const text = (l.task + ' ' + l.reflection).toLowerCase();
49
+ return keywords.some(k => text.includes(k));
50
+ })
51
+ .map(l => l.reflection)
52
+ .slice(0, 5);
53
+ }
54
+ }
package/dist/llm.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ export interface LLMResponse {
2
+ thought: string;
3
+ tool: string;
4
+ args: any;
5
+ message?: string;
6
+ raw: string;
7
+ }
8
+ export declare class LLM {
9
+ private config;
10
+ constructor(config: {
11
+ provider: string;
12
+ model: string;
13
+ apiKey?: string;
14
+ });
15
+ generate(system: string, history: any[]): Promise<LLMResponse>;
16
+ private parse;
17
+ }
18
+ export declare const createLLM: (model?: string) => LLM;
package/dist/llm.js ADDED
@@ -0,0 +1,73 @@
1
+ import { spawn } from 'child_process';
2
+ import { dirname, join } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import { jsonrepair } from 'jsonrepair';
5
+ import fs from 'fs';
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ export class LLM {
8
+ config;
9
+ constructor(config) {
10
+ this.config = config;
11
+ }
12
+ async generate(system, history) {
13
+ const payload = {
14
+ ...this.config,
15
+ messages: [{ role: 'system', content: system }, ...history],
16
+ api_key: this.config.apiKey || process.env.OPENAI_API_KEY || process.env.GEMINI_API_KEY || process.env.ANTHROPIC_API_KEY
17
+ };
18
+ return new Promise((resolve, reject) => {
19
+ // Find python bridge
20
+ let py = join(__dirname, 'anyllm.py');
21
+ if (!fs.existsSync(py))
22
+ py = join(process.cwd(), 'src/lib/anyllm.py'); // Fallback
23
+ // Try to find a working python command
24
+ const getPyCmd = () => {
25
+ const isWin = process.platform === 'win32';
26
+ // On Windows, preferred is 'python' or 'py' if they aren't store aliases
27
+ // On Linux/Mac, preferred is 'python3'
28
+ return isWin ? 'python' : 'python3';
29
+ };
30
+ const child = spawn(getPyCmd(), [py]);
31
+ let out = '';
32
+ let err = '';
33
+ child.stdout.on('data', d => out += d);
34
+ child.stderr.on('data', d => err += d);
35
+ child.on('close', code => {
36
+ if (code !== 0)
37
+ return reject(new Error(err));
38
+ try {
39
+ const res = JSON.parse(out);
40
+ if (res.error)
41
+ return reject(new Error(res.error));
42
+ resolve(this.parse(res.content));
43
+ }
44
+ catch (e) {
45
+ reject(e);
46
+ }
47
+ });
48
+ child.stdin.write(JSON.stringify(payload));
49
+ child.stdin.end();
50
+ });
51
+ }
52
+ parse(raw) {
53
+ try {
54
+ const repaired = jsonrepair(raw.trim().match(/\{[\s\S]*\}/)?.[0] || raw);
55
+ const p = JSON.parse(repaired);
56
+ return {
57
+ thought: p.thought || '',
58
+ tool: (p.tool || p.command || 'none').toLowerCase(),
59
+ args: p.args || p.parameters || {},
60
+ message: p.message || '',
61
+ raw
62
+ };
63
+ }
64
+ catch {
65
+ return { thought: '', tool: 'none', args: {}, message: raw, raw };
66
+ }
67
+ }
68
+ }
69
+ export const createLLM = (model) => {
70
+ const m = model || process.env.MODEL || 'openai:gpt-5.2-codex';
71
+ const [p, n] = m.includes(':') ? m.split(':') : ['openai', m];
72
+ return new LLM({ provider: p, model: n });
73
+ };
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,132 @@
1
+ export declare class MCP {
2
+ private clients;
3
+ init(): Promise<void>;
4
+ getTools(): Promise<{
5
+ execute: (args: any) => Promise<{
6
+ [x: string]: unknown;
7
+ content: ({
8
+ type: "text";
9
+ text: string;
10
+ annotations?: {
11
+ audience?: ("user" | "assistant")[] | undefined;
12
+ priority?: number | undefined;
13
+ lastModified?: string | undefined;
14
+ } | undefined;
15
+ _meta?: Record<string, unknown> | undefined;
16
+ } | {
17
+ type: "image";
18
+ data: string;
19
+ mimeType: string;
20
+ annotations?: {
21
+ audience?: ("user" | "assistant")[] | undefined;
22
+ priority?: number | undefined;
23
+ lastModified?: string | undefined;
24
+ } | undefined;
25
+ _meta?: Record<string, unknown> | undefined;
26
+ } | {
27
+ type: "audio";
28
+ data: string;
29
+ mimeType: string;
30
+ annotations?: {
31
+ audience?: ("user" | "assistant")[] | undefined;
32
+ priority?: number | undefined;
33
+ lastModified?: string | undefined;
34
+ } | undefined;
35
+ _meta?: Record<string, unknown> | undefined;
36
+ } | {
37
+ type: "resource";
38
+ resource: {
39
+ uri: string;
40
+ text: string;
41
+ mimeType?: string | undefined;
42
+ _meta?: Record<string, unknown> | undefined;
43
+ } | {
44
+ uri: string;
45
+ blob: string;
46
+ mimeType?: string | undefined;
47
+ _meta?: Record<string, unknown> | undefined;
48
+ };
49
+ annotations?: {
50
+ audience?: ("user" | "assistant")[] | undefined;
51
+ priority?: number | undefined;
52
+ lastModified?: string | undefined;
53
+ } | undefined;
54
+ _meta?: Record<string, unknown> | undefined;
55
+ } | {
56
+ uri: string;
57
+ name: string;
58
+ type: "resource_link";
59
+ description?: string | undefined;
60
+ mimeType?: string | undefined;
61
+ annotations?: {
62
+ audience?: ("user" | "assistant")[] | undefined;
63
+ priority?: number | undefined;
64
+ lastModified?: string | undefined;
65
+ } | undefined;
66
+ _meta?: {
67
+ [x: string]: unknown;
68
+ } | undefined;
69
+ icons?: {
70
+ src: string;
71
+ mimeType?: string | undefined;
72
+ sizes?: string[] | undefined;
73
+ theme?: "light" | "dark" | undefined;
74
+ }[] | undefined;
75
+ title?: string | undefined;
76
+ })[];
77
+ _meta?: {
78
+ [x: string]: unknown;
79
+ progressToken?: string | number | undefined;
80
+ "io.modelcontextprotocol/related-task"?: {
81
+ taskId: string;
82
+ } | undefined;
83
+ } | undefined;
84
+ structuredContent?: Record<string, unknown> | undefined;
85
+ isError?: boolean | undefined;
86
+ } | {
87
+ [x: string]: unknown;
88
+ toolResult: unknown;
89
+ _meta?: {
90
+ [x: string]: unknown;
91
+ progressToken?: string | number | undefined;
92
+ "io.modelcontextprotocol/related-task"?: {
93
+ taskId: string;
94
+ } | undefined;
95
+ } | undefined;
96
+ }>;
97
+ source: "mcp";
98
+ server: string;
99
+ inputSchema: {
100
+ [x: string]: unknown;
101
+ type: "object";
102
+ properties?: Record<string, object> | undefined;
103
+ required?: string[] | undefined;
104
+ };
105
+ name: string;
106
+ description?: string | undefined;
107
+ outputSchema?: {
108
+ [x: string]: unknown;
109
+ type: "object";
110
+ properties?: Record<string, object> | undefined;
111
+ required?: string[] | undefined;
112
+ } | undefined;
113
+ annotations?: {
114
+ title?: string | undefined;
115
+ readOnlyHint?: boolean | undefined;
116
+ destructiveHint?: boolean | undefined;
117
+ idempotentHint?: boolean | undefined;
118
+ openWorldHint?: boolean | undefined;
119
+ } | undefined;
120
+ execution?: {
121
+ taskSupport?: "optional" | "required" | "forbidden" | undefined;
122
+ } | undefined;
123
+ _meta?: Record<string, unknown> | undefined;
124
+ icons?: {
125
+ src: string;
126
+ mimeType?: string | undefined;
127
+ sizes?: string[] | undefined;
128
+ theme?: "light" | "dark" | undefined;
129
+ }[] | undefined;
130
+ title?: string | undefined;
131
+ }[]>;
132
+ }
package/dist/mcp.js ADDED
@@ -0,0 +1,43 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3
+ import { existsSync, readFileSync } from 'fs';
4
+ import { join } from 'path';
5
+ export class MCP {
6
+ clients = new Map();
7
+ async init() {
8
+ const configPath = join(process.cwd(), 'mcp.json');
9
+ if (!existsSync(configPath))
10
+ return;
11
+ const config = JSON.parse(readFileSync(configPath, 'utf-8'));
12
+ const servers = config.mcpServers || config.servers || {};
13
+ for (const [name, cfg] of Object.entries(servers)) {
14
+ try {
15
+ const client = new Client({ name: 'simple-cli', version: '1.0.0' }, { capabilities: {} });
16
+ const transport = new StdioClientTransport({
17
+ command: cfg.command,
18
+ args: cfg.args || [],
19
+ env: { ...process.env, ...(cfg.env || {}) }
20
+ });
21
+ await client.connect(transport);
22
+ this.clients.set(name, client);
23
+ console.log(`✓ Connected to MCP: ${name}`);
24
+ }
25
+ catch (e) {
26
+ console.error(`✗ Failed to connect to MCP ${name}:`, e);
27
+ }
28
+ }
29
+ }
30
+ async getTools() {
31
+ const all = [];
32
+ for (const [name, client] of this.clients) {
33
+ const { tools } = await client.listTools();
34
+ all.push(...tools.map(t => ({
35
+ ...t,
36
+ execute: (args) => client.callTool({ name: t.name, arguments: args }),
37
+ source: 'mcp',
38
+ server: name
39
+ })));
40
+ }
41
+ return all;
42
+ }
43
+ }
package/dist/skills.d.ts CHANGED
@@ -1,25 +1,14 @@
1
- /**
2
- * Skills/Presets System
3
- * Based on OpenHands skills and Aider prompts
4
- * Provides specialized behavior presets for different tasks
5
- */
6
1
  export interface Skill {
7
2
  name: string;
8
- description: string;
3
+ description?: string;
9
4
  systemPrompt: string;
10
5
  tools?: string[];
11
- modelPreference?: string;
12
- autoActions?: string[];
13
6
  }
14
7
  export declare const builtinSkills: Record<string, Skill>;
15
- export declare function getActiveSkill(): Skill;
8
+ export declare function loadSkillFromFile(path: string): Promise<Skill | null>;
9
+ export declare function getActiveSkill(cwd?: string): Promise<Skill>;
16
10
  export declare function setActiveSkill(name: string): Skill | undefined;
17
11
  export declare function listSkills(): Skill[];
18
- export declare function loadSkillFromFile(path: string): Promise<Skill | null>;
19
- export declare function saveSkillToFile(skill: Skill, path: string): Promise<void>;
20
12
  export declare function loadCustomSkills(dir: string): Promise<Record<string, Skill>>;
21
- export declare function buildSkillPrompt(skill: Skill, context?: {
22
- files?: string[];
23
- repoMap?: string;
24
- history?: string;
25
- }): string;
13
+ export declare function buildSkillPrompt(skill: Skill, context?: any): string;
14
+ export declare function saveSkillToFile(skill: Skill, path: string): Promise<void>;