thatgfsj-code 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.
- package/.patches/0001-fix-repl-replace-readline-with-inquirer-input-for-ke.patch +279 -0
- package/.patches/0002-fix-repl-stream-AI-output-directly-to-stdout-so-term.patch +564 -0
- package/.patches/0003-fix-session-break-the-hallucination-loop-in-assistan.patch +194 -0
- package/.patches/0004-chore-release-bump-version-to-0.2.1.patch +24 -0
- package/LICENSE +21 -0
- package/README.md +100 -0
- package/ROADMAP.md +107 -0
- package/dist/agent/core.d.ts +56 -0
- package/dist/agent/core.d.ts.map +1 -0
- package/dist/agent/core.js +142 -0
- package/dist/agent/core.js.map +1 -0
- package/dist/agent/index.d.ts +8 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +8 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/intent.d.ts +36 -0
- package/dist/agent/intent.d.ts.map +1 -0
- package/dist/agent/intent.js +146 -0
- package/dist/agent/intent.js.map +1 -0
- package/dist/agent/streaming.d.ts +50 -0
- package/dist/agent/streaming.d.ts.map +1 -0
- package/dist/agent/streaming.js +110 -0
- package/dist/agent/streaming.js.map +1 -0
- package/dist/core/ai-engine.d.ts +59 -0
- package/dist/core/ai-engine.d.ts.map +1 -0
- package/dist/core/ai-engine.js +378 -0
- package/dist/core/ai-engine.js.map +1 -0
- package/dist/core/cli.d.ts +21 -0
- package/dist/core/cli.d.ts.map +1 -0
- package/dist/core/cli.js +143 -0
- package/dist/core/cli.js.map +1 -0
- package/dist/core/config.d.ts +38 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +129 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/context-compactor.d.ts +54 -0
- package/dist/core/context-compactor.d.ts.map +1 -0
- package/dist/core/context-compactor.js +197 -0
- package/dist/core/context-compactor.js.map +1 -0
- package/dist/core/hooks.d.ts +75 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +146 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/permissions.d.ts +52 -0
- package/dist/core/permissions.d.ts.map +1 -0
- package/dist/core/permissions.js +237 -0
- package/dist/core/permissions.js.map +1 -0
- package/dist/core/session.d.ts +54 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +147 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/skills.d.ts +60 -0
- package/dist/core/skills.d.ts.map +1 -0
- package/dist/core/skills.js +175 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/state.d.ts +60 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +106 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/subagent.d.ts +68 -0
- package/dist/core/subagent.d.ts.map +1 -0
- package/dist/core/subagent.js +142 -0
- package/dist/core/subagent.js.map +1 -0
- package/dist/core/system-prompt.d.ts +40 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +138 -0
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/tool-registry.d.ts +53 -0
- package/dist/core/tool-registry.d.ts.map +1 -0
- package/dist/core/tool-registry.js +138 -0
- package/dist/core/tool-registry.js.map +1 -0
- package/dist/core/types.d.ts +206 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +127 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +481 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +83 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +267 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/repl/index.d.ts +8 -0
- package/dist/repl/index.d.ts.map +1 -0
- package/dist/repl/index.js +8 -0
- package/dist/repl/index.js.map +1 -0
- package/dist/repl/input.d.ts +61 -0
- package/dist/repl/input.d.ts.map +1 -0
- package/dist/repl/input.js +127 -0
- package/dist/repl/input.js.map +1 -0
- package/dist/repl/loop.d.ts +53 -0
- package/dist/repl/loop.d.ts.map +1 -0
- package/dist/repl/loop.js +241 -0
- package/dist/repl/loop.js.map +1 -0
- package/dist/repl/output.d.ts +105 -0
- package/dist/repl/output.d.ts.map +1 -0
- package/dist/repl/output.js +197 -0
- package/dist/repl/output.js.map +1 -0
- package/dist/repl/welcome.d.ts +68 -0
- package/dist/repl/welcome.d.ts.map +1 -0
- package/dist/repl/welcome.js +249 -0
- package/dist/repl/welcome.js.map +1 -0
- package/dist/tools/file.d.ts +46 -0
- package/dist/tools/file.d.ts.map +1 -0
- package/dist/tools/file.js +100 -0
- package/dist/tools/file.js.map +1 -0
- package/dist/tools/git.d.ts +52 -0
- package/dist/tools/git.d.ts.map +1 -0
- package/dist/tools/git.js +112 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/index.d.ts +22 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +43 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/search.d.ts +36 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +223 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/shell.d.ts +57 -0
- package/dist/tools/shell.d.ts.map +1 -0
- package/dist/tools/shell.js +153 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/utils/diff-preview.d.ts +42 -0
- package/dist/utils/diff-preview.d.ts.map +1 -0
- package/dist/utils/diff-preview.js +174 -0
- package/dist/utils/diff-preview.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/memory.d.ts +81 -0
- package/dist/utils/memory.d.ts.map +1 -0
- package/dist/utils/memory.js +186 -0
- package/dist/utils/memory.js.map +1 -0
- package/dist/utils/project-context.d.ts +62 -0
- package/dist/utils/project-context.d.ts.map +1 -0
- package/dist/utils/project-context.js +197 -0
- package/dist/utils/project-context.js.map +1 -0
- package/docs/API_KEY_GUIDE.md +236 -0
- package/docs/FAQ.md +182 -0
- package/install.bat +63 -0
- package/install.ps1 +238 -0
- package/install.sh +113 -0
- package/package.json +36 -0
- package/src/agent/core.ts +179 -0
- package/src/agent/index.ts +8 -0
- package/src/agent/intent.ts +181 -0
- package/src/agent/streaming.ts +132 -0
- package/src/core/ai-engine.ts +437 -0
- package/src/core/cli.ts +171 -0
- package/src/core/config.ts +147 -0
- package/src/core/context-compactor.ts +245 -0
- package/src/core/hooks.ts +196 -0
- package/src/core/permissions.ts +308 -0
- package/src/core/session.ts +165 -0
- package/src/core/skills.ts +208 -0
- package/src/core/state.ts +120 -0
- package/src/core/subagent.ts +195 -0
- package/src/core/system-prompt.ts +163 -0
- package/src/core/tool-registry.ts +157 -0
- package/src/core/types.ts +280 -0
- package/src/index.ts +544 -0
- package/src/mcp/client.ts +330 -0
- package/src/repl/index.ts +8 -0
- package/src/repl/input.ts +139 -0
- package/src/repl/loop.ts +280 -0
- package/src/repl/output.ts +222 -0
- package/src/repl/welcome.ts +296 -0
- package/src/tools/file.ts +117 -0
- package/src/tools/git.ts +132 -0
- package/src/tools/index.ts +48 -0
- package/src/tools/search.ts +263 -0
- package/src/tools/shell.ts +181 -0
- package/src/utils/diff-preview.ts +202 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/memory.ts +223 -0
- package/src/utils/project-context.ts +207 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tools Module
|
|
3
|
+
* Built-in tools + Plugin loading
|
|
4
|
+
*/
|
|
5
|
+
import { FileTool } from './file.js';
|
|
6
|
+
import { ShellTool } from './shell.js';
|
|
7
|
+
import { GitTool } from './git.js';
|
|
8
|
+
import { SearchTool } from './search.js';
|
|
9
|
+
/**
|
|
10
|
+
* Get all built-in tools
|
|
11
|
+
*/
|
|
12
|
+
export function getBuiltInTools() {
|
|
13
|
+
return [
|
|
14
|
+
new FileTool(),
|
|
15
|
+
new ShellTool(),
|
|
16
|
+
new GitTool(),
|
|
17
|
+
new SearchTool()
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Tool descriptions for AI
|
|
22
|
+
*/
|
|
23
|
+
export function getToolDescriptions() {
|
|
24
|
+
return {
|
|
25
|
+
file: 'File operations: read, write, list, delete, exists, mkdir',
|
|
26
|
+
shell: 'Execute shell commands (npm, git, node, etc.)',
|
|
27
|
+
git: 'Git operations: status, log, diff, commit, branch, checkout, pull, push',
|
|
28
|
+
search: 'Search code: grep, find files, directory tree'
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Load custom tools from config (future)
|
|
33
|
+
*/
|
|
34
|
+
export async function loadCustomTools(config) {
|
|
35
|
+
// TODO: Implement plugin loading from config
|
|
36
|
+
// Example: load from ~/.thatgfsj/tools/*.js
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
export { FileTool } from './file.js';
|
|
40
|
+
export { ShellTool } from './shell.js';
|
|
41
|
+
export { GitTool } from './git.js';
|
|
42
|
+
export { SearchTool } from './search.js';
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,IAAI,QAAQ,EAAE;QACd,IAAI,SAAS,EAAE;QACf,IAAI,OAAO,EAAE;QACb,IAAI,UAAU,EAAE;KACjB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO;QACL,IAAI,EAAE,2DAA2D;QACjE,KAAK,EAAE,+CAA+C;QACtD,GAAG,EAAE,yEAAyE;QAC9E,MAAM,EAAE,+CAA+C;KACxD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAA2B;IAC/D,6CAA6C;IAC7C,4CAA4C;IAC5C,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search Tool - Code search and file operations
|
|
3
|
+
*/
|
|
4
|
+
import { Tool, ToolResult } from '../core/types.js';
|
|
5
|
+
export declare class SearchTool implements Tool {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
parameters: {
|
|
9
|
+
name: string;
|
|
10
|
+
type: string;
|
|
11
|
+
description: string;
|
|
12
|
+
required: boolean;
|
|
13
|
+
}[];
|
|
14
|
+
execute(params: Record<string, any>): Promise<ToolResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Grep - search for pattern in files
|
|
17
|
+
*/
|
|
18
|
+
private grep;
|
|
19
|
+
/**
|
|
20
|
+
* Find - find files by pattern
|
|
21
|
+
*/
|
|
22
|
+
private find;
|
|
23
|
+
/**
|
|
24
|
+
* Tree - show directory structure
|
|
25
|
+
*/
|
|
26
|
+
private tree;
|
|
27
|
+
/**
|
|
28
|
+
* List files in directory
|
|
29
|
+
*/
|
|
30
|
+
private listFiles;
|
|
31
|
+
/**
|
|
32
|
+
* Simple glob-like pattern matching
|
|
33
|
+
*/
|
|
34
|
+
private matchPattern;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAQpD,qBAAa,UAAW,YAAW,IAAI;IACrC,IAAI,SAAY;IAChB,WAAW,SAA4D;IAEvE,UAAU;;;;;QAKR;IAEI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IA2B/D;;OAEG;YACW,IAAI;IA+ClB;;OAEG;YACW,IAAI;IA6DlB;;OAEG;YACW,IAAI;IAwClB;;OAEG;YACW,SAAS;IAmCvB;;OAEG;IACH,OAAO,CAAC,YAAY;CAcrB"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search Tool - Code search and file operations
|
|
3
|
+
*/
|
|
4
|
+
import { exec } from 'child_process';
|
|
5
|
+
import { promisify } from 'util';
|
|
6
|
+
import { readdirSync, statSync } from 'fs';
|
|
7
|
+
import { join, relative } from 'path';
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
export class SearchTool {
|
|
10
|
+
name = 'search';
|
|
11
|
+
description = 'Search and find: grep, find files, list directory tree';
|
|
12
|
+
parameters = [
|
|
13
|
+
{ name: 'action', type: 'string', description: 'Action: grep, find, tree, files', required: true },
|
|
14
|
+
{ name: 'pattern', type: 'string', description: 'Search pattern or file pattern', required: false },
|
|
15
|
+
{ name: 'path', type: 'string', description: 'Directory to search in', required: false },
|
|
16
|
+
{ name: 'options', type: 'string', description: 'Additional options', required: false }
|
|
17
|
+
];
|
|
18
|
+
async execute(params) {
|
|
19
|
+
const { action, pattern, path, options } = params;
|
|
20
|
+
const workDir = path || process.cwd();
|
|
21
|
+
try {
|
|
22
|
+
switch (action) {
|
|
23
|
+
case 'grep':
|
|
24
|
+
case 'search':
|
|
25
|
+
return await this.grep(pattern || '', workDir, options || '');
|
|
26
|
+
case 'find':
|
|
27
|
+
return await this.find(pattern || '*', workDir);
|
|
28
|
+
case 'tree':
|
|
29
|
+
return await this.tree(workDir, parseInt(options) || 3);
|
|
30
|
+
case 'files':
|
|
31
|
+
return await this.listFiles(workDir, pattern || '*');
|
|
32
|
+
default:
|
|
33
|
+
return { success: false, error: `Unknown action: ${action}` };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
return { success: false, error: error.message };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Grep - search for pattern in files
|
|
42
|
+
*/
|
|
43
|
+
async grep(pattern, path, options) {
|
|
44
|
+
if (!pattern) {
|
|
45
|
+
return { success: false, error: 'Pattern required' };
|
|
46
|
+
}
|
|
47
|
+
// Build grep command
|
|
48
|
+
let cmd = `grep -rn "${pattern}" "${path}"`;
|
|
49
|
+
if (options?.includes('i'))
|
|
50
|
+
cmd += ' -i'; // Case insensitive
|
|
51
|
+
if (options?.includes('w'))
|
|
52
|
+
cmd += ' -w'; // Whole word
|
|
53
|
+
if (options?.includes('l'))
|
|
54
|
+
cmd += ' -l'; // Files only
|
|
55
|
+
if (options?.includes('n'))
|
|
56
|
+
cmd += ' -n'; // Line numbers
|
|
57
|
+
cmd += ' --color=never';
|
|
58
|
+
try {
|
|
59
|
+
const { stdout, stderr } = await execAsync(cmd, { timeout: 30000 });
|
|
60
|
+
if (!stdout && stderr) {
|
|
61
|
+
return { success: false, error: stderr };
|
|
62
|
+
}
|
|
63
|
+
const lines = (stdout || '').split('\n').filter(l => l.trim());
|
|
64
|
+
if (lines.length === 0) {
|
|
65
|
+
return { success: true, output: 'No matches found' };
|
|
66
|
+
}
|
|
67
|
+
// Limit output
|
|
68
|
+
const limited = lines.slice(0, 50);
|
|
69
|
+
const output = limited.join('\n');
|
|
70
|
+
return {
|
|
71
|
+
success: true,
|
|
72
|
+
output: lines.length > 50
|
|
73
|
+
? output + `\n... and ${lines.length - 50} more matches`
|
|
74
|
+
: output
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (error.killed) {
|
|
79
|
+
return { success: false, error: 'Search timed out (>30s)' };
|
|
80
|
+
}
|
|
81
|
+
return { success: false, error: error.message };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Find - find files by pattern
|
|
86
|
+
*/
|
|
87
|
+
async find(pattern, path) {
|
|
88
|
+
if (!pattern) {
|
|
89
|
+
pattern = '*';
|
|
90
|
+
}
|
|
91
|
+
const results = [];
|
|
92
|
+
const search = (dir, depth) => {
|
|
93
|
+
if (depth > 5)
|
|
94
|
+
return; // Max depth
|
|
95
|
+
try {
|
|
96
|
+
const items = readdirSync(dir);
|
|
97
|
+
for (const item of items) {
|
|
98
|
+
// Skip common ignored directories
|
|
99
|
+
if (item === 'node_modules' || item === '.git' || item === 'dist' || item === 'build') {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const fullPath = join(dir, item);
|
|
103
|
+
try {
|
|
104
|
+
const stat = statSync(fullPath);
|
|
105
|
+
if (stat.isDirectory()) {
|
|
106
|
+
// Check if matches pattern
|
|
107
|
+
if (this.matchPattern(item, pattern)) {
|
|
108
|
+
results.push(fullPath);
|
|
109
|
+
}
|
|
110
|
+
search(fullPath, depth + 1);
|
|
111
|
+
}
|
|
112
|
+
else if (stat.isFile()) {
|
|
113
|
+
if (this.matchPattern(item, pattern)) {
|
|
114
|
+
results.push(fullPath);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// Skip inaccessible files
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Skip inaccessible directories
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
search(path, 0);
|
|
128
|
+
if (results.length === 0) {
|
|
129
|
+
return { success: true, output: 'No files found' };
|
|
130
|
+
}
|
|
131
|
+
const limited = results.slice(0, 100);
|
|
132
|
+
const output = limited.join('\n');
|
|
133
|
+
return {
|
|
134
|
+
success: true,
|
|
135
|
+
output: results.length > 100
|
|
136
|
+
? output + `\n... and ${results.length - 100} more files`
|
|
137
|
+
: output
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Tree - show directory structure
|
|
142
|
+
*/
|
|
143
|
+
async tree(path, maxDepth) {
|
|
144
|
+
const lines = [];
|
|
145
|
+
const walk = (dir, prefix, depth) => {
|
|
146
|
+
if (depth > maxDepth)
|
|
147
|
+
return;
|
|
148
|
+
try {
|
|
149
|
+
const items = readdirSync(dir).filter(i => !i.startsWith('.') && i !== 'node_modules' && i !== 'dist');
|
|
150
|
+
for (let i = 0; i < items.length; i++) {
|
|
151
|
+
const item = items[i];
|
|
152
|
+
const fullPath = join(dir, item);
|
|
153
|
+
const isLast = i === items.length - 1;
|
|
154
|
+
const connector = isLast ? '└── ' : '├── ';
|
|
155
|
+
lines.push(prefix + connector + item);
|
|
156
|
+
try {
|
|
157
|
+
const stat = statSync(fullPath);
|
|
158
|
+
if (stat.isDirectory()) {
|
|
159
|
+
const newPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
160
|
+
walk(fullPath, newPrefix, depth + 1);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
// Skip
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// Skip inaccessible
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
lines.push(relative(process.cwd(), path) || '.');
|
|
173
|
+
walk(path, '', 0);
|
|
174
|
+
return { success: true, output: lines.join('\n') };
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* List files in directory
|
|
178
|
+
*/
|
|
179
|
+
async listFiles(path, pattern) {
|
|
180
|
+
const files = [];
|
|
181
|
+
const scan = (dir) => {
|
|
182
|
+
try {
|
|
183
|
+
const items = readdirSync(dir);
|
|
184
|
+
for (const item of items) {
|
|
185
|
+
if (item === 'node_modules' || item === '.git')
|
|
186
|
+
continue;
|
|
187
|
+
const fullPath = join(dir, item);
|
|
188
|
+
try {
|
|
189
|
+
const stat = statSync(fullPath);
|
|
190
|
+
if (stat.isFile() && this.matchPattern(item, pattern)) {
|
|
191
|
+
files.push(relative(process.cwd(), fullPath));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// Skip
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// Skip
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
scan(path);
|
|
204
|
+
if (files.length === 0) {
|
|
205
|
+
return { success: true, output: 'No files found' };
|
|
206
|
+
}
|
|
207
|
+
return { success: true, output: files.join('\n') };
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Simple glob-like pattern matching
|
|
211
|
+
*/
|
|
212
|
+
matchPattern(filename, pattern) {
|
|
213
|
+
if (pattern === '*')
|
|
214
|
+
return true;
|
|
215
|
+
// Convert glob to regex
|
|
216
|
+
const regex = new RegExp('^' + pattern
|
|
217
|
+
.replace(/\./g, '\\.')
|
|
218
|
+
.replace(/\*/g, '.*')
|
|
219
|
+
.replace(/\?/g, '.') + '$', 'i');
|
|
220
|
+
return regex.test(filename);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell Tool - Execute shell commands with security checks
|
|
3
|
+
*/
|
|
4
|
+
import { Tool, ToolResult, ToolContext } from '../core/types.js';
|
|
5
|
+
import { PermissionChecker } from '../core/permissions.js';
|
|
6
|
+
export declare function setPermissionChecker(checker: PermissionChecker): void;
|
|
7
|
+
export declare class ShellTool implements Tool {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
/** S02: Input schema for shell command */
|
|
11
|
+
inputSchema: {
|
|
12
|
+
type: "object";
|
|
13
|
+
properties: {
|
|
14
|
+
command: {
|
|
15
|
+
type: string;
|
|
16
|
+
description: string;
|
|
17
|
+
};
|
|
18
|
+
cwd: {
|
|
19
|
+
type: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
timeout: {
|
|
23
|
+
type: string;
|
|
24
|
+
description: string;
|
|
25
|
+
default: number;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
required: string[];
|
|
29
|
+
};
|
|
30
|
+
/** S02: Tool metadata — permission and category info */
|
|
31
|
+
metadata: {
|
|
32
|
+
permissions: ("read" | "write" | "execute" | "network")[];
|
|
33
|
+
tags: string[];
|
|
34
|
+
maxDuration: number;
|
|
35
|
+
version: string;
|
|
36
|
+
};
|
|
37
|
+
parameters: {
|
|
38
|
+
name: string;
|
|
39
|
+
type: string;
|
|
40
|
+
description: string;
|
|
41
|
+
required: boolean;
|
|
42
|
+
}[];
|
|
43
|
+
/**
|
|
44
|
+
* Check if command is dangerous
|
|
45
|
+
*/
|
|
46
|
+
private isDangerous;
|
|
47
|
+
/**
|
|
48
|
+
* Check if command needs confirmation
|
|
49
|
+
*/
|
|
50
|
+
private needsConfirmation;
|
|
51
|
+
/**
|
|
52
|
+
* Validate command before execution
|
|
53
|
+
*/
|
|
54
|
+
private validateCommand;
|
|
55
|
+
execute(params: Record<string, any>, ctx?: ToolContext): Promise<ToolResult>;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=shell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/tools/shell.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAO3D,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,QAE9D;AAkCD,qBAAa,SAAU,YAAW,IAAI;IACpC,IAAI,SAAW;IACf,WAAW,SAAqG;IAEhH,0CAA0C;IAC1C,WAAW;;;;;;;;;;;;;;;;;;MAQT;IAEF,wDAAwD;IACxD,QAAQ;qBAC0C,CAAC,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC,EAAE;;;;MAI5F;IAEF,UAAU;;;;;QAIR;IAEF;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAKzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAoBjB,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAiEnF"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell Tool - Execute shell commands with security checks
|
|
3
|
+
*/
|
|
4
|
+
import { exec } from 'child_process';
|
|
5
|
+
import { promisify } from 'util';
|
|
6
|
+
// Shared permission checker instance
|
|
7
|
+
let permissionChecker = null;
|
|
8
|
+
export function setPermissionChecker(checker) {
|
|
9
|
+
permissionChecker = checker;
|
|
10
|
+
}
|
|
11
|
+
const execAsync = promisify(exec);
|
|
12
|
+
// Dangerous command patterns
|
|
13
|
+
const DANGEROUS_PATTERNS = [
|
|
14
|
+
/^rm\s+-rf\s+\//i, // rm -rf /
|
|
15
|
+
/^del\s+\/f\s+\/s\s+\/q/i, // del /f /s /q
|
|
16
|
+
/^format\s+[a-z]:/i, // format c:
|
|
17
|
+
/^mkfs/i, // mkfs
|
|
18
|
+
/^dd\s+if=/i, // dd if=
|
|
19
|
+
/^shred/i, // shred
|
|
20
|
+
/^cat\s+\/dev\/null\s*>/i, // cat /dev/null >
|
|
21
|
+
/>\s*\/dev\/sda/i, // Write to disk
|
|
22
|
+
/^rm\s+-rf\s+\$HOME/i, // rm -rf $HOME
|
|
23
|
+
/^rm\s+-rf\s+%USERPROFILE%/i // Windows user profile
|
|
24
|
+
];
|
|
25
|
+
// Commands that need confirmation
|
|
26
|
+
const CONFIRM_REQUIRED = [
|
|
27
|
+
'rm -rf',
|
|
28
|
+
'rmdir',
|
|
29
|
+
'del /s /q',
|
|
30
|
+
'format',
|
|
31
|
+
'mkfs',
|
|
32
|
+
'dd',
|
|
33
|
+
'shutdown',
|
|
34
|
+
'restart',
|
|
35
|
+
'init 0',
|
|
36
|
+
'init 6',
|
|
37
|
+
'poweroff',
|
|
38
|
+
'reboot'
|
|
39
|
+
];
|
|
40
|
+
export class ShellTool {
|
|
41
|
+
name = 'shell';
|
|
42
|
+
description = 'Execute shell commands and scripts. Use with caution - some commands require user confirmation.';
|
|
43
|
+
/** S02: Input schema for shell command */
|
|
44
|
+
inputSchema = {
|
|
45
|
+
type: 'object',
|
|
46
|
+
properties: {
|
|
47
|
+
command: { type: 'string', description: 'Shell command to execute' },
|
|
48
|
+
cwd: { type: 'string', description: 'Working directory' },
|
|
49
|
+
timeout: { type: 'number', description: 'Timeout in seconds', default: 30 }
|
|
50
|
+
},
|
|
51
|
+
required: ['command']
|
|
52
|
+
};
|
|
53
|
+
/** S02: Tool metadata — permission and category info */
|
|
54
|
+
metadata = {
|
|
55
|
+
permissions: ['execute', 'write', 'network'],
|
|
56
|
+
tags: ['shell', 'system', 'dangerous'],
|
|
57
|
+
maxDuration: 120000, // 2 min max
|
|
58
|
+
version: '1.0.0'
|
|
59
|
+
};
|
|
60
|
+
parameters = [
|
|
61
|
+
{ name: 'command', type: 'string', description: 'Shell command to execute', required: true },
|
|
62
|
+
{ name: 'cwd', type: 'string', description: 'Working directory', required: false },
|
|
63
|
+
{ name: 'timeout', type: 'number', description: 'Timeout in seconds', required: false }
|
|
64
|
+
];
|
|
65
|
+
/**
|
|
66
|
+
* Check if command is dangerous
|
|
67
|
+
*/
|
|
68
|
+
isDangerous(command) {
|
|
69
|
+
return DANGEROUS_PATTERNS.some(pattern => pattern.test(command.trim()));
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if command needs confirmation
|
|
73
|
+
*/
|
|
74
|
+
needsConfirmation(command) {
|
|
75
|
+
const lower = command.toLowerCase();
|
|
76
|
+
return CONFIRM_REQUIRED.some(cmd => lower.includes(cmd.toLowerCase()));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Validate command before execution
|
|
80
|
+
*/
|
|
81
|
+
validateCommand(command) {
|
|
82
|
+
if (!command || typeof command !== 'string') {
|
|
83
|
+
return 'Command is required and must be a string';
|
|
84
|
+
}
|
|
85
|
+
const trimmed = command.trim();
|
|
86
|
+
// Check for dangerous commands
|
|
87
|
+
if (this.isDangerous(trimmed)) {
|
|
88
|
+
return `Dangerous command blocked: ${trimmed.substring(0, 50)}...`;
|
|
89
|
+
}
|
|
90
|
+
// Check command length
|
|
91
|
+
if (trimmed.length > 10000) {
|
|
92
|
+
return 'Command too long (max 10000 characters)';
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
async execute(params, ctx) {
|
|
97
|
+
const { command, cwd, timeout = 30 } = params;
|
|
98
|
+
// Validate command
|
|
99
|
+
const validationError = this.validateCommand(command);
|
|
100
|
+
if (validationError) {
|
|
101
|
+
return { success: false, error: validationError };
|
|
102
|
+
}
|
|
103
|
+
// S03: 6-stage permission check
|
|
104
|
+
if (permissionChecker) {
|
|
105
|
+
const result = await permissionChecker.check('shell', params, ctx || {});
|
|
106
|
+
if (!result.allowed) {
|
|
107
|
+
return { success: false, error: `Permission denied: ${result.reason}` };
|
|
108
|
+
}
|
|
109
|
+
if (result.requiresConfirmation) {
|
|
110
|
+
// Ask user for confirmation
|
|
111
|
+
if (ctx?.confirmAction) {
|
|
112
|
+
const confirmed = await ctx.confirmAction(`⚠️ Confirm command:\n ${command}\n\n[y] Yes [n] No`);
|
|
113
|
+
if (!confirmed) {
|
|
114
|
+
return { success: false, error: 'Command cancelled by user' };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (ctx?.confirmAction && this.needsConfirmation(command)) {
|
|
120
|
+
// Fallback confirmation
|
|
121
|
+
const confirmed = await ctx.confirmAction(`Execute this command?\n ${command}\n\nType 'y' to confirm or 'n' to cancel:`);
|
|
122
|
+
if (!confirmed) {
|
|
123
|
+
return { success: false, error: 'Command cancelled by user' };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
const options = {
|
|
128
|
+
timeout: timeout * 1000,
|
|
129
|
+
maxBuffer: 10 * 1024 * 1024 // 10MB
|
|
130
|
+
};
|
|
131
|
+
if (cwd) {
|
|
132
|
+
options.cwd = cwd;
|
|
133
|
+
}
|
|
134
|
+
const { stdout, stderr } = await execAsync(command, options);
|
|
135
|
+
const stdoutStr = stdout?.toString() || '';
|
|
136
|
+
const stderrStr = stderr?.toString() || '';
|
|
137
|
+
// Combine output, prioritize stdout
|
|
138
|
+
const output = stdoutStr + (stderrStr ? `\n[stderr]: ${stderrStr}` : '');
|
|
139
|
+
return { success: true, output: output.trim() || '(command executed successfully with no output)' };
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
// Handle timeout
|
|
143
|
+
if (error.killed) {
|
|
144
|
+
return { success: false, error: 'Command timed out' };
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
success: false,
|
|
148
|
+
error: error.message || 'Command execution failed'
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/tools/shell.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,IAAI,EAAS,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,qCAAqC;AACrC,IAAI,iBAAiB,GAA6B,IAAI,CAAC;AAEvD,MAAM,UAAU,oBAAoB,CAAC,OAA0B;IAC7D,iBAAiB,GAAG,OAAO,CAAC;AAC9B,CAAC;AAED,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC,6BAA6B;AAC7B,MAAM,kBAAkB,GAAG;IACzB,iBAAiB,EAAY,WAAW;IACxC,yBAAyB,EAAI,eAAe;IAC5C,mBAAmB,EAAU,YAAY;IACzC,QAAQ,EAAsB,OAAO;IACrC,YAAY,EAAkB,SAAS;IACvC,SAAS,EAAqB,QAAQ;IACtC,yBAAyB,EAAI,kBAAkB;IAC/C,iBAAiB,EAAY,gBAAgB;IAC7C,qBAAqB,EAAQ,eAAe;IAC5C,4BAA4B,CAAC,uBAAuB;CACrD,CAAC;AAEF,kCAAkC;AAClC,MAAM,gBAAgB,GAAG;IACvB,QAAQ;IACR,OAAO;IACP,WAAW;IACX,QAAQ;IACR,MAAM;IACN,IAAI;IACJ,UAAU;IACV,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,QAAQ;CACT,CAAC;AAEF,MAAM,OAAO,SAAS;IACpB,IAAI,GAAG,OAAO,CAAC;IACf,WAAW,GAAG,iGAAiG,CAAC;IAEhH,0CAA0C;IAC1C,WAAW,GAAG;QACZ,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0BAA0B,EAAE;YACpE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE;YACzD,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE,OAAO,EAAE,EAAE,EAAE;SAC5E;QACD,QAAQ,EAAE,CAAC,SAAS,CAAC;KACtB,CAAC;IAEF,wDAAwD;IACxD,QAAQ,GAAG;QACT,WAAW,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,CAAiD;QAC5F,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC;QACtC,WAAW,EAAE,MAAM,EAAE,YAAY;QACjC,OAAO,EAAE,OAAO;KACjB,CAAC;IAEF,UAAU,GAAG;QACX,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0BAA0B,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC5F,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE,QAAQ,EAAE,KAAK,EAAE;QAClF,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE,QAAQ,EAAE,KAAK,EAAE;KACxF,CAAC;IAEF;;OAEG;IACK,WAAW,CAAC,OAAe;QACjC,OAAO,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,OAAe;QACvC,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QACpC,OAAO,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACzE,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,OAAe;QACrC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC5C,OAAO,0CAA0C,CAAC;QACpD,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAE/B,+BAA+B;QAC/B,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,OAAO,8BAA8B,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC;QACrE,CAAC;QAED,uBAAuB;QACvB,IAAI,OAAO,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;YAC3B,OAAO,yCAAyC,CAAC;QACnD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAA2B,EAAE,GAAiB;QAC1D,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC;QAE9C,mBAAmB;QACnB,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;QACpD,CAAC;QAED,gCAAgC;QAChC,IAAI,iBAAiB,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;YACzE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1E,CAAC;YACD,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC;gBAChC,4BAA4B;gBAC5B,IAAI,GAAG,EAAE,aAAa,EAAE,CAAC;oBACvB,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,aAAa,CACvC,2BAA2B,OAAO,qBAAqB,CACxD,CAAC;oBACF,IAAI,CAAC,SAAS,EAAE,CAAC;wBACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC;oBAChE,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,GAAG,EAAE,aAAa,IAAI,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAC;YACjE,wBAAwB;YACxB,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,4BAA4B,OAAO,2CAA2C,CAAC,CAAC;YAC1H,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC;YAChE,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAQ;gBACnB,OAAO,EAAE,OAAO,GAAG,IAAI;gBACvB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,OAAO;aACpC,CAAC;YAEF,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;YACpB,CAAC;YAED,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7D,MAAM,SAAS,GAAG,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YAC3C,MAAM,SAAS,GAAG,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YAE3C,oCAAoC;YACpC,MAAM,MAAM,GAAG,SAAS,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAEzE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,gDAAgD,EAAE,CAAC;QAEtG,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,iBAAiB;YACjB,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;YACxD,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,0BAA0B;aACnD,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff Preview - Show file changes before modification
|
|
3
|
+
* Simple implementation without external dependencies
|
|
4
|
+
*/
|
|
5
|
+
export interface DiffResult {
|
|
6
|
+
hasChanges: boolean;
|
|
7
|
+
oldContent?: string;
|
|
8
|
+
newContent?: string;
|
|
9
|
+
diff?: string;
|
|
10
|
+
preview?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare class DiffPreview {
|
|
13
|
+
/**
|
|
14
|
+
* Compare old and new content and generate diff
|
|
15
|
+
*/
|
|
16
|
+
static compare(oldContent: string, newContent: string): DiffResult;
|
|
17
|
+
/**
|
|
18
|
+
* Compute simple line-by-line diff
|
|
19
|
+
*/
|
|
20
|
+
private static computeDiff;
|
|
21
|
+
/**
|
|
22
|
+
* Find longest common subsequence
|
|
23
|
+
*/
|
|
24
|
+
private static longestCommonSubsequence;
|
|
25
|
+
/**
|
|
26
|
+
* Show diff between file and proposed changes
|
|
27
|
+
*/
|
|
28
|
+
static diffFile(filePath: string, newContent: string): DiffResult;
|
|
29
|
+
/**
|
|
30
|
+
* Format diff for display with colors
|
|
31
|
+
*/
|
|
32
|
+
private static formatDiff;
|
|
33
|
+
/**
|
|
34
|
+
* Format a compact preview
|
|
35
|
+
*/
|
|
36
|
+
private static formatPreview;
|
|
37
|
+
/**
|
|
38
|
+
* Check if changes are significant
|
|
39
|
+
*/
|
|
40
|
+
static isSignificant(oldContent: string, newContent: string, threshold?: number): boolean;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=diff-preview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-preview.d.ts","sourceRoot":"","sources":["../../src/utils/diff-preview.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,WAAW;IACtB;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU;IAmBlE;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IA+C1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,wBAAwB;IAiCvC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU;IAcjE;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,UAAU;IAoBzB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAgB5B;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,GAAG,OAAO;CAU/F"}
|