grokcodecli 0.1.0

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 (99) hide show
  1. package/.claude/settings.local.json +32 -0
  2. package/README.md +1464 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +61 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/loader.d.ts +34 -0
  8. package/dist/commands/loader.d.ts.map +1 -0
  9. package/dist/commands/loader.js +192 -0
  10. package/dist/commands/loader.js.map +1 -0
  11. package/dist/config/manager.d.ts +21 -0
  12. package/dist/config/manager.d.ts.map +1 -0
  13. package/dist/config/manager.js +203 -0
  14. package/dist/config/manager.js.map +1 -0
  15. package/dist/conversation/chat.d.ts +50 -0
  16. package/dist/conversation/chat.d.ts.map +1 -0
  17. package/dist/conversation/chat.js +1145 -0
  18. package/dist/conversation/chat.js.map +1 -0
  19. package/dist/conversation/history.d.ts +24 -0
  20. package/dist/conversation/history.d.ts.map +1 -0
  21. package/dist/conversation/history.js +103 -0
  22. package/dist/conversation/history.js.map +1 -0
  23. package/dist/grok/client.d.ts +86 -0
  24. package/dist/grok/client.d.ts.map +1 -0
  25. package/dist/grok/client.js +106 -0
  26. package/dist/grok/client.js.map +1 -0
  27. package/dist/index.d.ts +7 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +8 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/permissions/manager.d.ts +26 -0
  32. package/dist/permissions/manager.d.ts.map +1 -0
  33. package/dist/permissions/manager.js +170 -0
  34. package/dist/permissions/manager.js.map +1 -0
  35. package/dist/tools/bash.d.ts +8 -0
  36. package/dist/tools/bash.d.ts.map +1 -0
  37. package/dist/tools/bash.js +102 -0
  38. package/dist/tools/bash.js.map +1 -0
  39. package/dist/tools/edit.d.ts +9 -0
  40. package/dist/tools/edit.d.ts.map +1 -0
  41. package/dist/tools/edit.js +61 -0
  42. package/dist/tools/edit.js.map +1 -0
  43. package/dist/tools/glob.d.ts +7 -0
  44. package/dist/tools/glob.d.ts.map +1 -0
  45. package/dist/tools/glob.js +38 -0
  46. package/dist/tools/glob.js.map +1 -0
  47. package/dist/tools/grep.d.ts +8 -0
  48. package/dist/tools/grep.d.ts.map +1 -0
  49. package/dist/tools/grep.js +78 -0
  50. package/dist/tools/grep.js.map +1 -0
  51. package/dist/tools/read.d.ts +8 -0
  52. package/dist/tools/read.d.ts.map +1 -0
  53. package/dist/tools/read.js +96 -0
  54. package/dist/tools/read.js.map +1 -0
  55. package/dist/tools/registry.d.ts +42 -0
  56. package/dist/tools/registry.d.ts.map +1 -0
  57. package/dist/tools/registry.js +230 -0
  58. package/dist/tools/registry.js.map +1 -0
  59. package/dist/tools/webfetch.d.ts +10 -0
  60. package/dist/tools/webfetch.d.ts.map +1 -0
  61. package/dist/tools/webfetch.js +108 -0
  62. package/dist/tools/webfetch.js.map +1 -0
  63. package/dist/tools/websearch.d.ts +7 -0
  64. package/dist/tools/websearch.d.ts.map +1 -0
  65. package/dist/tools/websearch.js +180 -0
  66. package/dist/tools/websearch.js.map +1 -0
  67. package/dist/tools/write.d.ts +7 -0
  68. package/dist/tools/write.d.ts.map +1 -0
  69. package/dist/tools/write.js +80 -0
  70. package/dist/tools/write.js.map +1 -0
  71. package/dist/utils/security.d.ts +36 -0
  72. package/dist/utils/security.d.ts.map +1 -0
  73. package/dist/utils/security.js +227 -0
  74. package/dist/utils/security.js.map +1 -0
  75. package/dist/utils/ui.d.ts +49 -0
  76. package/dist/utils/ui.d.ts.map +1 -0
  77. package/dist/utils/ui.js +302 -0
  78. package/dist/utils/ui.js.map +1 -0
  79. package/package.json +45 -0
  80. package/src/cli.ts +68 -0
  81. package/src/commands/loader.ts +244 -0
  82. package/src/config/manager.ts +239 -0
  83. package/src/conversation/chat.ts +1294 -0
  84. package/src/conversation/history.ts +131 -0
  85. package/src/grok/client.ts +192 -0
  86. package/src/index.ts +8 -0
  87. package/src/permissions/manager.ts +208 -0
  88. package/src/tools/bash.ts +119 -0
  89. package/src/tools/edit.ts +73 -0
  90. package/src/tools/glob.ts +49 -0
  91. package/src/tools/grep.ts +96 -0
  92. package/src/tools/read.ts +116 -0
  93. package/src/tools/registry.ts +248 -0
  94. package/src/tools/webfetch.ts +127 -0
  95. package/src/tools/websearch.ts +219 -0
  96. package/src/tools/write.ts +94 -0
  97. package/src/utils/security.ts +259 -0
  98. package/src/utils/ui.ts +382 -0
  99. package/tsconfig.json +22 -0
@@ -0,0 +1,170 @@
1
+ import * as readline from 'readline';
2
+ import chalk from 'chalk';
3
+ const TOOL_RISK_LEVELS = {
4
+ Read: 'read',
5
+ Glob: 'read',
6
+ Grep: 'read',
7
+ Write: 'write',
8
+ Edit: 'write',
9
+ Bash: 'execute',
10
+ WebFetch: 'read',
11
+ };
12
+ const RISK_COLORS = {
13
+ read: chalk.green,
14
+ write: chalk.yellow,
15
+ execute: chalk.red,
16
+ };
17
+ const RISK_ICONS = {
18
+ read: '📖',
19
+ write: '✏️',
20
+ execute: '⚡',
21
+ };
22
+ export class PermissionManager {
23
+ config;
24
+ rl = null;
25
+ constructor(autoApprove = []) {
26
+ this.config = {
27
+ autoApprove,
28
+ alwaysDeny: [],
29
+ sessionApproved: new Set(),
30
+ };
31
+ }
32
+ setReadlineInterface(rl) {
33
+ this.rl = rl;
34
+ }
35
+ async requestPermission(request) {
36
+ const { tool, description, riskLevel, details } = request;
37
+ // Check if always denied
38
+ if (this.config.alwaysDeny.includes(tool)) {
39
+ console.log(chalk.red(`\n⛔ Tool "${tool}" is blocked by configuration.\n`));
40
+ return false;
41
+ }
42
+ // Check if auto-approved
43
+ if (this.config.autoApprove.includes(tool) || this.config.autoApprove.includes('*')) {
44
+ return true;
45
+ }
46
+ // Check if approved for this session
47
+ const sessionKey = this.getSessionKey(tool, details);
48
+ if (this.config.sessionApproved.has(sessionKey)) {
49
+ return true;
50
+ }
51
+ // Read-only operations can be auto-approved with lower risk
52
+ if (riskLevel === 'read' && this.config.autoApprove.includes('read')) {
53
+ return true;
54
+ }
55
+ // Prompt user for permission
56
+ return this.promptUser(request);
57
+ }
58
+ async promptUser(request) {
59
+ const { tool, description, riskLevel, details } = request;
60
+ const color = RISK_COLORS[riskLevel];
61
+ const icon = RISK_ICONS[riskLevel];
62
+ console.log(chalk.cyan('\n┌─────────────────────────────────────────────────────┐'));
63
+ console.log(chalk.cyan('│') + ` ${icon} ${color(`Permission Request: ${tool}`)}`.padEnd(60) + chalk.cyan('│'));
64
+ console.log(chalk.cyan('├─────────────────────────────────────────────────────┤'));
65
+ console.log(chalk.cyan('│') + ` ${description}`.padEnd(52) + chalk.cyan('│'));
66
+ // Show details
67
+ if (details) {
68
+ console.log(chalk.cyan('├─────────────────────────────────────────────────────┤'));
69
+ for (const [key, value] of Object.entries(details)) {
70
+ const valueStr = typeof value === 'string'
71
+ ? value.length > 45 ? value.slice(0, 42) + '...' : value
72
+ : String(value);
73
+ console.log(chalk.cyan('│') + chalk.gray(` ${key}: `) + valueStr.padEnd(42 - key.length) + chalk.cyan('│'));
74
+ }
75
+ }
76
+ console.log(chalk.cyan('└─────────────────────────────────────────────────────┘'));
77
+ console.log();
78
+ console.log(` ${chalk.green('[y]')} Yes, allow once`);
79
+ console.log(` ${chalk.green('[a]')} Allow for this session`);
80
+ console.log(` ${chalk.red('[n]')} No, deny`);
81
+ console.log(` ${chalk.red('[!]')} Deny and block for session`);
82
+ console.log();
83
+ const answer = await this.question(chalk.cyan('Choice [y/a/n/!]: '));
84
+ const choice = answer.toLowerCase().trim();
85
+ switch (choice) {
86
+ case 'y':
87
+ case 'yes':
88
+ return true;
89
+ case 'a':
90
+ case 'always':
91
+ this.config.sessionApproved.add(this.getSessionKey(tool, details));
92
+ console.log(chalk.green(`✓ "${tool}" approved for this session.\n`));
93
+ return true;
94
+ case 'n':
95
+ case 'no':
96
+ case '':
97
+ console.log(chalk.yellow('⊘ Denied.\n'));
98
+ return false;
99
+ case '!':
100
+ case 'block':
101
+ this.config.alwaysDeny.push(tool);
102
+ console.log(chalk.red(`⛔ "${tool}" blocked for this session.\n`));
103
+ return false;
104
+ default:
105
+ console.log(chalk.gray('Invalid choice, defaulting to deny.\n'));
106
+ return false;
107
+ }
108
+ }
109
+ getSessionKey(tool, details) {
110
+ // For some tools, scope approval to specific paths/commands
111
+ if (tool === 'Bash' && details?.command) {
112
+ // Approve specific command patterns
113
+ const cmd = String(details.command);
114
+ if (cmd.startsWith('git '))
115
+ return `${tool}:git`;
116
+ if (cmd.startsWith('npm '))
117
+ return `${tool}:npm`;
118
+ if (cmd.startsWith('ls ') || cmd === 'ls')
119
+ return `${tool}:ls`;
120
+ return tool;
121
+ }
122
+ if ((tool === 'Read' || tool === 'Write' || tool === 'Edit') && details?.file_path) {
123
+ // Could scope to directory
124
+ return tool;
125
+ }
126
+ return tool;
127
+ }
128
+ question(prompt) {
129
+ return new Promise((resolve) => {
130
+ if (this.rl) {
131
+ this.rl.question(prompt, resolve);
132
+ }
133
+ else {
134
+ // Fallback if no readline interface
135
+ const tempRl = readline.createInterface({
136
+ input: process.stdin,
137
+ output: process.stdout,
138
+ });
139
+ tempRl.question(prompt, (answer) => {
140
+ tempRl.close();
141
+ resolve(answer);
142
+ });
143
+ }
144
+ });
145
+ }
146
+ getToolRiskLevel(tool) {
147
+ return TOOL_RISK_LEVELS[tool] || 'execute';
148
+ }
149
+ formatToolDetails(tool, params) {
150
+ switch (tool) {
151
+ case 'Read':
152
+ return `Read file: ${params.file_path}`;
153
+ case 'Write':
154
+ return `Write to file: ${params.file_path}`;
155
+ case 'Edit':
156
+ return `Edit file: ${params.file_path}`;
157
+ case 'Bash':
158
+ return `Execute command: ${params.command}`;
159
+ case 'Glob':
160
+ return `Search for files: ${params.pattern}`;
161
+ case 'Grep':
162
+ return `Search in files: ${params.pattern}`;
163
+ case 'WebFetch':
164
+ return `Fetch URL: ${params.url}`;
165
+ default:
166
+ return `Execute ${tool}`;
167
+ }
168
+ }
169
+ }
170
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/permissions/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { ToolResult } from './registry.js';
2
+ export interface BashToolParams {
3
+ command: string;
4
+ timeout?: number;
5
+ cwd?: string;
6
+ }
7
+ export declare function bashTool(params: BashToolParams): Promise<ToolResult>;
8
+ //# sourceMappingURL=bash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAI3C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAKD,wBAAsB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAwG1E"}
@@ -0,0 +1,102 @@
1
+ import { spawn } from 'child_process';
2
+ import { validateCommand, sanitizeOutput } from '../utils/security.js';
3
+ import chalk from 'chalk';
4
+ // Maximum output size to prevent memory issues
5
+ const MAX_OUTPUT_SIZE = 1024 * 1024; // 1MB
6
+ export async function bashTool(params) {
7
+ const timeout = params.timeout ?? 120000; // 2 minutes default
8
+ // Security validation
9
+ const security = validateCommand(params.command);
10
+ if (!security.allowed) {
11
+ return {
12
+ success: false,
13
+ output: '',
14
+ error: `Security: ${security.reason}${security.suggestion ? ` - ${security.suggestion}` : ''}`,
15
+ };
16
+ }
17
+ // Warn about risky commands but allow them
18
+ let warning = '';
19
+ if (security.severity === 'medium') {
20
+ warning = chalk.yellow(`⚠️ ${security.reason}\n`);
21
+ }
22
+ return new Promise((resolve) => {
23
+ let stdout = '';
24
+ let stderr = '';
25
+ let killed = false;
26
+ let outputTruncated = false;
27
+ const child = spawn('bash', ['-c', params.command], {
28
+ cwd: params.cwd || process.cwd(),
29
+ env: {
30
+ ...process.env,
31
+ // Prevent color codes from commands that might interfere
32
+ FORCE_COLOR: '0',
33
+ NO_COLOR: '1',
34
+ },
35
+ });
36
+ const timer = setTimeout(() => {
37
+ killed = true;
38
+ child.kill('SIGTERM');
39
+ // Force kill after 5 seconds if still running
40
+ setTimeout(() => {
41
+ try {
42
+ child.kill('SIGKILL');
43
+ }
44
+ catch {
45
+ // Already dead
46
+ }
47
+ }, 5000);
48
+ }, timeout);
49
+ child.stdout.on('data', (data) => {
50
+ if (stdout.length < MAX_OUTPUT_SIZE) {
51
+ stdout += data.toString();
52
+ }
53
+ else if (!outputTruncated) {
54
+ outputTruncated = true;
55
+ stdout += '\n... (output truncated)';
56
+ }
57
+ });
58
+ child.stderr.on('data', (data) => {
59
+ if (stderr.length < MAX_OUTPUT_SIZE) {
60
+ stderr += data.toString();
61
+ }
62
+ });
63
+ child.on('close', (code, signal) => {
64
+ clearTimeout(timer);
65
+ if (killed) {
66
+ resolve({
67
+ success: false,
68
+ output: sanitizeOutput(stdout),
69
+ error: `Command timed out after ${timeout / 1000}s and was terminated`,
70
+ });
71
+ return;
72
+ }
73
+ // Combine and sanitize output
74
+ let output = sanitizeOutput(stdout);
75
+ if (stderr && code !== 0) {
76
+ output += (output ? '\n' : '') + chalk.red('stderr: ') + sanitizeOutput(stderr);
77
+ }
78
+ if (code === 0) {
79
+ resolve({
80
+ success: true,
81
+ output: warning + (output.trim() || '(command completed with no output)'),
82
+ });
83
+ }
84
+ else {
85
+ resolve({
86
+ success: false,
87
+ output: output.trim(),
88
+ error: sanitizeOutput(stderr.trim()) || `Command exited with code ${code}${signal ? ` (signal: ${signal})` : ''}`,
89
+ });
90
+ }
91
+ });
92
+ child.on('error', (error) => {
93
+ clearTimeout(timer);
94
+ resolve({
95
+ success: false,
96
+ output: '',
97
+ error: `Failed to execute command: ${error.message}`,
98
+ });
99
+ });
100
+ });
101
+ }
102
+ //# sourceMappingURL=bash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { ToolResult } from './registry.js';
2
+ export interface EditToolParams {
3
+ file_path: string;
4
+ old_string: string;
5
+ new_string: string;
6
+ replace_all?: boolean;
7
+ }
8
+ export declare function editTool(params: EditToolParams): Promise<ToolResult>;
9
+ //# sourceMappingURL=edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CA6D1E"}
@@ -0,0 +1,61 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as path from 'path';
3
+ export async function editTool(params) {
4
+ try {
5
+ const filePath = path.resolve(params.file_path);
6
+ // Read existing content
7
+ let content;
8
+ try {
9
+ content = await fs.readFile(filePath, 'utf-8');
10
+ }
11
+ catch (error) {
12
+ const err = error;
13
+ if (err.code === 'ENOENT') {
14
+ return { success: false, output: '', error: `File not found: ${params.file_path}` };
15
+ }
16
+ throw error;
17
+ }
18
+ // Check if old_string exists
19
+ if (!content.includes(params.old_string)) {
20
+ return {
21
+ success: false,
22
+ output: '',
23
+ error: `String not found in file. Make sure the old_string matches exactly including whitespace.`,
24
+ };
25
+ }
26
+ // Check for uniqueness if not replace_all
27
+ if (!params.replace_all) {
28
+ const occurrences = content.split(params.old_string).length - 1;
29
+ if (occurrences > 1) {
30
+ return {
31
+ success: false,
32
+ output: '',
33
+ error: `Found ${occurrences} occurrences of the string. Use replace_all: true to replace all, or provide a more specific string.`,
34
+ };
35
+ }
36
+ }
37
+ // Perform replacement
38
+ let newContent;
39
+ let replacements;
40
+ if (params.replace_all) {
41
+ const parts = content.split(params.old_string);
42
+ replacements = parts.length - 1;
43
+ newContent = parts.join(params.new_string);
44
+ }
45
+ else {
46
+ newContent = content.replace(params.old_string, params.new_string);
47
+ replacements = 1;
48
+ }
49
+ // Write back
50
+ await fs.writeFile(filePath, newContent, 'utf-8');
51
+ return {
52
+ success: true,
53
+ output: `File edited successfully: ${filePath} (${replacements} replacement${replacements > 1 ? 's' : ''})`,
54
+ };
55
+ }
56
+ catch (error) {
57
+ const err = error;
58
+ return { success: false, output: '', error: `Error editing file: ${err.message}` };
59
+ }
60
+ }
61
+ //# sourceMappingURL=edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAU7B,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAsB;IACnD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAEhD,wBAAwB;QACxB,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,KAA8B,CAAC;YAC3C,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC1B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,mBAAmB,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;YACtF,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QAED,6BAA6B;QAC7B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,EAAE;gBACV,KAAK,EAAE,0FAA0F;aAClG,CAAC;QACJ,CAAC;QAED,0CAA0C;QAC1C,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACxB,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAChE,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBACpB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,MAAM,EAAE,EAAE;oBACV,KAAK,EAAE,SAAS,WAAW,sGAAsG;iBAClI,CAAC;YACJ,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,IAAI,UAAkB,CAAC;QACvB,IAAI,YAAoB,CAAC;QAEzB,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC/C,YAAY,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YAChC,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;YACnE,YAAY,GAAG,CAAC,CAAC;QACnB,CAAC;QAED,aAAa;QACb,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QAElD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,6BAA6B,QAAQ,KAAK,YAAY,eAAe,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG;SAC5G,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAc,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,uBAAuB,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;IACrF,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { ToolResult } from './registry.js';
2
+ export interface GlobToolParams {
3
+ pattern: string;
4
+ path?: string;
5
+ }
6
+ export declare function globTool(params: GlobToolParams): Promise<ToolResult>;
7
+ //# sourceMappingURL=glob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../src/tools/glob.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAuC1E"}
@@ -0,0 +1,38 @@
1
+ import { glob } from 'glob';
2
+ import * as path from 'path';
3
+ export async function globTool(params) {
4
+ try {
5
+ const cwd = params.path ? path.resolve(params.path) : process.cwd();
6
+ const matches = await glob(params.pattern, {
7
+ cwd,
8
+ nodir: true,
9
+ absolute: false,
10
+ ignore: ['node_modules/**', '.git/**', 'dist/**', 'build/**'],
11
+ });
12
+ if (matches.length === 0) {
13
+ return {
14
+ success: true,
15
+ output: 'No files found matching the pattern.',
16
+ };
17
+ }
18
+ // Sort by path
19
+ matches.sort();
20
+ // Limit output to prevent overwhelming responses
21
+ const maxResults = 100;
22
+ const limited = matches.slice(0, maxResults);
23
+ const remaining = matches.length - maxResults;
24
+ let output = limited.join('\n');
25
+ if (remaining > 0) {
26
+ output += `\n\n... and ${remaining} more files`;
27
+ }
28
+ return {
29
+ success: true,
30
+ output: `Found ${matches.length} file(s):\n${output}`,
31
+ };
32
+ }
33
+ catch (error) {
34
+ const err = error;
35
+ return { success: false, output: '', error: `Glob error: ${err.message}` };
36
+ }
37
+ }
38
+ //# sourceMappingURL=glob.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.js","sourceRoot":"","sources":["../../src/tools/glob.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAQ7B,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAsB;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAEpE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;YACzC,GAAG;YACH,KAAK,EAAE,IAAI;YACX,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,CAAC,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC;SAC9D,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,sCAAsC;aAC/C,CAAC;QACJ,CAAC;QAED,eAAe;QACf,OAAO,CAAC,IAAI,EAAE,CAAC;QAEf,iDAAiD;QACjD,MAAM,UAAU,GAAG,GAAG,CAAC;QACvB,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC;QAE9C,IAAI,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,eAAe,SAAS,aAAa,CAAC;QAClD,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,SAAS,OAAO,CAAC,MAAM,cAAc,MAAM,EAAE;SACtD,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAc,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,eAAe,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;IAC7E,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { ToolResult } from './registry.js';
2
+ export interface GrepToolParams {
3
+ pattern: string;
4
+ path?: string;
5
+ include?: string;
6
+ }
7
+ export declare function grepTool(params: GrepToolParams): Promise<ToolResult>;
8
+ //# sourceMappingURL=grep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../src/tools/grep.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAsF1E"}
@@ -0,0 +1,78 @@
1
+ import { spawn } from 'child_process';
2
+ export async function grepTool(params) {
3
+ return new Promise((resolve) => {
4
+ const args = [
5
+ '--color=never',
6
+ '-r',
7
+ '-n',
8
+ '-H',
9
+ '--include=*.{ts,tsx,js,jsx,json,md,py,go,rs,java,kt,swift,c,cpp,h,hpp,css,scss,html,xml,yaml,yml,toml}',
10
+ ];
11
+ if (params.include) {
12
+ args.push(`--include=${params.include}`);
13
+ }
14
+ // Exclude common directories
15
+ args.push('--exclude-dir=node_modules');
16
+ args.push('--exclude-dir=.git');
17
+ args.push('--exclude-dir=dist');
18
+ args.push('--exclude-dir=build');
19
+ args.push('--exclude-dir=.next');
20
+ args.push('-E'); // Extended regex
21
+ args.push(params.pattern);
22
+ args.push(params.path || '.');
23
+ const child = spawn('grep', args, {
24
+ cwd: process.cwd(),
25
+ });
26
+ let stdout = '';
27
+ let stderr = '';
28
+ child.stdout.on('data', (data) => {
29
+ stdout += data.toString();
30
+ });
31
+ child.stderr.on('data', (data) => {
32
+ stderr += data.toString();
33
+ });
34
+ child.on('close', (code) => {
35
+ // grep returns 1 if no matches, which is not an error
36
+ if (code === 1 && !stderr) {
37
+ resolve({
38
+ success: true,
39
+ output: 'No matches found.',
40
+ });
41
+ return;
42
+ }
43
+ if (code !== 0 && code !== 1) {
44
+ resolve({
45
+ success: false,
46
+ output: '',
47
+ error: stderr || `grep exited with code ${code}`,
48
+ });
49
+ return;
50
+ }
51
+ // Limit output
52
+ const lines = stdout.trim().split('\n').filter(Boolean);
53
+ const maxResults = 50;
54
+ if (lines.length > maxResults) {
55
+ const output = lines.slice(0, maxResults).join('\n');
56
+ resolve({
57
+ success: true,
58
+ output: `Found ${lines.length} matches (showing first ${maxResults}):\n${output}`,
59
+ });
60
+ }
61
+ else {
62
+ resolve({
63
+ success: true,
64
+ output: lines.length > 0 ? `Found ${lines.length} match(es):\n${stdout.trim()}` : 'No matches found.',
65
+ });
66
+ }
67
+ });
68
+ child.on('error', (error) => {
69
+ // Fall back to ripgrep if grep is not available
70
+ resolve({
71
+ success: false,
72
+ output: '',
73
+ error: `grep error: ${error.message}`,
74
+ });
75
+ });
76
+ });
77
+ }
78
+ //# sourceMappingURL=grep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../src/tools/grep.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { ToolResult } from './registry.js';
2
+ export interface ReadToolParams {
3
+ file_path: string;
4
+ offset?: number;
5
+ limit?: number;
6
+ }
7
+ export declare function readTool(params: ReadToolParams): Promise<ToolResult>;
8
+ //# sourceMappingURL=read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAI3C,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAQD,wBAAsB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAiG1E"}
@@ -0,0 +1,96 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as path from 'path';
3
+ import { validatePath } from '../utils/security.js';
4
+ import chalk from 'chalk';
5
+ // Maximum file size to read (10MB)
6
+ const MAX_FILE_SIZE = 10 * 1024 * 1024;
7
+ // Maximum lines to return
8
+ const MAX_LINES = 2000;
9
+ export async function readTool(params) {
10
+ try {
11
+ const filePath = path.resolve(params.file_path);
12
+ // Security validation
13
+ const security = validatePath(filePath);
14
+ if (!security.allowed) {
15
+ return {
16
+ success: false,
17
+ output: '',
18
+ error: `Security: ${security.reason}`,
19
+ };
20
+ }
21
+ // Check file stats first
22
+ let stats;
23
+ try {
24
+ stats = await fs.stat(filePath);
25
+ }
26
+ catch (error) {
27
+ const err = error;
28
+ if (err.code === 'ENOENT') {
29
+ return { success: false, output: '', error: `File not found: ${params.file_path}` };
30
+ }
31
+ throw error;
32
+ }
33
+ if (stats.isDirectory()) {
34
+ return { success: false, output: '', error: `Path is a directory: ${params.file_path}` };
35
+ }
36
+ if (stats.size > MAX_FILE_SIZE) {
37
+ return {
38
+ success: false,
39
+ output: '',
40
+ error: `File too large (${(stats.size / 1024 / 1024).toFixed(1)}MB). Maximum is ${MAX_FILE_SIZE / 1024 / 1024}MB. Use offset/limit to read portions.`,
41
+ };
42
+ }
43
+ // Read the file
44
+ const content = await fs.readFile(filePath, 'utf-8');
45
+ // Handle binary files
46
+ if (content.includes('\0')) {
47
+ return {
48
+ success: false,
49
+ output: '',
50
+ error: 'File appears to be binary. Cannot display binary content.',
51
+ };
52
+ }
53
+ const lines = content.split('\n');
54
+ const totalLines = lines.length;
55
+ const offset = Math.max(0, (params.offset ?? 1) - 1);
56
+ const limit = Math.min(params.limit ?? MAX_LINES, MAX_LINES);
57
+ const selectedLines = lines.slice(offset, offset + limit);
58
+ // Format with line numbers like cat -n
59
+ const padding = String(totalLines).length;
60
+ const output = selectedLines
61
+ .map((line, i) => {
62
+ const lineNum = offset + i + 1;
63
+ // Truncate very long lines
64
+ const displayLine = line.length > 2000 ? line.slice(0, 2000) + '...' : line;
65
+ return `${String(lineNum).padStart(padding)}${chalk.gray('│')} ${displayLine}`;
66
+ })
67
+ .join('\n');
68
+ // Add metadata
69
+ let header = '';
70
+ if (offset > 0 || selectedLines.length < totalLines) {
71
+ header = chalk.gray(`Showing lines ${offset + 1}-${offset + selectedLines.length} of ${totalLines}\n`);
72
+ }
73
+ // Security warning if applicable
74
+ if (security.severity === 'medium') {
75
+ header = chalk.yellow(`⚠️ ${security.suggestion}\n`) + header;
76
+ }
77
+ return {
78
+ success: true,
79
+ output: header + (output || '(empty file)'),
80
+ };
81
+ }
82
+ catch (error) {
83
+ const err = error;
84
+ if (err.code === 'ENOENT') {
85
+ return { success: false, output: '', error: `File not found: ${params.file_path}` };
86
+ }
87
+ if (err.code === 'EACCES') {
88
+ return { success: false, output: '', error: `Permission denied: ${params.file_path}` };
89
+ }
90
+ if (err.code === 'EISDIR') {
91
+ return { success: false, output: '', error: `Path is a directory: ${params.file_path}` };
92
+ }
93
+ return { success: false, output: '', error: `Error reading file: ${err.message}` };
94
+ }
95
+ }
96
+ //# sourceMappingURL=read.js.map