@stan-chen/simple-cli 0.2.1 → 0.2.2

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/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ <p align="center">
2
+ <img src="docs/assets/logo.jpeg" alt="Simple-CLI Logo" width="200"/>
3
+ </p>
4
+
1
5
  # Simple-CLI ⚡
2
6
 
3
7
  > **The terminal-native AI coding assistant that shapes itself to your task.**
@@ -36,6 +40,8 @@ simple --claw "Delete trash emails every hour"
36
40
 
37
41
  ## Instant Setup
38
42
 
43
+ ### Option 1: Install from npm (Recommended)
44
+
39
45
  ```bash
40
46
  # Install
41
47
  npm install -g @stan-chen/simple-cli
@@ -47,6 +53,29 @@ export OPENAI_API_KEY="sk-..."
47
53
  simple
48
54
  ```
49
55
 
56
+ ### Option 2: Clone from GitHub
57
+
58
+ ```bash
59
+ # Clone the repository
60
+ git clone https://github.com/stancsz/simple-cli.git
61
+ cd simple-cli
62
+
63
+ # Install dependencies
64
+ npm install
65
+
66
+ # Build the project
67
+ npm run build
68
+
69
+ # Link globally (or use npm start for dev mode)
70
+ npm link
71
+
72
+ # Configure
73
+ export OPENAI_API_KEY="sk-..."
74
+
75
+ # Start coding
76
+ simple
77
+ ```
78
+
50
79
  **That's it.** It launches an interactive terminal session where you can:
51
80
  - Ask questions about your codebase
52
81
  - Request code changes
@@ -218,7 +247,7 @@ Built with the **Adapter Pattern** - add features without touching core.
218
247
  ### Environment Variables
219
248
  ```bash
220
249
  OPENAI_API_KEY=sk-... # Primary LLM
221
- CLAW_MODEL=gpt-4 # Model selection
250
+ CLAW_MODEL=gpt-5-mini # Model selection
222
251
  LITELLM_BASE_URL=... # Proxy support
223
252
  DEBUG=true # Verbose logging
224
253
  ```
package/dist/cli.js CHANGED
@@ -23,7 +23,35 @@ const MOE_MODE = process.argv.includes('--moe');
23
23
  const SWARM_MODE = process.argv.includes('--swarm');
24
24
  const CLAW_MODE = process.argv.includes('--claw') || process.argv.includes('-claw');
25
25
  const DEBUG = process.argv.includes('--debug') || process.env.DEBUG === 'true';
26
- const VERSION = '0.2.0';
26
+ const VERSION = '0.2.2';
27
+ // Handle --version and --help immediately
28
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
29
+ console.log(`Simple-CLI v${VERSION}`);
30
+ process.exit(0);
31
+ }
32
+ if (process.argv.includes('--help') || process.argv.includes('-h')) {
33
+ console.log(`
34
+ ${pc.bgCyan(pc.black(' SIMPLE-CLI '))} ${pc.dim(`v${VERSION}`)}
35
+
36
+ ${pc.bold('Usage:')}
37
+ simple [target_dir] [prompt] [options]
38
+
39
+ ${pc.bold('Options:')}
40
+ --version, -v Show version
41
+ --help, -h Show help
42
+ --yolo Skip all confirmation prompts
43
+ --moe Enable Mixture of Experts (multi-model)
44
+ --swarm Enable Swarm orchestration mode
45
+ --claw "intent" Enable OpenClaw JIT agent generation
46
+ --debug Enable debug logging
47
+
48
+ ${pc.bold('Examples:')}
49
+ simple . "Build a login page"
50
+ simple --claw "Security audit this project"
51
+ simple --moe "Refactor this entire folder"
52
+ `);
53
+ process.exit(0);
54
+ }
27
55
  // Handle --claw mode (JIT Agent Generation)
28
56
  if (CLAW_MODE) {
29
57
  const { execSync } = await import('child_process');
@@ -149,7 +149,11 @@ export class MCPManager {
149
149
  else {
150
150
  throw new Error(`Invalid MCP server config for ${serverName}: missing command or url`);
151
151
  }
152
- await client.connect(transport);
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
+ ]);
153
157
  state.client = client;
154
158
  state.transport = transport;
155
159
  state.status = MCPServerStatus.CONNECTED;
@@ -8,7 +8,7 @@ const getProviderConfig = () => {
8
8
  if (process.env.OPENAI_API_KEY) {
9
9
  return {
10
10
  apiKey: process.env.OPENAI_API_KEY,
11
- model: process.env.OPENAI_MODEL || 'gpt-4o'
11
+ model: process.env.OPENAI_MODEL || 'gpt-5-mini'
12
12
  };
13
13
  }
14
14
  // 2. DeepSeek
package/dist/repoMap.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * Uses ts-morph for TypeScript/JavaScript and simple parsing for others.
4
4
  */
5
5
  import { Project, ScriptTarget } from 'ts-morph';
6
- import { readdir } from 'fs/promises';
6
+ import { readdir, readFile } from 'fs/promises';
7
7
  import { join, extname, relative } from 'path';
8
8
  const IGNORED_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', 'coverage']);
9
9
  const TS_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx']);
@@ -36,37 +36,37 @@ export const generateRepoMap = async (rootDir = '.') => {
36
36
  }
37
37
  catch { /* ignore access errors */ }
38
38
  }
39
- // 2. Process Files
39
+ // 2. Process Files in parallel
40
40
  // Limit to 50 files for now to avoid context explosion
41
41
  const filesToProcess = validFiles.slice(0, 50);
42
- for (const filePath of filesToProcess) {
42
+ const results = await Promise.all(filesToProcess.map(async (filePath) => {
43
43
  const ext = extname(filePath);
44
44
  const relPath = relative(rootDir, filePath);
45
45
  if (TS_EXTENSIONS.has(ext)) {
46
46
  try {
47
- // Use ts-morph
48
- const sourceFile = project.createSourceFile(filePath, await import('fs/promises').then(fs => fs.readFile(filePath, 'utf-8')), { overwrite: true });
47
+ const content = await readFile(filePath, 'utf-8');
48
+ const sourceFile = project.createSourceFile(filePath, content, { overwrite: true });
49
49
  const symbols = [];
50
- sourceFile.getClasses().forEach(c => symbols.push(`class ${c.getName()}`));
51
- sourceFile.getFunctions().forEach(f => symbols.push(`func ${f.getName()}`));
52
- sourceFile.getInterfaces().forEach(i => symbols.push(`interface ${i.getName()}`));
53
- sourceFile.getTypeAliases().forEach(t => symbols.push(`type ${t.getName()}`));
54
- sourceFile.getVariableStatements().forEach(v => {
55
- v.getDeclarations().forEach(d => symbols.push(`const ${d.getName()}`));
50
+ sourceFile.getClasses().forEach((c) => symbols.push(`class ${c.getName()}`));
51
+ sourceFile.getFunctions().forEach((f) => symbols.push(`func ${f.getName()}`));
52
+ sourceFile.getInterfaces().forEach((i) => symbols.push(`interface ${i.getName()}`));
53
+ sourceFile.getTypeAliases().forEach((t) => symbols.push(`type ${t.getName()}`));
54
+ sourceFile.getVariableStatements().forEach((v) => {
55
+ v.getDeclarations().forEach((d) => symbols.push(`const ${d.getName()}`));
56
56
  });
57
- if (symbols.length > 0) {
58
- fileMaps.push({ path: relPath, symbols });
59
- }
57
+ return { path: relPath, symbols };
60
58
  }
61
59
  catch (e) {
62
- // Fallback or ignore
60
+ return null;
63
61
  }
64
62
  }
65
63
  else {
66
- // Simple listing for non-TS files? Or just skip symbols to keep it clean.
67
- // For now, let's just list the file path for completeness if it's source code
68
- fileMaps.push({ path: relPath, symbols: [] });
64
+ return { path: relPath, symbols: [] };
69
65
  }
66
+ }));
67
+ for (const res of results) {
68
+ if (res)
69
+ fileMaps.push(res);
70
70
  }
71
71
  if (fileMaps.length === 0)
72
72
  return 'No source files found.';
@@ -20,12 +20,12 @@ export declare const inputSchema: z.ZodObject<{
20
20
  contextLines: number;
21
21
  filesOnly: boolean;
22
22
  includeHidden: boolean;
23
- glob?: string | undefined;
24
23
  path?: string | undefined;
24
+ glob?: string | undefined;
25
25
  }, {
26
26
  pattern: string;
27
- glob?: string | undefined;
28
27
  path?: string | undefined;
28
+ glob?: string | undefined;
29
29
  ignoreCase?: boolean | undefined;
30
30
  maxResults?: number | undefined;
31
31
  contextLines?: number | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stan-chen/simple-cli",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "A lean, lightweight coding agent. Packs a punch with token efficiency.",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",
@@ -75,4 +75,4 @@
75
75
  "README.md",
76
76
  "docs/assets/logo.jpeg"
77
77
  ]
78
- }
78
+ }