@stan-chen/simple-cli 0.2.1

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 (87) hide show
  1. package/README.md +287 -0
  2. package/dist/cli.d.ts +6 -0
  3. package/dist/cli.js +259 -0
  4. package/dist/commands/add.d.ts +9 -0
  5. package/dist/commands/add.js +50 -0
  6. package/dist/commands/git/commit.d.ts +12 -0
  7. package/dist/commands/git/commit.js +97 -0
  8. package/dist/commands/git/status.d.ts +6 -0
  9. package/dist/commands/git/status.js +42 -0
  10. package/dist/commands/index.d.ts +16 -0
  11. package/dist/commands/index.js +376 -0
  12. package/dist/commands/mcp/status.d.ts +6 -0
  13. package/dist/commands/mcp/status.js +31 -0
  14. package/dist/commands/swarm.d.ts +36 -0
  15. package/dist/commands/swarm.js +236 -0
  16. package/dist/commands.d.ts +32 -0
  17. package/dist/commands.js +427 -0
  18. package/dist/context.d.ts +116 -0
  19. package/dist/context.js +327 -0
  20. package/dist/index.d.ts +6 -0
  21. package/dist/index.js +109 -0
  22. package/dist/lib/agent.d.ts +98 -0
  23. package/dist/lib/agent.js +281 -0
  24. package/dist/lib/editor.d.ts +74 -0
  25. package/dist/lib/editor.js +441 -0
  26. package/dist/lib/git.d.ts +164 -0
  27. package/dist/lib/git.js +351 -0
  28. package/dist/lib/ui.d.ts +159 -0
  29. package/dist/lib/ui.js +252 -0
  30. package/dist/mcp/client.d.ts +22 -0
  31. package/dist/mcp/client.js +81 -0
  32. package/dist/mcp/manager.d.ts +186 -0
  33. package/dist/mcp/manager.js +442 -0
  34. package/dist/prompts/provider.d.ts +22 -0
  35. package/dist/prompts/provider.js +78 -0
  36. package/dist/providers/index.d.ts +15 -0
  37. package/dist/providers/index.js +82 -0
  38. package/dist/providers/multi.d.ts +11 -0
  39. package/dist/providers/multi.js +28 -0
  40. package/dist/registry.d.ts +24 -0
  41. package/dist/registry.js +379 -0
  42. package/dist/repoMap.d.ts +5 -0
  43. package/dist/repoMap.js +79 -0
  44. package/dist/router.d.ts +41 -0
  45. package/dist/router.js +108 -0
  46. package/dist/skills.d.ts +25 -0
  47. package/dist/skills.js +288 -0
  48. package/dist/swarm/coordinator.d.ts +86 -0
  49. package/dist/swarm/coordinator.js +257 -0
  50. package/dist/swarm/index.d.ts +28 -0
  51. package/dist/swarm/index.js +29 -0
  52. package/dist/swarm/task.d.ts +104 -0
  53. package/dist/swarm/task.js +221 -0
  54. package/dist/swarm/types.d.ts +132 -0
  55. package/dist/swarm/types.js +37 -0
  56. package/dist/swarm/worker.d.ts +107 -0
  57. package/dist/swarm/worker.js +299 -0
  58. package/dist/tools/analyzeFile.d.ts +16 -0
  59. package/dist/tools/analyzeFile.js +43 -0
  60. package/dist/tools/git.d.ts +40 -0
  61. package/dist/tools/git.js +236 -0
  62. package/dist/tools/glob.d.ts +34 -0
  63. package/dist/tools/glob.js +165 -0
  64. package/dist/tools/grep.d.ts +53 -0
  65. package/dist/tools/grep.js +296 -0
  66. package/dist/tools/linter.d.ts +35 -0
  67. package/dist/tools/linter.js +349 -0
  68. package/dist/tools/listDir.d.ts +29 -0
  69. package/dist/tools/listDir.js +50 -0
  70. package/dist/tools/memory.d.ts +34 -0
  71. package/dist/tools/memory.js +215 -0
  72. package/dist/tools/readFiles.d.ts +25 -0
  73. package/dist/tools/readFiles.js +31 -0
  74. package/dist/tools/reloadTools.d.ts +11 -0
  75. package/dist/tools/reloadTools.js +22 -0
  76. package/dist/tools/runCommand.d.ts +32 -0
  77. package/dist/tools/runCommand.js +79 -0
  78. package/dist/tools/scraper.d.ts +31 -0
  79. package/dist/tools/scraper.js +211 -0
  80. package/dist/tools/writeFiles.d.ts +63 -0
  81. package/dist/tools/writeFiles.js +87 -0
  82. package/dist/ui/server.d.ts +5 -0
  83. package/dist/ui/server.js +74 -0
  84. package/dist/watcher.d.ts +35 -0
  85. package/dist/watcher.js +164 -0
  86. package/docs/assets/logo.jpeg +0 -0
  87. package/package.json +78 -0
package/dist/lib/ui.js ADDED
@@ -0,0 +1,252 @@
1
+ /**
2
+ * Terminal UI using Clack
3
+ * Modern, clean terminal prompts and spinners
4
+ */
5
+ import * as p from '@clack/prompts';
6
+ import pc from 'picocolors';
7
+ export { p as prompts };
8
+ /**
9
+ * UI Theme colors
10
+ */
11
+ export const theme = {
12
+ primary: pc.cyan,
13
+ success: pc.green,
14
+ warning: pc.yellow,
15
+ error: pc.red,
16
+ muted: pc.dim,
17
+ highlight: pc.bold,
18
+ code: pc.bgBlack,
19
+ };
20
+ /**
21
+ * Display intro banner
22
+ */
23
+ export function intro(message) {
24
+ p.intro(theme.primary(message));
25
+ }
26
+ /**
27
+ * Display outro message
28
+ */
29
+ export function outro(message) {
30
+ p.outro(theme.success(message));
31
+ }
32
+ /**
33
+ * Display a note
34
+ */
35
+ export function note(message, title) {
36
+ p.note(message, title);
37
+ }
38
+ /**
39
+ * Display a log message
40
+ */
41
+ export function log(message) {
42
+ p.log.message(message);
43
+ }
44
+ /**
45
+ * Display an info message
46
+ */
47
+ export function info(message) {
48
+ p.log.info(theme.primary(message));
49
+ }
50
+ /**
51
+ * Display a success message
52
+ */
53
+ export function success(message) {
54
+ p.log.success(theme.success(message));
55
+ }
56
+ /**
57
+ * Display a warning message
58
+ */
59
+ export function warning(message) {
60
+ p.log.warn(theme.warning(message));
61
+ }
62
+ /**
63
+ * Display an error message
64
+ */
65
+ export function error(message) {
66
+ p.log.error(theme.error(message));
67
+ }
68
+ /**
69
+ * Display a step message
70
+ */
71
+ export function step(message) {
72
+ p.log.step(message);
73
+ }
74
+ /**
75
+ * Show a spinner while executing an async operation
76
+ */
77
+ export async function spin(message, fn) {
78
+ const s = p.spinner();
79
+ s.start(message);
80
+ try {
81
+ const result = await fn();
82
+ s.stop(theme.success('✓ ' + message));
83
+ return result;
84
+ }
85
+ catch (err) {
86
+ s.stop(theme.error('✗ ' + message));
87
+ throw err;
88
+ }
89
+ }
90
+ /**
91
+ * Prompt for text input
92
+ */
93
+ export async function text(options) {
94
+ return p.text(options);
95
+ }
96
+ /**
97
+ * Prompt for password input
98
+ */
99
+ export async function password(options) {
100
+ return p.password(options);
101
+ }
102
+ /**
103
+ * Prompt for confirmation
104
+ */
105
+ export async function confirm(options) {
106
+ return p.confirm(options);
107
+ }
108
+ /**
109
+ * Prompt for single selection
110
+ */
111
+ export async function select(options) {
112
+ return p.select(options);
113
+ }
114
+ /**
115
+ * Prompt for multi-selection
116
+ */
117
+ export async function multiselect(options) {
118
+ return p.multiselect(options);
119
+ }
120
+ /**
121
+ * Group related prompts together
122
+ */
123
+ export async function group(prompts, options) {
124
+ return p.group(prompts, options);
125
+ }
126
+ /**
127
+ * Check if user cancelled
128
+ */
129
+ export function isCancel(value) {
130
+ return p.isCancel(value);
131
+ }
132
+ /**
133
+ * Cancel and exit
134
+ */
135
+ export function cancel(message) {
136
+ p.cancel(message || 'Operation cancelled.');
137
+ process.exit(0);
138
+ }
139
+ /**
140
+ * Display a diff with syntax highlighting
141
+ */
142
+ export function showDiff(diffText) {
143
+ const lines = diffText.split('\n');
144
+ for (const line of lines) {
145
+ if (line.startsWith('+') && !line.startsWith('+++')) {
146
+ console.log(theme.success(line));
147
+ }
148
+ else if (line.startsWith('-') && !line.startsWith('---')) {
149
+ console.log(theme.error(line));
150
+ }
151
+ else if (line.startsWith('@@')) {
152
+ console.log(theme.primary(line));
153
+ }
154
+ else if (line.startsWith('diff') || line.startsWith('index')) {
155
+ console.log(theme.muted(line));
156
+ }
157
+ else {
158
+ console.log(line);
159
+ }
160
+ }
161
+ }
162
+ /**
163
+ * Display a code block
164
+ */
165
+ export function showCode(code, language) {
166
+ const header = language ? theme.muted(`\`\`\`${language}`) : theme.muted('```');
167
+ const footer = theme.muted('```');
168
+ console.log(header);
169
+ console.log(code);
170
+ console.log(footer);
171
+ }
172
+ /**
173
+ * Display a thinking/reasoning block
174
+ */
175
+ export function showThought(thought) {
176
+ const lines = thought.split('\n');
177
+ const boxed = lines.map(line => theme.muted('│ ') + line).join('\n');
178
+ console.log(theme.muted('┌─ Thinking'));
179
+ console.log(boxed);
180
+ console.log(theme.muted('└─'));
181
+ }
182
+ /**
183
+ * Display a tool invocation
184
+ */
185
+ export function showToolCall(name, args) {
186
+ const argsStr = Object.entries(args)
187
+ .map(([k, v]) => `${theme.muted(k)}=${theme.highlight(JSON.stringify(v))}`)
188
+ .join(' ');
189
+ console.log(`${theme.primary('▶')} ${theme.highlight(name)} ${argsStr}`);
190
+ }
191
+ /**
192
+ * Display a tool result
193
+ */
194
+ export function showToolResult(result, truncate = 500) {
195
+ const display = result.length > truncate
196
+ ? result.slice(0, truncate) + theme.muted(`\n... (${result.length - truncate} more chars)`)
197
+ : result;
198
+ console.log(theme.muted('◀ ') + display);
199
+ }
200
+ /**
201
+ * Display file status indicators
202
+ */
203
+ export function showFileStatus(files) {
204
+ const icons = {
205
+ added: theme.success('+'),
206
+ modified: theme.warning('~'),
207
+ deleted: theme.error('-'),
208
+ readonly: theme.muted('○'),
209
+ };
210
+ for (const file of files) {
211
+ console.log(` ${icons[file.status]} ${file.path}`);
212
+ }
213
+ }
214
+ /**
215
+ * Display token count
216
+ */
217
+ export function showTokens(count, max) {
218
+ const formatted = count.toLocaleString();
219
+ if (max) {
220
+ const percent = ((count / max) * 100).toFixed(1);
221
+ const color = count / max > 0.8 ? theme.warning : theme.muted;
222
+ console.log(color(`Tokens: ${formatted} / ${max.toLocaleString()} (${percent}%)`));
223
+ }
224
+ else {
225
+ console.log(theme.muted(`Tokens: ~${formatted}`));
226
+ }
227
+ }
228
+ /**
229
+ * Create a task list for progress tracking
230
+ */
231
+ export function tasks() {
232
+ const taskList = new Map();
233
+ const icons = {
234
+ pending: theme.muted('○'),
235
+ running: theme.primary('●'),
236
+ done: theme.success('✓'),
237
+ error: theme.error('✗'),
238
+ };
239
+ return {
240
+ add(name, status = 'pending') {
241
+ taskList.set(name, status);
242
+ },
243
+ update(name, status) {
244
+ taskList.set(name, status);
245
+ },
246
+ render() {
247
+ for (const [name, status] of taskList) {
248
+ console.log(` ${icons[status]} ${name}`);
249
+ }
250
+ },
251
+ };
252
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * MCP Client: External tool integration via Model Context Protocol
3
+ */
4
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
+ import { z } from 'zod';
6
+ export interface MCPServer {
7
+ name: string;
8
+ command: string;
9
+ args?: string[];
10
+ env?: Record<string, string>;
11
+ }
12
+ export interface MCPTool {
13
+ name: string;
14
+ description: string;
15
+ inputSchema: z.ZodObject<z.ZodRawShape>;
16
+ }
17
+ export declare const connectMCPServer: (server: MCPServer) => Promise<Client>;
18
+ export declare const listMCPTools: (serverName: string) => Promise<MCPTool[]>;
19
+ export declare const callMCPTool: (serverName: string, toolName: string, args: Record<string, unknown>) => Promise<unknown>;
20
+ export declare const disconnectMCPServer: (serverName: string) => Promise<void>;
21
+ export declare const disconnectAllMCPServers: () => Promise<void>;
22
+ export declare const loadMCPConfig: (configPath?: string) => Promise<MCPServer[]>;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * MCP Client: External tool integration via Model Context Protocol
3
+ */
4
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
6
+ import { z } from 'zod';
7
+ // Active MCP connections
8
+ const connections = new Map();
9
+ // Connect to an MCP server
10
+ export const connectMCPServer = async (server) => {
11
+ if (connections.has(server.name)) {
12
+ return connections.get(server.name).client;
13
+ }
14
+ const transport = new StdioClientTransport({
15
+ command: server.command,
16
+ args: server.args || [],
17
+ env: { ...process.env, ...server.env }
18
+ });
19
+ const client = new Client({
20
+ name: 'simplecli',
21
+ version: '0.1.0'
22
+ }, {
23
+ capabilities: {}
24
+ });
25
+ await client.connect(transport);
26
+ connections.set(server.name, { client, transport });
27
+ console.log(` ✓ Connected to MCP server: ${server.name}`);
28
+ return client;
29
+ };
30
+ // List tools from an MCP server
31
+ export const listMCPTools = async (serverName) => {
32
+ const connection = connections.get(serverName);
33
+ if (!connection) {
34
+ throw new Error(`MCP server "${serverName}" not connected`);
35
+ }
36
+ const result = await connection.client.listTools();
37
+ return result.tools.map(tool => ({
38
+ name: tool.name,
39
+ description: tool.description || '',
40
+ inputSchema: z.object({}) // Simplified - would parse JSON schema in production
41
+ }));
42
+ };
43
+ // Call an MCP tool
44
+ export const callMCPTool = async (serverName, toolName, args) => {
45
+ const connection = connections.get(serverName);
46
+ if (!connection) {
47
+ throw new Error(`MCP server "${serverName}" not connected`);
48
+ }
49
+ const result = await connection.client.callTool({
50
+ name: toolName,
51
+ arguments: args
52
+ });
53
+ return result.content;
54
+ };
55
+ // Disconnect from an MCP server
56
+ export const disconnectMCPServer = async (serverName) => {
57
+ const connection = connections.get(serverName);
58
+ if (connection) {
59
+ await connection.client.close();
60
+ connections.delete(serverName);
61
+ console.log(` ✓ Disconnected from MCP server: ${serverName}`);
62
+ }
63
+ };
64
+ // Disconnect from all MCP servers
65
+ export const disconnectAllMCPServers = async () => {
66
+ for (const [name] of connections) {
67
+ await disconnectMCPServer(name);
68
+ }
69
+ };
70
+ // Load MCP servers from configuration
71
+ export const loadMCPConfig = async (configPath = './mcp.json') => {
72
+ try {
73
+ const { readFile } = await import('fs/promises');
74
+ const content = await readFile(configPath, 'utf-8');
75
+ const config = JSON.parse(content);
76
+ return config.servers || [];
77
+ }
78
+ catch {
79
+ return [];
80
+ }
81
+ };
@@ -0,0 +1,186 @@
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 { z } from 'zod';
7
+ export declare const MCPServerConfigSchema: z.ZodObject<{
8
+ name: z.ZodString;
9
+ command: z.ZodOptional<z.ZodString>;
10
+ args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
11
+ env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
12
+ url: z.ZodOptional<z.ZodString>;
13
+ type: z.ZodOptional<z.ZodEnum<["stdio", "sse", "http"]>>;
14
+ timeout: z.ZodOptional<z.ZodNumber>;
15
+ trust: z.ZodOptional<z.ZodEnum<["full", "partial", "none"]>>;
16
+ enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
17
+ }, "strip", z.ZodTypeAny, {
18
+ name: string;
19
+ enabled: boolean;
20
+ command?: string | undefined;
21
+ type?: "stdio" | "sse" | "http" | undefined;
22
+ args?: string[] | undefined;
23
+ env?: Record<string, string> | undefined;
24
+ url?: string | undefined;
25
+ timeout?: number | undefined;
26
+ trust?: "full" | "partial" | "none" | undefined;
27
+ }, {
28
+ name: string;
29
+ command?: string | undefined;
30
+ type?: "stdio" | "sse" | "http" | undefined;
31
+ args?: string[] | undefined;
32
+ env?: Record<string, string> | undefined;
33
+ url?: string | undefined;
34
+ timeout?: number | undefined;
35
+ trust?: "full" | "partial" | "none" | undefined;
36
+ enabled?: boolean | undefined;
37
+ }>;
38
+ export type MCPServerConfig = z.infer<typeof MCPServerConfigSchema>;
39
+ export interface MCPTool {
40
+ name: string;
41
+ description: string;
42
+ serverName: string;
43
+ inputSchema: Record<string, unknown>;
44
+ execute: (args: Record<string, unknown>) => Promise<unknown>;
45
+ }
46
+ export interface MCPResource {
47
+ uri: string;
48
+ name: string;
49
+ description?: string;
50
+ mimeType?: string;
51
+ serverName: string;
52
+ }
53
+ export interface MCPPrompt {
54
+ name: string;
55
+ description?: string;
56
+ serverName: string;
57
+ arguments?: Array<{
58
+ name: string;
59
+ description?: string;
60
+ required?: boolean;
61
+ }>;
62
+ invoke: (params: Record<string, unknown>) => Promise<{
63
+ messages: Array<{
64
+ role: string;
65
+ content: string;
66
+ }>;
67
+ }>;
68
+ }
69
+ export declare enum MCPServerStatus {
70
+ DISCONNECTED = "disconnected",
71
+ CONNECTING = "connecting",
72
+ CONNECTED = "connected",
73
+ ERROR = "error"
74
+ }
75
+ /**
76
+ * MCP Client Manager
77
+ * Manages connections to multiple MCP servers and aggregates their tools
78
+ */
79
+ export declare class MCPManager {
80
+ private servers;
81
+ private onStatusChange?;
82
+ constructor(options?: {
83
+ onStatusChange?: (serverName: string, status: MCPServerStatus) => void;
84
+ });
85
+ /**
86
+ * Load MCP configuration from all available sources
87
+ */
88
+ loadConfig(configPath?: string): Promise<MCPServerConfig[]>;
89
+ /**
90
+ * Parse MCP config content which can be in multiple formats
91
+ */
92
+ private parseConfigContent;
93
+ /**
94
+ * Connect to an MCP server
95
+ */
96
+ connect(config: MCPServerConfig): Promise<void>;
97
+ /**
98
+ * Connect to all configured servers
99
+ */
100
+ connectAll(configs?: MCPServerConfig[]): Promise<void>;
101
+ /**
102
+ * Disconnect from an MCP server
103
+ */
104
+ disconnect(serverName: string): Promise<void>;
105
+ /**
106
+ * Disconnect from all servers
107
+ */
108
+ disconnectAll(): Promise<void>;
109
+ /**
110
+ * Discover tools, resources, and prompts from a server
111
+ */
112
+ private discover;
113
+ /**
114
+ * Get all discovered tools from all connected servers
115
+ */
116
+ getAllTools(): MCPTool[];
117
+ /**
118
+ * Get all discovered resources from all connected servers
119
+ */
120
+ getAllResources(): MCPResource[];
121
+ /**
122
+ * Get all discovered prompts from all connected servers
123
+ */
124
+ getAllPrompts(): MCPPrompt[];
125
+ /**
126
+ * Get a specific tool by name
127
+ */
128
+ getTool(name: string): MCPTool | undefined;
129
+ /**
130
+ * Execute an MCP tool
131
+ */
132
+ executeTool(name: string, args: Record<string, unknown>): Promise<unknown>;
133
+ /**
134
+ * Read an MCP resource
135
+ */
136
+ readResource(uri: string): Promise<{
137
+ contents: Array<{
138
+ uri: string;
139
+ text?: string;
140
+ blob?: string;
141
+ }>;
142
+ }>;
143
+ /**
144
+ * Invoke an MCP prompt
145
+ */
146
+ invokePrompt(name: string, params: Record<string, unknown>): Promise<{
147
+ messages: Array<{
148
+ role: string;
149
+ content: string;
150
+ }>;
151
+ }>;
152
+ /**
153
+ * Get server status
154
+ */
155
+ getServerStatus(serverName: string): MCPServerStatus;
156
+ /**
157
+ * Get all server statuses
158
+ */
159
+ getAllServerStatuses(): Map<string, MCPServerStatus>;
160
+ private updateStatus;
161
+ }
162
+ /**
163
+ * Create Composio MCP configuration
164
+ * Composio provides pre-built integrations for 250+ tools
165
+ */
166
+ export declare function createComposioConfig(apiKey?: string): MCPServerConfig;
167
+ /**
168
+ * Create filesystem MCP configuration
169
+ */
170
+ export declare function createFilesystemConfig(allowedPaths: string[]): MCPServerConfig;
171
+ /**
172
+ * Create GitHub MCP configuration
173
+ */
174
+ export declare function createGitHubConfig(token?: string): MCPServerConfig;
175
+ /**
176
+ * Create memory/context MCP configuration
177
+ */
178
+ export declare function createMemoryConfig(): MCPServerConfig;
179
+ /**
180
+ * Create Brave Search MCP configuration
181
+ */
182
+ export declare function createBraveSearchConfig(apiKey?: string): MCPServerConfig;
183
+ /**
184
+ * Get or create the global MCP manager instance
185
+ */
186
+ export declare function getMCPManager(): MCPManager;