@stan-chen/simple-cli 0.2.1 → 0.2.3

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 (61) hide show
  1. package/README.md +55 -238
  2. package/dist/claw/jit.d.ts +5 -0
  3. package/dist/claw/jit.js +138 -0
  4. package/dist/claw/management.d.ts +3 -0
  5. package/dist/claw/management.js +107 -0
  6. package/dist/cli.js +306 -61
  7. package/dist/commands/git/commit.js +2 -1
  8. package/dist/commands/index.js +3 -2
  9. package/dist/context.js +13 -3
  10. package/dist/lib/agent.d.ts +4 -3
  11. package/dist/lib/agent.js +49 -17
  12. package/dist/lib/git.js +6 -1
  13. package/dist/lib/shim.d.ts +4 -0
  14. package/dist/lib/shim.js +30 -0
  15. package/dist/lib/ui.js +25 -0
  16. package/dist/mcp/manager.js +5 -1
  17. package/dist/prompts/provider.js +1 -0
  18. package/dist/providers/index.d.ts +21 -5
  19. package/dist/providers/index.js +75 -64
  20. package/dist/providers/multi.d.ts +2 -1
  21. package/dist/registry.d.ts +5 -0
  22. package/dist/registry.js +86 -22
  23. package/dist/repoMap.js +18 -18
  24. package/dist/router.js +21 -11
  25. package/dist/skills.js +10 -10
  26. package/dist/swarm/worker.d.ts +2 -0
  27. package/dist/swarm/worker.js +85 -15
  28. package/dist/tools/analyze_file.d.ts +16 -0
  29. package/dist/tools/analyze_file.js +43 -0
  30. package/dist/tools/clawBrain.d.ts +23 -0
  31. package/dist/tools/clawBrain.js +136 -0
  32. package/dist/tools/claw_brain.d.ts +23 -0
  33. package/dist/tools/claw_brain.js +139 -0
  34. package/dist/tools/deleteFile.d.ts +19 -0
  35. package/dist/tools/deleteFile.js +36 -0
  36. package/dist/tools/delete_file.d.ts +19 -0
  37. package/dist/tools/delete_file.js +36 -0
  38. package/dist/tools/fileOps.d.ts +22 -0
  39. package/dist/tools/fileOps.js +43 -0
  40. package/dist/tools/file_ops.d.ts +22 -0
  41. package/dist/tools/file_ops.js +43 -0
  42. package/dist/tools/grep.d.ts +2 -2
  43. package/dist/tools/linter.js +85 -27
  44. package/dist/tools/list_dir.d.ts +29 -0
  45. package/dist/tools/list_dir.js +50 -0
  46. package/dist/tools/organizer.d.ts +1 -0
  47. package/dist/tools/organizer.js +65 -0
  48. package/dist/tools/read_files.d.ts +25 -0
  49. package/dist/tools/read_files.js +31 -0
  50. package/dist/tools/reload_tools.d.ts +11 -0
  51. package/dist/tools/reload_tools.js +22 -0
  52. package/dist/tools/run_command.d.ts +32 -0
  53. package/dist/tools/run_command.js +103 -0
  54. package/dist/tools/scheduler.d.ts +25 -0
  55. package/dist/tools/scheduler.js +65 -0
  56. package/dist/tools/writeFiles.js +1 -1
  57. package/dist/tools/write_files.d.ts +84 -0
  58. package/dist/tools/write_files.js +91 -0
  59. package/dist/tools/write_to_file.d.ts +15 -0
  60. package/dist/tools/write_to_file.js +21 -0
  61. package/package.json +84 -78
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Tool: writeFiles
3
+ * Write or update files with search/replace support (Aider-style)
4
+ */
5
+ import { z } from 'zod';
6
+ export declare const name = "write_files";
7
+ export declare const description = "Write or modify files. ALWAYS provide an array of objects in the \"files\" parameter, even for a single file. Each object must have \"path\" and either \"content\" (for full write) or \"searchReplace\" (for edits).";
8
+ export declare const permission: "write";
9
+ export declare const schema: z.ZodObject<{
10
+ files: z.ZodArray<z.ZodObject<{
11
+ path: z.ZodString;
12
+ content: z.ZodOptional<z.ZodString>;
13
+ searchReplace: z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodObject<{
14
+ search: z.ZodString;
15
+ replace: z.ZodString;
16
+ }, "strip", z.ZodTypeAny, {
17
+ replace: string;
18
+ search: string;
19
+ }, {
20
+ replace: string;
21
+ search: string;
22
+ }>, "many">, z.ZodEffects<z.ZodObject<{
23
+ search: z.ZodString;
24
+ replace: z.ZodString;
25
+ }, "strip", z.ZodTypeAny, {
26
+ replace: string;
27
+ search: string;
28
+ }, {
29
+ replace: string;
30
+ search: string;
31
+ }>, {
32
+ replace: string;
33
+ search: string;
34
+ }[], {
35
+ replace: string;
36
+ search: string;
37
+ }>]>>;
38
+ }, "strip", z.ZodTypeAny, {
39
+ path: string;
40
+ content?: string | undefined;
41
+ searchReplace?: {
42
+ replace: string;
43
+ search: string;
44
+ }[] | undefined;
45
+ }, {
46
+ path: string;
47
+ content?: string | undefined;
48
+ searchReplace?: {
49
+ replace: string;
50
+ search: string;
51
+ } | {
52
+ replace: string;
53
+ search: string;
54
+ }[] | undefined;
55
+ }>, "many">;
56
+ }, "strip", z.ZodTypeAny, {
57
+ files: {
58
+ path: string;
59
+ content?: string | undefined;
60
+ searchReplace?: {
61
+ replace: string;
62
+ search: string;
63
+ }[] | undefined;
64
+ }[];
65
+ }, {
66
+ files: {
67
+ path: string;
68
+ content?: string | undefined;
69
+ searchReplace?: {
70
+ replace: string;
71
+ search: string;
72
+ } | {
73
+ replace: string;
74
+ search: string;
75
+ }[] | undefined;
76
+ }[];
77
+ }>;
78
+ interface WriteResult {
79
+ path: string;
80
+ success: boolean;
81
+ message: string;
82
+ }
83
+ export declare const execute: (args: Record<string, unknown>) => Promise<WriteResult[]>;
84
+ export {};
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Tool: writeFiles
3
+ * Write or update files with search/replace support (Aider-style)
4
+ */
5
+ import { readFile, writeFile, mkdir } from 'fs/promises';
6
+ import { dirname, resolve } from 'path';
7
+ import { z } from 'zod';
8
+ export const name = 'write_files';
9
+ export const description = 'Write or modify files. ALWAYS provide an array of objects in the "files" parameter, even for a single file. Each object must have "path" and either "content" (for full write) or "searchReplace" (for edits).';
10
+ export const permission = 'write';
11
+ const SearchReplaceSchema = z.object({
12
+ search: z.string().describe('Text to search for'),
13
+ replace: z.string().describe('Text to replace with')
14
+ });
15
+ const FileWriteSchema = z.object({
16
+ path: z.string().describe('File path to write'),
17
+ content: z.string().optional().describe('Full content to write (for new files or full rewrites)'),
18
+ searchReplace: z.union([
19
+ z.array(SearchReplaceSchema),
20
+ SearchReplaceSchema.transform(val => [val])
21
+ ]).optional().describe('Array of search/replace operations for targeted edits')
22
+ });
23
+ export const schema = z.object({
24
+ files: z.array(FileWriteSchema).describe('Array of files to write/modify')
25
+ });
26
+ export const execute = async (args) => {
27
+ const parsed = schema.parse(args);
28
+ const results = [];
29
+ for (const file of parsed.files) {
30
+ try {
31
+ // Ensure directory exists
32
+ await mkdir(dirname(file.path), { recursive: true });
33
+ if (file.content !== undefined) {
34
+ // Full file write
35
+ await writeFile(file.path, file.content, 'utf-8');
36
+ const absPath = resolve(file.path);
37
+ results.push({
38
+ path: file.path,
39
+ success: true,
40
+ message: `File written successfully to ${absPath}`
41
+ });
42
+ }
43
+ else if (file.searchReplace && file.searchReplace.length > 0) {
44
+ // Search/replace operations
45
+ let content = await readFile(file.path, 'utf-8');
46
+ let changesApplied = 0;
47
+ const absPath = resolve(file.path);
48
+ for (const { search, replace } of file.searchReplace) {
49
+ if (content.includes(search)) {
50
+ // Apply replacement to all occurrences
51
+ const newContent = content.replace(search, replace);
52
+ if (newContent !== content) {
53
+ content = newContent;
54
+ changesApplied++;
55
+ }
56
+ }
57
+ }
58
+ if (changesApplied > 0) {
59
+ await writeFile(file.path, content, 'utf-8');
60
+ results.push({
61
+ path: file.path,
62
+ success: true,
63
+ message: `Applied ${changesApplied} search/replace operation(s) to ${absPath}`
64
+ });
65
+ }
66
+ else {
67
+ results.push({
68
+ path: file.path,
69
+ success: false,
70
+ message: `No matching search patterns found in ${absPath}`
71
+ });
72
+ }
73
+ }
74
+ else {
75
+ results.push({
76
+ path: file.path,
77
+ success: false,
78
+ message: 'No content or searchReplace provided'
79
+ });
80
+ }
81
+ }
82
+ catch (error) {
83
+ results.push({
84
+ path: file.path,
85
+ success: false,
86
+ message: error instanceof Error ? error.message : 'Unknown error'
87
+ });
88
+ }
89
+ }
90
+ return results;
91
+ };
@@ -0,0 +1,15 @@
1
+ import { z } from 'zod';
2
+ export declare const name = "write_to_file";
3
+ export declare const description = "Write content to a single file. Overwrites if it exists.";
4
+ export declare const permission: "write";
5
+ export declare const schema: z.ZodObject<{
6
+ path: z.ZodString;
7
+ content: z.ZodString;
8
+ }, "strip", z.ZodTypeAny, {
9
+ path: string;
10
+ content: string;
11
+ }, {
12
+ path: string;
13
+ content: string;
14
+ }>;
15
+ export declare const execute: (args: Record<string, unknown>) => Promise<string>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Tool: write_to_file
3
+ * Simplified file write for single files
4
+ */
5
+ import { writeFile, mkdir } from 'fs/promises';
6
+ import { dirname, resolve } from 'path';
7
+ import { z } from 'zod';
8
+ export const name = 'write_to_file';
9
+ export const description = 'Write content to a single file. Overwrites if it exists.';
10
+ export const permission = 'write';
11
+ export const schema = z.object({
12
+ path: z.string().describe('File path to write'),
13
+ content: z.string().describe('Content to write')
14
+ });
15
+ export const execute = async (args) => {
16
+ const { path, content } = schema.parse(args);
17
+ const absPath = resolve(path);
18
+ await mkdir(dirname(absPath), { recursive: true });
19
+ await writeFile(absPath, content, 'utf-8');
20
+ return `Successfully wrote to ${path}`;
21
+ };
package/package.json CHANGED
@@ -1,78 +1,84 @@
1
- {
2
- "name": "@stan-chen/simple-cli",
3
- "version": "0.2.1",
4
- "description": "A lean, lightweight coding agent. Packs a punch with token efficiency.",
5
- "type": "module",
6
- "main": "dist/cli.js",
7
- "bin": {
8
- "simple": "dist/cli.js"
9
- },
10
- "scripts": {
11
- "start": "node --loader ts-node/esm src/cli.ts",
12
- "dev": "node --loader ts-node/esm --watch src/index.ts",
13
- "build": "tsc",
14
- "typecheck": "tsc --noEmit",
15
- "test": "vitest run",
16
- "test:watch": "vitest",
17
- "test:coverage": "vitest run --coverage",
18
- "lint": "eslint src/ tests/",
19
- "format": "prettier --write src/ tests/"
20
- },
21
- "keywords": [
22
- "cli",
23
- "agent",
24
- "coding-assistant",
25
- "llm",
26
- "mcp",
27
- "ai",
28
- "openai",
29
- "anthropic",
30
- "gemini",
31
- "litellm",
32
- "aider"
33
- ],
34
- "license": "MIT",
35
- "engines": {
36
- "node": ">=18.0.0"
37
- },
38
- "dependencies": {
39
- "@clack/prompts": "^0.7.0",
40
- "@modelcontextprotocol/sdk": "^1.0.0",
41
- "@oclif/core": "^4.0.0",
42
- "chalk": "^5.3.0",
43
- "chokidar": "^5.0.0",
44
- "diff": "^5.2.0",
45
- "dotenv": "^16.4.7",
46
- "fast-glob": "^3.3.2",
47
- "fast-levenshtein": "^3.0.0",
48
- "glob": "^13.0.0",
49
- "gpt-tokenizer": "^2.5.0",
50
- "jsonrepair": "^3.13.2",
51
- "openai": "^6.16.0",
52
- "ora": "^8.0.0",
53
- "picocolors": "^1.0.0",
54
- "simple-git": "^3.22.0",
55
- "ts-morph": "^22.0.0",
56
- "turndown": "^7.2.0",
57
- "yaml": "^2.8.2",
58
- "zod": "^3.24.1"
59
- },
60
- "devDependencies": {
61
- "@oclif/test": "^4.0.0",
62
- "@types/chokidar": "^1.7.5",
63
- "@types/diff": "^5.2.3",
64
- "@types/fast-levenshtein": "^0.0.4",
65
- "@types/node": "^22.19.7",
66
- "@types/turndown": "^5.0.5",
67
- "oclif": "^4.0.0",
68
- "ts-node": "^10.9.2",
69
- "tsx": "^4.19.2",
70
- "typescript": "^5.7.2",
71
- "vitest": "^2.1.8"
72
- },
73
- "files": [
74
- "dist",
75
- "README.md",
76
- "docs/assets/logo.jpeg"
77
- ]
78
- }
1
+ {
2
+ "name": "@stan-chen/simple-cli",
3
+ "version": "0.2.3",
4
+ "description": "A lean, lightweight coding agent. Packs a punch with token efficiency.",
5
+ "type": "module",
6
+ "main": "dist/cli.js",
7
+ "bin": {
8
+ "simple": "dist/cli.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node --loader ts-node/esm src/cli.ts",
12
+ "dev": "node --loader ts-node/esm --watch src/index.ts",
13
+ "build": "tsc",
14
+ "typecheck": "tsc --noEmit",
15
+ "test": "vitest run",
16
+ "test:watch": "vitest",
17
+ "test:coverage": "vitest run --coverage",
18
+ "lint": "eslint src/ tests/",
19
+ "format": "prettier --write src/ tests/"
20
+ },
21
+ "keywords": [
22
+ "cli",
23
+ "agent",
24
+ "coding-assistant",
25
+ "llm",
26
+ "mcp",
27
+ "ai",
28
+ "openai",
29
+ "anthropic",
30
+ "gemini",
31
+ "litellm",
32
+ "aider"
33
+ ],
34
+ "license": "MIT",
35
+ "engines": {
36
+ "node": ">=18.0.0"
37
+ },
38
+ "dependencies": {
39
+ "@ai-sdk/anthropic": "^3.0.35",
40
+ "@ai-sdk/google": "^3.0.20",
41
+ "@ai-sdk/openai": "^3.0.25",
42
+ "@clack/prompts": "^0.7.0",
43
+ "@modelcontextprotocol/sdk": "^1.0.0",
44
+ "@oclif/core": "^4.0.0",
45
+ "@stan-chen/typellm": "^0.1.2",
46
+ "@types/node-fetch": "^2.6.13",
47
+ "ai": "^6.0.67",
48
+ "chalk": "^5.3.0",
49
+ "chokidar": "^5.0.0",
50
+ "diff": "^5.2.0",
51
+ "dotenv": "^16.4.7",
52
+ "fast-glob": "^3.3.2",
53
+ "fast-levenshtein": "^3.0.0",
54
+ "glob": "^13.0.0",
55
+ "gpt-tokenizer": "^2.5.0",
56
+ "jsonrepair": "^3.13.2",
57
+ "node-fetch": "^3.3.2",
58
+ "ora": "^8.0.0",
59
+ "picocolors": "^1.0.0",
60
+ "simple-git": "^3.22.0",
61
+ "ts-morph": "^22.0.0",
62
+ "turndown": "^7.2.0",
63
+ "yaml": "^2.8.2",
64
+ "zod": "^3.25.76"
65
+ },
66
+ "devDependencies": {
67
+ "@oclif/test": "^4.0.0",
68
+ "@types/chokidar": "^1.7.5",
69
+ "@types/diff": "^5.2.3",
70
+ "@types/fast-levenshtein": "^0.0.4",
71
+ "@types/node": "^22.19.7",
72
+ "@types/turndown": "^5.0.5",
73
+ "oclif": "^4.0.0",
74
+ "ts-node": "^10.9.2",
75
+ "tsx": "^4.19.2",
76
+ "typescript": "^5.7.2",
77
+ "vitest": "^2.1.8"
78
+ },
79
+ "files": [
80
+ "dist",
81
+ "README.md",
82
+ "docs/assets/logo.jpeg"
83
+ ]
84
+ }