@stan-chen/simple-cli 0.2.3 → 0.2.4

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 +66 -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 +10 -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
@@ -1,446 +0,0 @@
1
- /**
2
- * MCP Client Manager - Manages multiple MCP server connections
3
- * Supports Composio, custom MCP servers, and dynamic tool discovery
4
- * Based on GeminiCLI's mcp-client.ts patterns
5
- */
6
- import { Client } from '@modelcontextprotocol/sdk/client/index.js';
7
- import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
8
- import { z } from 'zod';
9
- import { existsSync, readFileSync } from 'fs';
10
- import { join } from 'path';
11
- // MCP Server Configuration Schema
12
- export const MCPServerConfigSchema = z.object({
13
- name: z.string(),
14
- command: z.string().optional(),
15
- args: z.array(z.string()).optional(),
16
- env: z.record(z.string()).optional(),
17
- url: z.string().optional(),
18
- type: z.enum(['stdio', 'sse', 'http']).optional(),
19
- timeout: z.number().optional(),
20
- trust: z.enum(['full', 'partial', 'none']).optional(),
21
- enabled: z.boolean().optional().default(true),
22
- });
23
- // Server Status
24
- export var MCPServerStatus;
25
- (function (MCPServerStatus) {
26
- MCPServerStatus["DISCONNECTED"] = "disconnected";
27
- MCPServerStatus["CONNECTING"] = "connecting";
28
- MCPServerStatus["CONNECTED"] = "connected";
29
- MCPServerStatus["ERROR"] = "error";
30
- })(MCPServerStatus || (MCPServerStatus = {}));
31
- /**
32
- * MCP Client Manager
33
- * Manages connections to multiple MCP servers and aggregates their tools
34
- */
35
- export class MCPManager {
36
- servers = new Map();
37
- onStatusChange;
38
- constructor(options) {
39
- this.onStatusChange = options?.onStatusChange;
40
- }
41
- /**
42
- * Load MCP configuration from all available sources
43
- */
44
- async loadConfig(configPath) {
45
- const allConfigs = [];
46
- const sources = [
47
- { path: configPath, type: 'file' },
48
- { path: join(process.cwd(), 'mcp.json'), type: 'file' },
49
- { path: join(process.cwd(), '.mcp.json'), type: 'file' },
50
- { path: join(process.cwd(), 'mcp'), type: 'dir' },
51
- { path: join(process.env.HOME || '', '.config', 'simplecli', 'mcp.json'), type: 'file' },
52
- { path: join(process.env.APPDATA || '', 'simplecli', 'mcp.json'), type: 'file' },
53
- ].filter(s => s.path && existsSync(s.path));
54
- for (const source of sources) {
55
- try {
56
- if (source.type === 'file') {
57
- const content = readFileSync(source.path, 'utf-8');
58
- allConfigs.push(...this.parseConfigContent(content));
59
- }
60
- else if (source.type === 'dir') {
61
- // Scan directory for .json files
62
- const { readdir } = await import('fs/promises');
63
- const files = await readdir(source.path);
64
- for (const file of files) {
65
- if (file.endsWith('.json')) {
66
- const content = readFileSync(join(source.path, file), 'utf-8');
67
- allConfigs.push(...this.parseConfigContent(content));
68
- }
69
- }
70
- }
71
- }
72
- catch (e) {
73
- if (process.env.DEBUG)
74
- console.error(`Failed to load MCP source ${source.path}:`, e);
75
- }
76
- }
77
- // De-duplicate by name, preferring earlier (local) configs
78
- const unique = new Map();
79
- for (const config of allConfigs) {
80
- if (!unique.has(config.name)) {
81
- unique.set(config.name, config);
82
- }
83
- }
84
- return Array.from(unique.values()).filter(s => s.enabled !== false);
85
- }
86
- /**
87
- * Parse MCP config content which can be in multiple formats
88
- */
89
- parseConfigContent(content) {
90
- try {
91
- const config = JSON.parse(content);
92
- // Handle { servers: [...] } format
93
- if (Array.isArray(config.servers)) {
94
- return config.servers;
95
- }
96
- // Handle { mcpServers: { name: config } } format (Claude-style)
97
- if (config.mcpServers) {
98
- return Object.entries(config.mcpServers).map(([name, cfg]) => ({
99
- name,
100
- ...cfg
101
- }));
102
- }
103
- // Handle single server config
104
- if (config.name && (config.command || config.url)) {
105
- return [config];
106
- }
107
- }
108
- catch (e) {
109
- if (process.env.DEBUG)
110
- console.error('Failed to parse MCP content:', e);
111
- }
112
- return [];
113
- }
114
- /**
115
- * Connect to an MCP server
116
- */
117
- async connect(config) {
118
- const serverName = config.name;
119
- if (this.servers.has(serverName)) {
120
- await this.disconnect(serverName);
121
- }
122
- const state = {
123
- client: null,
124
- transport: null,
125
- status: MCPServerStatus.CONNECTING,
126
- config,
127
- tools: [],
128
- resources: [],
129
- prompts: [],
130
- };
131
- this.servers.set(serverName, state);
132
- this.updateStatus(serverName, MCPServerStatus.CONNECTING);
133
- try {
134
- const client = new Client({ name: 'simplecli', version: '0.2.1' }, { capabilities: {} });
135
- let transport;
136
- if (config.command) {
137
- // Stdio transport
138
- transport = new StdioClientTransport({
139
- command: config.command,
140
- args: config.args || [],
141
- env: { ...process.env, ...(config.env || {}) },
142
- });
143
- }
144
- else if (config.url) {
145
- // For URL-based transports, we'd need additional SDK imports
146
- // For now, throw an error suggesting stdio
147
- throw new Error('URL-based MCP transports require additional configuration. Use stdio transport with command.');
148
- }
149
- else {
150
- throw new Error(`Invalid MCP server config for ${serverName}: missing command or url`);
151
- }
152
- // Connect with a 5-second timeout
153
- await Promise.race([
154
- client.connect(transport),
155
- new Promise((_, reject) => setTimeout(() => reject(new Error('Connection timeout')), 5000))
156
- ]);
157
- state.client = client;
158
- state.transport = transport;
159
- state.status = MCPServerStatus.CONNECTED;
160
- // Discover tools, resources, and prompts
161
- await this.discover(serverName);
162
- this.updateStatus(serverName, MCPServerStatus.CONNECTED);
163
- console.log(`✓ Connected to MCP server: ${serverName}`);
164
- }
165
- catch (error) {
166
- state.status = MCPServerStatus.ERROR;
167
- state.error = error instanceof Error ? error.message : String(error);
168
- this.updateStatus(serverName, MCPServerStatus.ERROR);
169
- console.error(`✗ Failed to connect to MCP server ${serverName}:`, state.error);
170
- }
171
- }
172
- /**
173
- * Connect to all configured servers
174
- */
175
- async connectAll(configs) {
176
- const serverConfigs = configs || await this.loadConfig();
177
- await Promise.all(serverConfigs.map(config => this.connect(config).catch(e => {
178
- console.error(`Failed to connect to ${config.name}:`, e);
179
- })));
180
- }
181
- /**
182
- * Disconnect from an MCP server
183
- */
184
- async disconnect(serverName) {
185
- const state = this.servers.get(serverName);
186
- if (!state)
187
- return;
188
- try {
189
- if (state.transport) {
190
- await state.transport.close();
191
- }
192
- if (state.client) {
193
- await state.client.close();
194
- }
195
- }
196
- catch (e) {
197
- // Ignore close errors
198
- }
199
- this.servers.delete(serverName);
200
- this.updateStatus(serverName, MCPServerStatus.DISCONNECTED);
201
- }
202
- /**
203
- * Disconnect from all servers
204
- */
205
- async disconnectAll() {
206
- await Promise.all(Array.from(this.servers.keys()).map(name => this.disconnect(name)));
207
- }
208
- /**
209
- * Discover tools, resources, and prompts from a server
210
- */
211
- async discover(serverName) {
212
- const state = this.servers.get(serverName);
213
- if (!state?.client)
214
- return;
215
- const client = state.client;
216
- // Discover tools
217
- try {
218
- const toolsResult = await client.listTools();
219
- state.tools = toolsResult.tools.map(tool => ({
220
- name: tool.name,
221
- description: tool.description || '',
222
- serverName,
223
- inputSchema: tool.inputSchema || {},
224
- execute: async (args) => {
225
- const result = await client.callTool({ name: tool.name, arguments: args });
226
- return result;
227
- },
228
- }));
229
- }
230
- catch {
231
- // Server may not support tools
232
- }
233
- // Discover resources
234
- try {
235
- const resourcesResult = await client.listResources();
236
- state.resources = resourcesResult.resources.map(resource => ({
237
- uri: resource.uri,
238
- name: resource.name,
239
- description: resource.description,
240
- mimeType: resource.mimeType,
241
- serverName,
242
- }));
243
- }
244
- catch {
245
- // Server may not support resources
246
- }
247
- // Discover prompts
248
- try {
249
- const promptsResult = await client.listPrompts();
250
- state.prompts = promptsResult.prompts.map(prompt => ({
251
- name: prompt.name,
252
- description: prompt.description,
253
- serverName,
254
- arguments: prompt.arguments,
255
- invoke: async (params) => {
256
- const stringParams = {};
257
- for (const [k, v] of Object.entries(params)) {
258
- stringParams[k] = String(v);
259
- }
260
- const result = await client.getPrompt({ name: prompt.name, arguments: stringParams });
261
- return {
262
- messages: result.messages.map(m => ({
263
- role: m.role,
264
- content: typeof m.content === 'string' ? m.content : JSON.stringify(m.content),
265
- })),
266
- };
267
- },
268
- }));
269
- }
270
- catch {
271
- // Server may not support prompts
272
- }
273
- }
274
- /**
275
- * Get all discovered tools from all connected servers
276
- */
277
- getAllTools() {
278
- const tools = [];
279
- for (const state of this.servers.values()) {
280
- if (state.status === MCPServerStatus.CONNECTED) {
281
- tools.push(...state.tools);
282
- }
283
- }
284
- return tools;
285
- }
286
- /**
287
- * Get all discovered resources from all connected servers
288
- */
289
- getAllResources() {
290
- const resources = [];
291
- for (const state of this.servers.values()) {
292
- if (state.status === MCPServerStatus.CONNECTED) {
293
- resources.push(...state.resources);
294
- }
295
- }
296
- return resources;
297
- }
298
- /**
299
- * Get all discovered prompts from all connected servers
300
- */
301
- getAllPrompts() {
302
- const prompts = [];
303
- for (const state of this.servers.values()) {
304
- if (state.status === MCPServerStatus.CONNECTED) {
305
- prompts.push(...state.prompts);
306
- }
307
- }
308
- return prompts;
309
- }
310
- /**
311
- * Get a specific tool by name
312
- */
313
- getTool(name) {
314
- return this.getAllTools().find(t => t.name === name);
315
- }
316
- /**
317
- * Execute an MCP tool
318
- */
319
- async executeTool(name, args) {
320
- const tool = this.getTool(name);
321
- if (!tool) {
322
- throw new Error(`MCP tool not found: ${name}`);
323
- }
324
- return tool.execute(args);
325
- }
326
- /**
327
- * Read an MCP resource
328
- */
329
- async readResource(uri) {
330
- // Find which server has this resource
331
- for (const state of this.servers.values()) {
332
- if (state.status !== MCPServerStatus.CONNECTED || !state.client)
333
- continue;
334
- const resource = state.resources.find(r => r.uri === uri);
335
- if (resource) {
336
- const result = await state.client.readResource({ uri });
337
- return result;
338
- }
339
- }
340
- throw new Error(`Resource not found: ${uri}`);
341
- }
342
- /**
343
- * Invoke an MCP prompt
344
- */
345
- async invokePrompt(name, params) {
346
- const prompt = this.getAllPrompts().find(p => p.name === name);
347
- if (!prompt) {
348
- throw new Error(`MCP prompt not found: ${name}`);
349
- }
350
- return prompt.invoke(params);
351
- }
352
- /**
353
- * Get server status
354
- */
355
- getServerStatus(serverName) {
356
- return this.servers.get(serverName)?.status || MCPServerStatus.DISCONNECTED;
357
- }
358
- /**
359
- * Get all server statuses
360
- */
361
- getAllServerStatuses() {
362
- const statuses = new Map();
363
- for (const [name, state] of this.servers) {
364
- statuses.set(name, state.status);
365
- }
366
- return statuses;
367
- }
368
- updateStatus(serverName, status) {
369
- this.onStatusChange?.(serverName, status);
370
- }
371
- }
372
- /**
373
- * Create Composio MCP configuration
374
- * Composio provides pre-built integrations for 250+ tools
375
- */
376
- export function createComposioConfig(apiKey) {
377
- return {
378
- name: 'composio',
379
- command: 'npx',
380
- args: ['-y', 'composio-core', 'mcp'],
381
- env: apiKey ? { COMPOSIO_API_KEY: apiKey } : {},
382
- trust: 'full',
383
- enabled: true,
384
- };
385
- }
386
- /**
387
- * Create filesystem MCP configuration
388
- */
389
- export function createFilesystemConfig(allowedPaths) {
390
- return {
391
- name: 'filesystem',
392
- command: 'npx',
393
- args: ['-y', '@modelcontextprotocol/server-filesystem', ...allowedPaths],
394
- trust: 'full',
395
- enabled: true,
396
- };
397
- }
398
- /**
399
- * Create GitHub MCP configuration
400
- */
401
- export function createGitHubConfig(token) {
402
- return {
403
- name: 'github',
404
- command: 'npx',
405
- args: ['-y', '@modelcontextprotocol/server-github'],
406
- env: token ? { GITHUB_PERSONAL_ACCESS_TOKEN: token } : {},
407
- trust: 'full',
408
- enabled: true,
409
- };
410
- }
411
- /**
412
- * Create memory/context MCP configuration
413
- */
414
- export function createMemoryConfig() {
415
- return {
416
- name: 'memory',
417
- command: 'npx',
418
- args: ['-y', '@modelcontextprotocol/server-memory'],
419
- trust: 'full',
420
- enabled: true,
421
- };
422
- }
423
- /**
424
- * Create Brave Search MCP configuration
425
- */
426
- export function createBraveSearchConfig(apiKey) {
427
- return {
428
- name: 'brave-search',
429
- command: 'npx',
430
- args: ['-y', '@modelcontextprotocol/server-brave-search'],
431
- env: apiKey ? { BRAVE_API_KEY: apiKey } : {},
432
- trust: 'full',
433
- enabled: true,
434
- };
435
- }
436
- // Singleton instance
437
- let mcpManager = null;
438
- /**
439
- * Get or create the global MCP manager instance
440
- */
441
- export function getMCPManager() {
442
- if (!mcpManager) {
443
- mcpManager = new MCPManager();
444
- }
445
- return mcpManager;
446
- }
@@ -1,22 +0,0 @@
1
- /**
2
- * Prompt Provider - Manages composition of system prompts
3
- * Supports built-in defaults, project-specific overrides, and modular personas.
4
- */
5
- export interface PromptOptions {
6
- cwd: string;
7
- skillPrompt?: string;
8
- }
9
- export declare class PromptProvider {
10
- /**
11
- * Builds the full system prompt by composing multiple layers:
12
- * 1. Built-in system instructions (src/prompts/defaults)
13
- * 2. Global user overrides (~/.simple/prompts)
14
- * 3. Project-specific prompts (.simple/prompts)
15
- * 4. Current skill instructions
16
- * 5. Local project rules (AGENT.md)
17
- */
18
- getSystemPrompt(options: PromptOptions): Promise<string>;
19
- private loadFromDirectory;
20
- private loadProjectRules;
21
- }
22
- export declare function getPromptProvider(): PromptProvider;
@@ -1,79 +0,0 @@
1
- /**
2
- * Prompt Provider - Manages composition of system prompts
3
- * Supports built-in defaults, project-specific overrides, and modular personas.
4
- */
5
- import { readFileSync, existsSync, readdirSync } from 'fs';
6
- import { join, dirname } from 'path';
7
- import { fileURLToPath } from 'url';
8
- import { homedir } from 'os';
9
- const __filename = fileURLToPath(import.meta.url);
10
- const __dirname = dirname(__filename);
11
- export class PromptProvider {
12
- /**
13
- * Builds the full system prompt by composing multiple layers:
14
- * 1. Built-in system instructions (src/prompts/defaults)
15
- * 2. Global user overrides (~/.simple/prompts)
16
- * 3. Project-specific prompts (.simple/prompts)
17
- * 4. Current skill instructions
18
- * 5. Local project rules (AGENT.md)
19
- */
20
- async getSystemPrompt(options) {
21
- const parts = [];
22
- // 1. Built-in defaults (Hardcoded in the package)
23
- const builtInDir = join(__dirname, 'defaults');
24
- if (existsSync(builtInDir)) {
25
- parts.push(...this.loadFromDirectory(builtInDir));
26
- }
27
- // 2. Global user rules (~/.simple/AGENT.md)
28
- const globalRulesPath = join(homedir(), '.simple', 'AGENT.md');
29
- if (existsSync(globalRulesPath)) {
30
- parts.push('\n## Global Rules\n' + readFileSync(globalRulesPath, 'utf-8'));
31
- }
32
- // 3. Project rules (AGENT.md)
33
- const rules = this.loadProjectRules(options.cwd);
34
- if (rules) {
35
- parts.push('\n## Project Rules\n' + rules);
36
- }
37
- // 4. Skill-specific prompt (Dynamic based on @skill)
38
- if (options.skillPrompt) {
39
- parts.push('\n## Skill Context: ' + options.skillPrompt);
40
- }
41
- return parts.join('\n\n').trim();
42
- }
43
- loadFromDirectory(dir) {
44
- try {
45
- return readdirSync(dir)
46
- .filter(f => f.endsWith('.md') || f.endsWith('.mdc'))
47
- .sort() // Ensure deterministic order
48
- .map(f => readFileSync(join(dir, f), 'utf-8'));
49
- }
50
- catch {
51
- return [];
52
- }
53
- }
54
- loadProjectRules(cwd) {
55
- const commonPaths = [
56
- '.simple/workdir/AGENT.md',
57
- '.simple/AGENT.md',
58
- '.agent/AGENT.md',
59
- 'AGENT.md',
60
- '.agent.md',
61
- '.cursorrules',
62
- '.aider/agent.md'
63
- ];
64
- for (const p of commonPaths) {
65
- const fullPath = join(cwd, p);
66
- if (existsSync(fullPath)) {
67
- return readFileSync(fullPath, 'utf-8');
68
- }
69
- }
70
- return null;
71
- }
72
- }
73
- let provider = null;
74
- export function getPromptProvider() {
75
- if (!provider) {
76
- provider = new PromptProvider();
77
- }
78
- return provider;
79
- }
@@ -1,31 +0,0 @@
1
- /**
2
- * Provider Bridge: Unified LLM interface via Vercel AI SDK
3
- * Support for OpenAI, Anthropic, Google (Gemini), and custom endpoints.
4
- */
5
- import { type TypeLLMResponse } from '@stan-chen/typellm';
6
- export interface Message {
7
- role: 'user' | 'assistant' | 'system';
8
- content: string;
9
- }
10
- export interface Provider {
11
- name: string;
12
- model: string;
13
- generateResponse: (systemPrompt: string, messages: Message[]) => Promise<TypeLLMResponse>;
14
- }
15
- /**
16
- * Structured output strategy:
17
- * - Uses strong system prompts with explicit JSON format examples
18
- * - Response parsing with jsonrepair (in cli.ts)
19
- * - Format reminders in user messages (in context.ts)
20
- *
21
- * This approach works across ALL providers without hitting
22
- * provider-specific schema limitations (e.g., OpenAI's additionalProperties requirement)
23
- */
24
- /**
25
- * Creates a provider instance using TypeLLM
26
- */
27
- export declare const createProviderForModel: (modelId: string) => Provider;
28
- /**
29
- * Creates the default provider
30
- */
31
- export declare const createProvider: () => Provider;
@@ -1,93 +0,0 @@
1
- /**
2
- * Provider Bridge: Unified LLM interface via Vercel AI SDK
3
- * Support for OpenAI, Anthropic, Google (Gemini), and custom endpoints.
4
- */
5
- import { createTypeLLM } from '@stan-chen/typellm';
6
- /**
7
- * Structured output strategy:
8
- * - Uses strong system prompts with explicit JSON format examples
9
- * - Response parsing with jsonrepair (in cli.ts)
10
- * - Format reminders in user messages (in context.ts)
11
- *
12
- * This approach works across ALL providers without hitting
13
- * provider-specific schema limitations (e.g., OpenAI's additionalProperties requirement)
14
- */
15
- /**
16
- * Creates a provider instance using TypeLLM
17
- */
18
- export const createProviderForModel = (modelId) => {
19
- let providerType = 'openai';
20
- let actualModel = modelId;
21
- let baseURL;
22
- // Handle provider selection
23
- if (modelId.startsWith('anthropic:')) {
24
- actualModel = modelId.split(':')[1] || modelId;
25
- providerType = 'anthropic';
26
- }
27
- else if (modelId.startsWith('google:') || modelId.startsWith('gemini:')) {
28
- actualModel = modelId.split(':')[1] || modelId;
29
- providerType = 'google';
30
- }
31
- else if (modelId.startsWith('openai:')) {
32
- actualModel = modelId.split(':')[1] || modelId;
33
- providerType = 'openai';
34
- }
35
- else if (modelId.startsWith('claude') || (process.env.ANTHROPIC_API_KEY && !process.env.OPENAI_API_KEY)) {
36
- providerType = 'anthropic';
37
- }
38
- else if (modelId.startsWith('gemini') || (process.env.GEMINI_API_KEY && !process.env.OPENAI_API_KEY)) {
39
- providerType = 'google';
40
- }
41
- else if (process.env.LITELLM_BASE_URL) {
42
- providerType = 'litellm';
43
- baseURL = process.env.LITELLM_BASE_URL;
44
- }
45
- else {
46
- providerType = 'openai';
47
- }
48
- // Final check for the Google key mapping
49
- if (providerType === 'google' && process.env.GEMINI_API_KEY && !process.env.GOOGLE_GENERATIVE_AI_API_KEY) {
50
- process.env.GOOGLE_GENERATIVE_AI_API_KEY = process.env.GEMINI_API_KEY;
51
- }
52
- const llm = createTypeLLM({
53
- provider: providerType,
54
- model: actualModel,
55
- baseURL: baseURL,
56
- apiKey: providerType === 'openai' ? process.env.OPENAI_API_KEY :
57
- providerType === 'google' ? process.env.GEMINI_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY :
58
- providerType === 'anthropic' ? process.env.ANTHROPIC_API_KEY :
59
- undefined,
60
- temperature: 0
61
- });
62
- return {
63
- name: providerType,
64
- model: actualModel,
65
- generateResponse: async (systemPrompt, messages) => {
66
- try {
67
- const response = await llm.generate(systemPrompt, messages);
68
- if ((process.env.DEBUG === 'true') && response)
69
- console.log(`[DEBUG] TypeLLM Response: ${JSON.stringify(response).substring(0, 300)}...`);
70
- return response;
71
- }
72
- catch (e) {
73
- const msg = `Error calling TypeLLM: ${e instanceof Error ? e.message : e}`;
74
- return {
75
- thought: 'Error occurred during generation',
76
- tool: 'none',
77
- args: {},
78
- message: msg,
79
- raw: msg
80
- };
81
- }
82
- }
83
- };
84
- };
85
- /**
86
- * Creates the default provider
87
- */
88
- export const createProvider = () => {
89
- const isClaw = process.argv.includes('--claw') || process.argv.includes('-claw');
90
- const model = (isClaw ? process.env.CLAW_MODEL : null) || process.env.OPENAI_MODEL || process.env.GEMINI_MODEL || 'gpt-4o-mini';
91
- console.log(`🤖 Using TypeLLM with model: ${model}`);
92
- return createProviderForModel(model);
93
- };
@@ -1,12 +0,0 @@
1
- /**
2
- * Multi-Provider: Manages multiple LLM models for MoE routing via LiteLLM
3
- * Each tier can use a different model from any provider
4
- */
5
- import { type Provider, type Message } from './index.js';
6
- import type { Tier, TierConfig } from '../router.js';
7
- import type { TypeLLMResponse } from '@stan-chen/typellm';
8
- export interface MultiProvider {
9
- getProvider: (tier: Tier) => Provider;
10
- generateWithTier: (tier: Tier, systemPrompt: string, messages: Message[]) => Promise<TypeLLMResponse>;
11
- }
12
- export declare const createMultiProvider: (tierConfigs: Map<Tier, TierConfig>) => MultiProvider;