@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,139 +0,0 @@
1
- /**
2
- * ClawBrain - Agentic Reasoning and Persistence for Autonomous Mode
3
- */
4
- import { z } from 'zod';
5
- import { readFile, writeFile, mkdir } from 'fs/promises';
6
- import { existsSync } from 'fs';
7
- import { join } from 'path';
8
- export const inputSchema = z.object({
9
- action: z.enum(['set_goal', 'update_status', 'log_reflection', 'get_summary', 'prune', 'link_files']),
10
- content: z.string().optional().describe('Text content for the action'),
11
- status: z.enum(['planning', 'executing', 'completed', 'failed']).optional().describe('Current mission status'),
12
- links: z.array(z.string()).optional().describe('Paths or IDs to link in the graph'),
13
- });
14
- const MISSION_FILE = '.simple/workdir/mission.json';
15
- async function loadMission(cwd) {
16
- const path = join(cwd, MISSION_FILE);
17
- if (!existsSync(path)) {
18
- return { goal: 'Unknown', status: 'planning', reflections: [], lastUpdated: Date.now() };
19
- }
20
- try {
21
- return JSON.parse(await readFile(path, 'utf-8'));
22
- }
23
- catch {
24
- return { goal: 'Unknown', status: 'planning', reflections: [], lastUpdated: Date.now() };
25
- }
26
- }
27
- async function saveMission(cwd, mission) {
28
- const path = join(cwd, MISSION_FILE);
29
- await mkdir(join(cwd, '.simple/workdir'), { recursive: true });
30
- mission.lastUpdated = Date.now();
31
- await writeFile(path, JSON.stringify(mission, null, 2));
32
- }
33
- export const execute = async (args, cwd = process.cwd()) => {
34
- const { action, content, status, links } = inputSchema.parse(args);
35
- const mission = await loadMission(cwd);
36
- switch (action) {
37
- case 'set_goal':
38
- mission.goal = content || mission.goal;
39
- if (status)
40
- mission.status = status;
41
- await saveMission(cwd, mission);
42
- return { success: true, message: `Goal set to: ${mission.goal}` };
43
- case 'update_status':
44
- if (status)
45
- mission.status = status;
46
- if (content)
47
- mission.reflections.push(`[Status Update] ${content}`);
48
- await saveMission(cwd, mission);
49
- return { success: true, status: mission.status };
50
- case 'log_reflection':
51
- if (content) {
52
- mission.reflections.push(content);
53
- if (mission.reflections.length > 50)
54
- mission.reflections.shift();
55
- await saveMission(cwd, mission);
56
- // Write to reflections directory for JIT context
57
- const reflectionsDir = join(cwd, '.simple/workdir/memory/reflections');
58
- await mkdir(reflectionsDir, { recursive: true });
59
- const fileName = `reflection-${Date.now()}.md`;
60
- await writeFile(join(reflectionsDir, fileName), content);
61
- }
62
- return { success: true, added: !!content };
63
- case 'link_files':
64
- if (links && links.length > 0) {
65
- const graphDir = join(cwd, '.simple/workdir/memory/graph');
66
- await mkdir(graphDir, { recursive: true });
67
- const graphFile = join(graphDir, 'links.jsonl');
68
- const entry = JSON.stringify({ timestamp: Date.now(), links, goal: mission.goal }) + '\n';
69
- await writeFile(graphFile, entry, { flag: 'a' });
70
- }
71
- return { success: true, linked: links?.length || 0 };
72
- case 'get_summary':
73
- return {
74
- goal: mission.goal,
75
- status: mission.status,
76
- recent_reflections: mission.reflections.slice(-5),
77
- last_updated: new Date(mission.lastUpdated).toISOString()
78
- };
79
- case 'prune': {
80
- const memoryDir = join(cwd, '.simple/workdir/memory');
81
- const notesDir = join(memoryDir, 'notes');
82
- await mkdir(notesDir, { recursive: true });
83
- if (mission.reflections.length === 0) {
84
- return { success: true, message: 'Nothing to prune.' };
85
- }
86
- const archiveFile = join(notesDir, `archive-${Date.now()}.md`);
87
- let consolidated;
88
- try {
89
- const { createProvider } = await import('../providers/index.js');
90
- const provider = createProvider();
91
- const prompt = `Consolidate and summarize the following mission reflections into a concise technical brief.
92
- Keep ONLY unique technical insights, discovered paths, and finalized facts.
93
- Original Goal: ${mission.goal}\n\nReflections:\n${mission.reflections.join('\n')}`;
94
- console.log('🤖 Summarizing reflections for pruning...');
95
- const summary = await provider.generateResponse('You are a technical documentarian.', [
96
- { role: 'user', content: prompt }
97
- ]);
98
- let summaryText = summary.message || summary.thought || summary.raw || '';
99
- try {
100
- // Try parsing raw if it looks like JSON and primary fields are empty
101
- if (!summaryText && summary.raw && (summary.raw.startsWith('{') || summary.raw.startsWith('['))) {
102
- const parsed = JSON.parse(summary.raw);
103
- summaryText = parsed.thought || parsed.message || summary.raw;
104
- }
105
- }
106
- catch { /* not JSON */ }
107
- consolidated = [
108
- `# Mission Summary Archive: ${mission.goal}`,
109
- `Status: ${mission.status}`,
110
- `Date: ${new Date().toISOString()}`,
111
- '',
112
- '## Executive Summary',
113
- summaryText
114
- ].join('\n');
115
- }
116
- catch (e) {
117
- // Fallback to basic concatenation if LLM fails
118
- consolidated = mission.reflections.map(r => `- ${r}`).join('\n');
119
- }
120
- await writeFile(archiveFile, consolidated);
121
- mission.reflections = mission.reflections.slice(-3); // Keep only very recent context
122
- await saveMission(cwd, mission);
123
- return {
124
- success: true,
125
- message: 'Memory pruned and summarized with LLM.',
126
- archivePath: archiveFile
127
- };
128
- }
129
- default:
130
- throw new Error(`Invalid action: ${action}`);
131
- }
132
- };
133
- export const tool = {
134
- name: 'claw_brain',
135
- description: 'Manage autonomous mission state and technical reasoning. Use to set goals, log reflections, and track status.',
136
- inputSchema,
137
- permission: 'write',
138
- execute: async (args) => execute(args),
139
- };
@@ -1,19 +0,0 @@
1
- /**
2
- * Tool: delete_file
3
- * Safely delete files
4
- */
5
- import { z } from 'zod';
6
- export declare const name = "delete_file";
7
- export declare const description = "Delete a file from the filesystem. Use with caution.";
8
- export declare const permission: "write";
9
- export declare const schema: z.ZodObject<{
10
- path: z.ZodString;
11
- confirm: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
12
- }, "strip", z.ZodTypeAny, {
13
- path: string;
14
- confirm: boolean;
15
- }, {
16
- path: string;
17
- confirm?: boolean | undefined;
18
- }>;
19
- export declare const execute: (args: Record<string, unknown>) => Promise<string>;
@@ -1,36 +0,0 @@
1
- /**
2
- * Tool: delete_file
3
- * Safely delete files
4
- */
5
- import { unlink, stat } from 'fs/promises';
6
- import { resolve } from 'path';
7
- import { z } from 'zod';
8
- import { existsSync } from 'fs';
9
- export const name = 'delete_file';
10
- export const description = 'Delete a file from the filesystem. Use with caution.';
11
- export const permission = 'write';
12
- export const schema = z.object({
13
- path: z.string().describe('Path to the file to delete'),
14
- confirm: z.boolean().optional().default(false).describe('Confirmation flag (must be true to execute)')
15
- });
16
- export const execute = async (args) => {
17
- const { path, confirm } = schema.parse(args);
18
- if (!confirm) {
19
- throw new Error('Deletion requires explicit confirmation. Set confirm=true to proceed.');
20
- }
21
- const fullPath = resolve(path);
22
- if (!existsSync(fullPath)) {
23
- throw new Error(`File not found: ${fullPath}`);
24
- }
25
- try {
26
- const stats = await stat(fullPath);
27
- if (stats.isDirectory()) {
28
- throw new Error(`Path is a directory, not a file: ${fullPath}. Use a different tool for directories.`);
29
- }
30
- await unlink(fullPath);
31
- return `Successfully deleted ${path}`;
32
- }
33
- catch (error) {
34
- throw new Error(`Failed to delete file: ${error instanceof Error ? error.message : String(error)}`);
35
- }
36
- };
@@ -1,19 +0,0 @@
1
- /**
2
- * Tool: delete_file
3
- * Safely delete files
4
- */
5
- import { z } from 'zod';
6
- export declare const name = "delete_file";
7
- export declare const description = "Delete a file from the filesystem. Use with caution.";
8
- export declare const permission: "write";
9
- export declare const schema: z.ZodObject<{
10
- path: z.ZodString;
11
- confirm: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
12
- }, "strip", z.ZodTypeAny, {
13
- path: string;
14
- confirm: boolean;
15
- }, {
16
- path: string;
17
- confirm?: boolean | undefined;
18
- }>;
19
- export declare const execute: (args: Record<string, unknown>) => Promise<string>;
@@ -1,36 +0,0 @@
1
- /**
2
- * Tool: delete_file
3
- * Safely delete files
4
- */
5
- import { unlink, stat } from 'fs/promises';
6
- import { resolve } from 'path';
7
- import { z } from 'zod';
8
- import { existsSync } from 'fs';
9
- export const name = 'delete_file';
10
- export const description = 'Delete a file from the filesystem. Use with caution.';
11
- export const permission = 'write';
12
- export const schema = z.object({
13
- path: z.string().describe('Path to the file to delete'),
14
- confirm: z.boolean().optional().default(false).describe('Confirmation flag (must be true to execute)')
15
- });
16
- export const execute = async (args) => {
17
- const { path, confirm } = schema.parse(args);
18
- if (!confirm) {
19
- throw new Error('Deletion requires explicit confirmation. Set confirm=true to proceed.');
20
- }
21
- const fullPath = resolve(path);
22
- if (!existsSync(fullPath)) {
23
- throw new Error(`File not found: ${fullPath}`);
24
- }
25
- try {
26
- const stats = await stat(fullPath);
27
- if (stats.isDirectory()) {
28
- throw new Error(`Path is a directory, not a file: ${fullPath}. Use a different tool for directories.`);
29
- }
30
- await unlink(fullPath);
31
- return `Successfully deleted ${path}`;
32
- }
33
- catch (error) {
34
- throw new Error(`Failed to delete file: ${error instanceof Error ? error.message : String(error)}`);
35
- }
36
- };
@@ -1,22 +0,0 @@
1
- /**
2
- * Tool: move_file
3
- * Move or rename files safely
4
- */
5
- import { z } from 'zod';
6
- export declare const name = "move_file";
7
- export declare const description = "Move or rename a file from source to destination. Creates destination directory if it does not exist.";
8
- export declare const permission: "write";
9
- export declare const schema: z.ZodObject<{
10
- source: z.ZodString;
11
- destination: z.ZodString;
12
- overwrite: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
13
- }, "strip", z.ZodTypeAny, {
14
- overwrite: boolean;
15
- source: string;
16
- destination: string;
17
- }, {
18
- source: string;
19
- destination: string;
20
- overwrite?: boolean | undefined;
21
- }>;
22
- export declare const execute: (args: Record<string, unknown>) => Promise<string>;
@@ -1,43 +0,0 @@
1
- /**
2
- * Tool: move_file
3
- * Move or rename files safely
4
- */
5
- import { rename, stat, mkdir } from 'fs/promises';
6
- import { resolve, dirname } from 'path';
7
- import { z } from 'zod';
8
- import { existsSync } from 'fs';
9
- export const name = 'move_file';
10
- export const description = 'Move or rename a file from source to destination. Creates destination directory if it does not exist.';
11
- export const permission = 'write';
12
- export const schema = z.object({
13
- source: z.string().describe('Source file path'),
14
- destination: z.string().describe('Destination file path'),
15
- overwrite: z.boolean().optional().default(false).describe('Overwrite if destination exists')
16
- });
17
- export const execute = async (args) => {
18
- const { source, destination, overwrite } = schema.parse(args);
19
- const srcPath = resolve(source);
20
- const destPath = resolve(destination);
21
- try {
22
- // Check if source exists
23
- await stat(srcPath);
24
- }
25
- catch {
26
- throw new Error(`Source file not found: ${srcPath}`);
27
- }
28
- // Check if destination exists
29
- if (existsSync(destPath) && !overwrite) {
30
- throw new Error(`Destination already exists: ${destPath}. Set overwrite=true to force.`);
31
- }
32
- // Ensure destination directory exists
33
- await mkdir(dirname(destPath), { recursive: true });
34
- try {
35
- await rename(srcPath, destPath);
36
- return `Successfully moved ${source} to ${destination}`;
37
- }
38
- catch (error) {
39
- // If cross-device link error (EXDEV), we might need copy+unlink, but Node's rename usually handles this or throws.
40
- // For simplicity in this tool, we report the error.
41
- throw new Error(`Failed to move file: ${error instanceof Error ? error.message : String(error)}`);
42
- }
43
- };
@@ -1,22 +0,0 @@
1
- /**
2
- * Tool: move_file
3
- * Move or rename files safely
4
- */
5
- import { z } from 'zod';
6
- export declare const name = "move_file";
7
- export declare const description = "Move or rename a file from source to destination. Creates destination directory if it does not exist.";
8
- export declare const permission: "write";
9
- export declare const schema: z.ZodObject<{
10
- source: z.ZodString;
11
- destination: z.ZodString;
12
- overwrite: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
13
- }, "strip", z.ZodTypeAny, {
14
- overwrite: boolean;
15
- source: string;
16
- destination: string;
17
- }, {
18
- source: string;
19
- destination: string;
20
- overwrite?: boolean | undefined;
21
- }>;
22
- export declare const execute: (args: Record<string, unknown>) => Promise<string>;
@@ -1,43 +0,0 @@
1
- /**
2
- * Tool: move_file
3
- * Move or rename files safely
4
- */
5
- import { rename, stat, mkdir } from 'fs/promises';
6
- import { resolve, dirname } from 'path';
7
- import { z } from 'zod';
8
- import { existsSync } from 'fs';
9
- export const name = 'move_file';
10
- export const description = 'Move or rename a file from source to destination. Creates destination directory if it does not exist.';
11
- export const permission = 'write';
12
- export const schema = z.object({
13
- source: z.string().describe('Source file path'),
14
- destination: z.string().describe('Destination file path'),
15
- overwrite: z.boolean().optional().default(false).describe('Overwrite if destination exists')
16
- });
17
- export const execute = async (args) => {
18
- const { source, destination, overwrite } = schema.parse(args);
19
- const srcPath = resolve(source);
20
- const destPath = resolve(destination);
21
- try {
22
- // Check if source exists
23
- await stat(srcPath);
24
- }
25
- catch {
26
- throw new Error(`Source file not found: ${srcPath}`);
27
- }
28
- // Check if destination exists
29
- if (existsSync(destPath) && !overwrite) {
30
- throw new Error(`Destination already exists: ${destPath}. Set overwrite=true to force.`);
31
- }
32
- // Ensure destination directory exists
33
- await mkdir(dirname(destPath), { recursive: true });
34
- try {
35
- await rename(srcPath, destPath);
36
- return `Successfully moved ${source} to ${destination}`;
37
- }
38
- catch (error) {
39
- // If cross-device link error (EXDEV), we might need copy+unlink, but Node's rename usually handles this or throws.
40
- // For simplicity in this tool, we report the error.
41
- throw new Error(`Failed to move file: ${error instanceof Error ? error.message : String(error)}`);
42
- }
43
- };
@@ -1,40 +0,0 @@
1
- /**
2
- * Git Tool - Git operations for version control
3
- * Based on Aider's repo.py
4
- */
5
- import { z } from 'zod';
6
- import type { Tool } from '../registry.js';
7
- export declare const inputSchema: z.ZodObject<{
8
- operation: z.ZodEnum<["status", "diff", "log", "add", "commit", "branch", "checkout", "stash", "show", "blame"]>;
9
- args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
10
- cwd: z.ZodOptional<z.ZodString>;
11
- message: z.ZodOptional<z.ZodString>;
12
- files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
13
- }, "strip", z.ZodTypeAny, {
14
- operation: "status" | "diff" | "log" | "add" | "commit" | "branch" | "checkout" | "stash" | "show" | "blame";
15
- files?: string[] | undefined;
16
- message?: string | undefined;
17
- args?: string[] | undefined;
18
- cwd?: string | undefined;
19
- }, {
20
- operation: "status" | "diff" | "log" | "add" | "commit" | "branch" | "checkout" | "stash" | "show" | "blame";
21
- files?: string[] | undefined;
22
- message?: string | undefined;
23
- args?: string[] | undefined;
24
- cwd?: string | undefined;
25
- }>;
26
- type GitInput = z.infer<typeof inputSchema>;
27
- interface GitResult {
28
- operation: string;
29
- success: boolean;
30
- output: string;
31
- error?: string;
32
- }
33
- export declare function execute(input: GitInput): Promise<GitResult>;
34
- export declare function getCurrentBranch(cwd?: string): string | null;
35
- export declare function getChangedFiles(cwd?: string): string[];
36
- export declare function getTrackedFiles(cwd?: string): string[];
37
- export declare function isIgnored(filePath: string, cwd?: string): boolean;
38
- export declare function getStagedDiff(cwd?: string): string | null;
39
- export declare const tool: Tool;
40
- export {};
package/dist/tools/git.js DELETED
@@ -1,236 +0,0 @@
1
- /**
2
- * Git Tool - Git operations for version control
3
- * Based on Aider's repo.py
4
- */
5
- import { z } from 'zod';
6
- import { execSync, spawnSync } from 'child_process';
7
- // Input schema for git operations
8
- export const inputSchema = z.object({
9
- operation: z.enum([
10
- 'status',
11
- 'diff',
12
- 'log',
13
- 'add',
14
- 'commit',
15
- 'branch',
16
- 'checkout',
17
- 'stash',
18
- 'show',
19
- 'blame',
20
- ]).describe('Git operation to perform'),
21
- args: z.array(z.string()).optional().describe('Additional arguments for the operation'),
22
- cwd: z.string().optional().describe('Working directory'),
23
- message: z.string().optional().describe('Commit message (for commit operation)'),
24
- files: z.array(z.string()).optional().describe('Files to operate on'),
25
- });
26
- // Check if directory is a git repository
27
- function isGitRepo(cwd) {
28
- try {
29
- execSync('git rev-parse --git-dir', {
30
- cwd,
31
- encoding: 'utf-8',
32
- stdio: ['pipe', 'pipe', 'pipe'],
33
- });
34
- return true;
35
- }
36
- catch {
37
- return false;
38
- }
39
- }
40
- // Run git command
41
- function runGit(args, cwd) {
42
- const operation = args[0] || 'unknown';
43
- try {
44
- const result = spawnSync('git', args, {
45
- cwd,
46
- encoding: 'utf-8',
47
- maxBuffer: 10 * 1024 * 1024, // 10MB
48
- timeout: 60000,
49
- });
50
- if (result.error) {
51
- return {
52
- operation,
53
- success: false,
54
- output: '',
55
- error: result.error.message,
56
- };
57
- }
58
- const output = (result.stdout || '') + (result.stderr || '');
59
- const success = result.status === 0;
60
- return {
61
- operation,
62
- success,
63
- output: output.trim(),
64
- error: success ? undefined : output.trim(),
65
- };
66
- }
67
- catch (error) {
68
- return {
69
- operation,
70
- success: false,
71
- output: '',
72
- error: error instanceof Error ? error.message : String(error),
73
- };
74
- }
75
- }
76
- // Execute git operation
77
- export async function execute(input) {
78
- const { operation, args = [], cwd = process.cwd(), message, files = [], } = inputSchema.parse(input);
79
- // Check if it's a git repository
80
- if (!isGitRepo(cwd)) {
81
- return {
82
- operation,
83
- success: false,
84
- output: '',
85
- error: 'Not a git repository',
86
- };
87
- }
88
- // Build git command based on operation
89
- let gitArgs = [];
90
- switch (operation) {
91
- case 'status':
92
- gitArgs = ['status', '--porcelain=v1', ...args];
93
- break;
94
- case 'diff':
95
- gitArgs = ['diff', '--no-color', ...args, ...files];
96
- break;
97
- case 'log':
98
- gitArgs = [
99
- 'log',
100
- '--oneline',
101
- '--no-decorate',
102
- '-n', '20',
103
- ...args,
104
- ];
105
- break;
106
- case 'add':
107
- if (files.length === 0) {
108
- return {
109
- operation,
110
- success: false,
111
- output: '',
112
- error: 'No files specified to add',
113
- };
114
- }
115
- gitArgs = ['add', ...args, ...files];
116
- break;
117
- case 'commit':
118
- if (!message) {
119
- return {
120
- operation,
121
- success: false,
122
- output: '',
123
- error: 'Commit message required',
124
- };
125
- }
126
- gitArgs = ['commit', '-m', message, ...args];
127
- break;
128
- case 'branch':
129
- gitArgs = ['branch', '--no-color', ...args];
130
- break;
131
- case 'checkout':
132
- gitArgs = ['checkout', ...args, ...files];
133
- break;
134
- case 'stash':
135
- gitArgs = ['stash', ...args];
136
- break;
137
- case 'show':
138
- gitArgs = ['show', '--no-color', '--stat', ...args];
139
- break;
140
- case 'blame':
141
- if (files.length === 0) {
142
- return {
143
- operation,
144
- success: false,
145
- output: '',
146
- error: 'File path required for blame',
147
- };
148
- }
149
- gitArgs = ['blame', '--no-color', '-l', ...args, files[0]];
150
- break;
151
- default:
152
- return {
153
- operation,
154
- success: false,
155
- output: '',
156
- error: `Unknown operation: ${operation}`,
157
- };
158
- }
159
- return runGit(gitArgs, cwd);
160
- }
161
- // Get current branch
162
- export function getCurrentBranch(cwd = process.cwd()) {
163
- try {
164
- const result = execSync('git rev-parse --abbrev-ref HEAD', {
165
- cwd,
166
- encoding: 'utf-8',
167
- });
168
- return result.trim();
169
- }
170
- catch {
171
- return null;
172
- }
173
- }
174
- // Get list of changed files
175
- export function getChangedFiles(cwd = process.cwd()) {
176
- try {
177
- const result = execSync('git status --porcelain=v1', {
178
- cwd,
179
- encoding: 'utf-8',
180
- });
181
- return result
182
- .split('\n')
183
- .filter(Boolean)
184
- .map(line => line.slice(3).trim());
185
- }
186
- catch {
187
- return [];
188
- }
189
- }
190
- // Get list of tracked files
191
- export function getTrackedFiles(cwd = process.cwd()) {
192
- try {
193
- const result = execSync('git ls-files', {
194
- cwd,
195
- encoding: 'utf-8',
196
- });
197
- return result.split('\n').filter(Boolean);
198
- }
199
- catch {
200
- return [];
201
- }
202
- }
203
- // Check if file is ignored
204
- export function isIgnored(filePath, cwd = process.cwd()) {
205
- try {
206
- execSync(`git check-ignore -q "${filePath}"`, {
207
- cwd,
208
- encoding: 'utf-8',
209
- });
210
- return true;
211
- }
212
- catch {
213
- return false;
214
- }
215
- }
216
- // Get commit message for staged changes (using AI)
217
- export function getStagedDiff(cwd = process.cwd()) {
218
- try {
219
- const result = execSync('git diff --cached', {
220
- cwd,
221
- encoding: 'utf-8',
222
- });
223
- return result.trim() || null;
224
- }
225
- catch {
226
- return null;
227
- }
228
- }
229
- // Tool definition
230
- export const tool = {
231
- name: 'git',
232
- description: 'Perform git operations: status, diff, log, add, commit, branch, checkout, stash, show, blame',
233
- inputSchema,
234
- permission: 'execute',
235
- execute: async (args) => execute(args),
236
- };