codepage-bridge-mcp 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 (97) hide show
  1. package/.claude-plugin/marketplace.json +19 -0
  2. package/.claude-plugin/plugin.json +15 -0
  3. package/.mcp.json +11 -0
  4. package/LICENSE +21 -0
  5. package/README.md +990 -0
  6. package/README_CN.md +781 -0
  7. package/dist/src/core.d.ts +56 -0
  8. package/dist/src/core.js +166 -0
  9. package/dist/src/core.js.map +1 -0
  10. package/dist/src/diff.d.ts +8 -0
  11. package/dist/src/diff.js +11 -0
  12. package/dist/src/diff.js.map +1 -0
  13. package/dist/src/encoding/codec.d.ts +5 -0
  14. package/dist/src/encoding/codec.js +75 -0
  15. package/dist/src/encoding/codec.js.map +1 -0
  16. package/dist/src/encoding/index.d.ts +3 -0
  17. package/dist/src/encoding/index.js +4 -0
  18. package/dist/src/encoding/index.js.map +1 -0
  19. package/dist/src/encoding/rules.d.ts +4 -0
  20. package/dist/src/encoding/rules.js +70 -0
  21. package/dist/src/encoding/rules.js.map +1 -0
  22. package/dist/src/encoding/types.d.ts +22 -0
  23. package/dist/src/encoding/types.js +2 -0
  24. package/dist/src/encoding/types.js.map +1 -0
  25. package/dist/src/filesystem/atomic.d.ts +6 -0
  26. package/dist/src/filesystem/atomic.js +91 -0
  27. package/dist/src/filesystem/atomic.js.map +1 -0
  28. package/dist/src/filesystem/cache.d.ts +21 -0
  29. package/dist/src/filesystem/cache.js +40 -0
  30. package/dist/src/filesystem/cache.js.map +1 -0
  31. package/dist/src/filesystem/index.d.ts +4 -0
  32. package/dist/src/filesystem/index.js +5 -0
  33. package/dist/src/filesystem/index.js.map +1 -0
  34. package/dist/src/filesystem/mutex.d.ts +5 -0
  35. package/dist/src/filesystem/mutex.js +23 -0
  36. package/dist/src/filesystem/mutex.js.map +1 -0
  37. package/dist/src/filesystem/path.d.ts +9 -0
  38. package/dist/src/filesystem/path.js +53 -0
  39. package/dist/src/filesystem/path.js.map +1 -0
  40. package/dist/src/media/errors.d.ts +14 -0
  41. package/dist/src/media/errors.js +29 -0
  42. package/dist/src/media/errors.js.map +1 -0
  43. package/dist/src/media/image.d.ts +11 -0
  44. package/dist/src/media/image.js +81 -0
  45. package/dist/src/media/image.js.map +1 -0
  46. package/dist/src/media/index.d.ts +5 -0
  47. package/dist/src/media/index.js +6 -0
  48. package/dist/src/media/index.js.map +1 -0
  49. package/dist/src/media/notebook.d.ts +47 -0
  50. package/dist/src/media/notebook.js +122 -0
  51. package/dist/src/media/notebook.js.map +1 -0
  52. package/dist/src/media/pdf.d.ts +25 -0
  53. package/dist/src/media/pdf.js +104 -0
  54. package/dist/src/media/pdf.js.map +1 -0
  55. package/dist/src/media/types.d.ts +14 -0
  56. package/dist/src/media/types.js +2 -0
  57. package/dist/src/media/types.js.map +1 -0
  58. package/dist/src/prompts.d.ts +8 -0
  59. package/dist/src/prompts.js +46 -0
  60. package/dist/src/prompts.js.map +1 -0
  61. package/dist/src/schemas.d.ts +138 -0
  62. package/dist/src/schemas.js +81 -0
  63. package/dist/src/schemas.js.map +1 -0
  64. package/dist/src/server.d.ts +159 -0
  65. package/dist/src/server.js +98 -0
  66. package/dist/src/server.js.map +1 -0
  67. package/dist/src/toolTypes.d.ts +31 -0
  68. package/dist/src/toolTypes.js +2 -0
  69. package/dist/src/toolTypes.js.map +1 -0
  70. package/dist/src/tools/edit.d.ts +3 -0
  71. package/dist/src/tools/edit.js +168 -0
  72. package/dist/src/tools/edit.js.map +1 -0
  73. package/dist/src/tools/grep.d.ts +21 -0
  74. package/dist/src/tools/grep.js +192 -0
  75. package/dist/src/tools/grep.js.map +1 -0
  76. package/dist/src/tools/read.d.ts +3 -0
  77. package/dist/src/tools/read.js +137 -0
  78. package/dist/src/tools/read.js.map +1 -0
  79. package/dist/src/tools/write.d.ts +3 -0
  80. package/dist/src/tools/write.js +80 -0
  81. package/dist/src/tools/write.js.map +1 -0
  82. package/dist/src/validation.d.ts +6 -0
  83. package/dist/src/validation.js +42 -0
  84. package/dist/src/validation.js.map +1 -0
  85. package/examples/claude-config/settings.fragment.json +17 -0
  86. package/examples/minimal-project/.encoding-rules +10 -0
  87. package/examples/minimal-project/.mcp.json +11 -0
  88. package/examples/minimal-project/CLAUDE.md +15 -0
  89. package/install/download-release-unix.sh +72 -0
  90. package/install/download-release-windows.ps1 +61 -0
  91. package/install/install-from-release-unix.sh +18 -0
  92. package/install/install-from-release-windows.ps1 +19 -0
  93. package/install/install-from-source-unix.sh +44 -0
  94. package/install/install-from-source-windows.ps1 +45 -0
  95. package/install/install-this-release-unix.sh +37 -0
  96. package/install/install-this-release-windows.ps1 +36 -0
  97. package/package.json +64 -0
@@ -0,0 +1,168 @@
1
+ import { mkdir, stat } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { getProjectFileContext, encodeSnapshotText, readDecodedFile, readRegistry } from '../core.js';
4
+ import { createStructuredPatch } from '../diff.js';
5
+ import { atomicWriteBuffer } from '../filesystem/index.js';
6
+ import { assertObject, optionalBoolean, rejectUnknown, requiredString, } from '../validation.js';
7
+ const MAX_EDIT_BYTES = 1024 * 1024 * 1024;
8
+ const SMART_QUOTES = new Map([
9
+ ['‘', "'"], ['’', "'"], ['‚', "'"], ['‛', "'"],
10
+ ['“', '"'], ['”', '"'], ['„', '"'], ['‟', '"'],
11
+ ]);
12
+ export function parseEditInput(value) {
13
+ assertObject(value);
14
+ rejectUnknown(value, ['file_path', 'old_string', 'new_string', 'replace_all']);
15
+ const replace_all = optionalBoolean(value, 'replace_all');
16
+ return {
17
+ file_path: requiredString(value, 'file_path'),
18
+ old_string: requiredString(value, 'old_string'),
19
+ new_string: requiredString(value, 'new_string'),
20
+ ...(replace_all === undefined ? {} : { replace_all }),
21
+ };
22
+ }
23
+ function normalizeQuotes(text) {
24
+ return [...text].map(character => SMART_QUOTES.get(character) ?? character).join('');
25
+ }
26
+ function lineRangeForMatch(content, match) {
27
+ const startLine = content.slice(0, match.index).split('\n').length;
28
+ const endLine = startLine + match.actual.split('\n').length - 1;
29
+ return { startLine, endLine };
30
+ }
31
+ function findQuoteMatches(content, search) {
32
+ const matches = [];
33
+ const normalizedSearch = normalizeQuotes(search);
34
+ for (let index = 0; index <= content.length - search.length; index += 1) {
35
+ const candidate = content.slice(index, index + search.length);
36
+ if (normalizeQuotes(candidate) === normalizedSearch) {
37
+ matches.push({ index, actual: candidate });
38
+ index += Math.max(0, search.length - 1);
39
+ }
40
+ }
41
+ return matches;
42
+ }
43
+ function adaptReplacementQuotes(replacement, actual, requested) {
44
+ const style = new Map();
45
+ for (let index = 0; index < Math.min(actual.length, requested.length); index += 1) {
46
+ const normalized = normalizeQuotes(requested[index] ?? '');
47
+ const actualCharacter = actual[index];
48
+ if ((normalized === "'" || normalized === '"') && actualCharacter) {
49
+ style.set(normalized, actualCharacter);
50
+ }
51
+ }
52
+ return [...replacement].map(character => style.get(normalizeQuotes(character)) ?? character).join('');
53
+ }
54
+ function replaceText(content, oldString, newString, replaceAll, matches = findQuoteMatches(content, oldString)) {
55
+ if (matches.length === 0)
56
+ throw new Error('old_string not found in file');
57
+ if (matches.length > 1 && !replaceAll) {
58
+ throw new Error(`Found ${matches.length} matches of old_string. Provide more surrounding context or set replace_all to true.`);
59
+ }
60
+ const selected = replaceAll ? matches : matches.slice(0, 1);
61
+ let next = content;
62
+ for (const match of [...selected].reverse()) {
63
+ const replacement = adaptReplacementQuotes(newString, match.actual, oldString);
64
+ let end = match.index + match.actual.length;
65
+ if (replacement.length === 0 && !match.actual.endsWith('\n') && next[end] === '\n')
66
+ end += 1;
67
+ next = `${next.slice(0, match.index)}${replacement}${next.slice(end)}`;
68
+ }
69
+ return { content: next, actual: matches[0].actual, count: matches.length };
70
+ }
71
+ export async function executeEdit(input) {
72
+ if (input.old_string === input.new_string)
73
+ throw new Error('old_string and new_string must be different');
74
+ if (path.extname(input.file_path).toLowerCase() === '.ipynb') {
75
+ throw new Error('Editing Jupyter notebooks is not supported');
76
+ }
77
+ const context = await getProjectFileContext(input.file_path);
78
+ let exists = true;
79
+ try {
80
+ const info = await stat(context.absolutePath);
81
+ if (info.size > MAX_EDIT_BYTES)
82
+ throw new Error('File exceeds the 1 GiB edit limit');
83
+ }
84
+ catch (error) {
85
+ if (error.code !== 'ENOENT')
86
+ throw error;
87
+ exists = false;
88
+ }
89
+ if (!exists) {
90
+ if (input.old_string !== '')
91
+ throw new Error(`File does not exist: ${input.file_path}`);
92
+ await mkdir(path.dirname(context.absolutePath), { recursive: true });
93
+ const snapshot = {
94
+ absolutePath: context.absolutePath,
95
+ root: context.root,
96
+ encoding: context.encoding,
97
+ text: '',
98
+ bom: null,
99
+ newline: null,
100
+ mtimeMs: 0,
101
+ size: 0,
102
+ hash: '',
103
+ complete: true,
104
+ };
105
+ const buffer = encodeSnapshotText(snapshot, input.new_string);
106
+ await atomicWriteBuffer(context.root, context.absolutePath, buffer);
107
+ const info = await stat(context.absolutePath);
108
+ readRegistry.updateAfterWrite(snapshot, input.new_string, buffer, info.mtimeMs);
109
+ return {
110
+ content: [{ type: 'text', text: `The file ${context.absolutePath} has been created successfully.` }],
111
+ structuredContent: {
112
+ filePath: context.absolutePath,
113
+ oldString: '',
114
+ newString: input.new_string,
115
+ originalFile: '',
116
+ structuredPatch: createStructuredPatch(context.absolutePath, '', input.new_string),
117
+ userModified: false,
118
+ replaceAll: false,
119
+ },
120
+ };
121
+ }
122
+ const current = await readDecodedFile(context);
123
+ if (input.old_string === '' && current.text.trim().length > 0) {
124
+ throw new Error('Cannot use an empty old_string to overwrite a non-empty file');
125
+ }
126
+ const matches = input.old_string === '' ? [] : findQuoteMatches(current.text, input.old_string);
127
+ if (input.old_string !== '' && matches.length === 0)
128
+ throw new Error('old_string not found in file');
129
+ if (matches.length > 1 && !(input.replace_all ?? false)) {
130
+ throw new Error(`Found ${matches.length} matches of old_string. Provide more surrounding context or set replace_all to true.`);
131
+ }
132
+ const selectedMatches = input.replace_all ? matches : matches.slice(0, 1);
133
+ const authorization = readRegistry.authorizeEdit(context.absolutePath, current.hash, selectedMatches.map(match => lineRangeForMatch(current.text, match)));
134
+ if (authorization.status === 'unread') {
135
+ throw new Error('File has not been read. Read the target lines before attempting to edit them.');
136
+ }
137
+ if (authorization.status === 'changed') {
138
+ throw new Error('File has been unexpectedly modified. Read the target lines again before attempting to write it.');
139
+ }
140
+ if (authorization.status === 'uncovered') {
141
+ const ranges = authorization.missing
142
+ .map(range => range.startLine === range.endLine ? String(range.startLine) : `${range.startLine}-${range.endLine}`)
143
+ .join(', ');
144
+ throw new Error(`The target text has not been read. Read line range(s) ${ranges} before attempting this edit.`);
145
+ }
146
+ const result = input.old_string === ''
147
+ ? { content: input.new_string, actual: '', count: 1 }
148
+ : replaceText(current.text, input.old_string, input.new_string, input.replace_all ?? false, matches);
149
+ const buffer = encodeSnapshotText(current, result.content);
150
+ await atomicWriteBuffer(context.root, context.absolutePath, buffer, {
151
+ expected: { mtimeMs: current.mtimeMs, hash: current.hash },
152
+ });
153
+ const info = await stat(context.absolutePath);
154
+ readRegistry.updateAfterWrite(current, result.content, buffer, info.mtimeMs);
155
+ return {
156
+ content: [{ type: 'text', text: `The file ${context.absolutePath} has been updated successfully.` }],
157
+ structuredContent: {
158
+ filePath: context.absolutePath,
159
+ oldString: result.actual,
160
+ newString: input.new_string,
161
+ originalFile: current.text,
162
+ structuredPatch: createStructuredPatch(context.absolutePath, current.text, result.content),
163
+ userModified: false,
164
+ replaceAll: input.replace_all ?? false,
165
+ },
166
+ };
167
+ }
168
+ //# sourceMappingURL=edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/tools/edit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ToolResponse } from '../toolTypes.js';
2
+ export type GrepOutputMode = 'content' | 'files_with_matches' | 'count';
3
+ export interface GrepInput {
4
+ pattern: string;
5
+ path?: string;
6
+ glob?: string;
7
+ type?: string;
8
+ output_mode?: GrepOutputMode;
9
+ '-i'?: boolean;
10
+ '-n'?: boolean;
11
+ '-o'?: boolean;
12
+ '-A'?: number;
13
+ '-B'?: number;
14
+ '-C'?: number;
15
+ context?: number;
16
+ multiline?: boolean;
17
+ head_limit?: number;
18
+ offset?: number;
19
+ }
20
+ export declare function parseGrepInput(value: unknown): GrepInput;
21
+ export declare function executeGrep(input: GrepInput): Promise<ToolResponse>;
@@ -0,0 +1,192 @@
1
+ import { readdir, stat } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import picomatch from 'picomatch';
4
+ import { getProjectFileContext, readDecodedFile } from '../core.js';
5
+ import { assertObject, optionalBoolean, optionalInteger, optionalString, rejectUnknown, requiredString, } from '../validation.js';
6
+ const TYPE_GLOBS = {
7
+ js: ['**/*.js', '**/*.jsx', '**/*.mjs', '**/*.cjs'],
8
+ ts: ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'],
9
+ py: ['**/*.py', '**/*.pyi'],
10
+ rust: ['**/*.rs'],
11
+ go: ['**/*.go'],
12
+ java: ['**/*.java'],
13
+ c: ['**/*.c', '**/*.h'],
14
+ cpp: ['**/*.cc', '**/*.cpp', '**/*.cxx', '**/*.hpp', '**/*.hh'],
15
+ cs: ['**/*.cs'],
16
+ json: ['**/*.json'],
17
+ yaml: ['**/*.yaml', '**/*.yml'],
18
+ toml: ['**/*.toml'],
19
+ markdown: ['**/*.md', '**/*.markdown'],
20
+ html: ['**/*.html', '**/*.htm'],
21
+ css: ['**/*.css'],
22
+ xml: ['**/*.xml'],
23
+ sh: ['**/*.sh', '**/*.bash'],
24
+ };
25
+ export function parseGrepInput(value) {
26
+ assertObject(value);
27
+ const allowed = ['pattern', 'path', 'glob', 'type', 'output_mode', '-i', '-n', '-o', '-A', '-B', '-C', 'context', 'multiline', 'head_limit', 'offset'];
28
+ rejectUnknown(value, allowed);
29
+ const outputMode = optionalString(value, 'output_mode');
30
+ if (outputMode !== undefined && !['content', 'files_with_matches', 'count'].includes(outputMode)) {
31
+ throw new Error('output_mode must be content, files_with_matches, or count');
32
+ }
33
+ const result = { pattern: requiredString(value, 'pattern') };
34
+ for (const key of ['path', 'glob', 'type']) {
35
+ const item = optionalString(value, key);
36
+ if (item !== undefined)
37
+ result[key] = item;
38
+ }
39
+ if (outputMode !== undefined)
40
+ result.output_mode = outputMode;
41
+ for (const key of ['-i', '-n', '-o', 'multiline']) {
42
+ const item = optionalBoolean(value, key);
43
+ if (item !== undefined)
44
+ result[key] = item;
45
+ }
46
+ for (const [key, minimum] of [['-A', 0], ['-B', 0], ['-C', 0], ['context', 0], ['head_limit', 0], ['offset', 0]]) {
47
+ const item = optionalInteger(value, key, minimum);
48
+ if (item !== undefined)
49
+ result[key] = item;
50
+ }
51
+ return result;
52
+ }
53
+ function matchesType(relative, type) {
54
+ if (!type)
55
+ return true;
56
+ const patterns = TYPE_GLOBS[type];
57
+ if (!patterns)
58
+ throw new Error(`Unsupported file type: ${type}`);
59
+ return patterns.some(pattern => picomatch.isMatch(relative, pattern, { dot: true }));
60
+ }
61
+ function matchesGlob(relative, glob) {
62
+ return glob === undefined || picomatch.isMatch(relative, glob, { dot: true });
63
+ }
64
+ async function collectFiles(root, target, glob, type) {
65
+ const info = await stat(target);
66
+ if (info.isFile())
67
+ return [target];
68
+ if (!info.isDirectory())
69
+ throw new Error(`Path is not a file or directory: ${target}`);
70
+ const files = [];
71
+ const visit = async (directory) => {
72
+ const entries = await readdir(directory, { withFileTypes: true });
73
+ for (const entry of entries) {
74
+ if (entry.name === 'node_modules' || entry.name === '.git' || entry.name === 'dist')
75
+ continue;
76
+ const absolute = path.join(directory, entry.name);
77
+ const relative = path.relative(root, absolute).split(path.sep).join('/');
78
+ if (entry.isDirectory())
79
+ await visit(absolute);
80
+ else if (entry.isFile() && matchesGlob(relative, glob) && matchesType(relative, type))
81
+ files.push(absolute);
82
+ }
83
+ };
84
+ await visit(target);
85
+ return files.sort();
86
+ }
87
+ function searchLines(text, expression, onlyMatching) {
88
+ const lines = text.split('\n');
89
+ const matches = [];
90
+ for (let index = 0; index < lines.length; index += 1) {
91
+ const line = lines[index] ?? '';
92
+ expression.lastIndex = 0;
93
+ if (!expression.test(line))
94
+ continue;
95
+ if (onlyMatching) {
96
+ const global = new RegExp(expression.source, expression.flags.includes('g') ? expression.flags : `${expression.flags}g`);
97
+ const only = [...line.matchAll(global)].map(match => match[0]).filter(Boolean);
98
+ matches.push({ line: index + 1, text: line, only });
99
+ }
100
+ else
101
+ matches.push({ line: index + 1, text: line });
102
+ }
103
+ return matches;
104
+ }
105
+ function formatContent(file, text, matches, input, multipleFiles) {
106
+ const lines = text.split('\n');
107
+ const context = input.context ?? input['-C'];
108
+ const before = context ?? input['-B'] ?? 0;
109
+ const after = context ?? input['-A'] ?? 0;
110
+ const withNumbers = input['-n'] ?? true;
111
+ const output = [];
112
+ if (input['-o']) {
113
+ for (const match of matches) {
114
+ for (const part of match.only ?? [])
115
+ output.push(`${multipleFiles ? `${file}:` : ''}${withNumbers ? `${match.line}:` : ''}${part}`);
116
+ }
117
+ return output;
118
+ }
119
+ const selected = new Map();
120
+ for (const match of matches) {
121
+ for (let line = Math.max(1, match.line - before); line <= Math.min(lines.length, match.line + after); line += 1) {
122
+ selected.set(line, selected.get(line) === true || line === match.line);
123
+ }
124
+ }
125
+ let previous = 0;
126
+ for (const [line, direct] of [...selected.entries()].sort((a, b) => a[0] - b[0])) {
127
+ if (previous > 0 && line > previous + 1)
128
+ output.push('--');
129
+ const separator = direct ? ':' : '-';
130
+ output.push(`${multipleFiles ? `${file}${separator}` : ''}${withNumbers ? `${line}${separator}` : ''}${lines[line - 1] ?? ''}`);
131
+ previous = line;
132
+ }
133
+ return output;
134
+ }
135
+ export async function executeGrep(input) {
136
+ const targetInput = path.resolve(input.path ?? process.cwd());
137
+ const targetInfo = await stat(targetInput);
138
+ const targetContext = await getProjectFileContext(targetInfo.isDirectory() ? path.join(targetInput, '.codepage-bridge-search-probe') : targetInput);
139
+ const files = await collectFiles(targetContext.root, targetInput, input.glob, input.type);
140
+ const explicitFile = targetInfo.isFile();
141
+ const flags = `${input['-i'] ? 'i' : ''}${input.multiline ? 'ms' : ''}`;
142
+ let expression;
143
+ try {
144
+ expression = new RegExp(input.pattern, flags);
145
+ }
146
+ catch (error) {
147
+ throw new Error(`Invalid regular expression: ${error instanceof Error ? error.message : String(error)}`);
148
+ }
149
+ const results = [];
150
+ for (const file of files) {
151
+ try {
152
+ const context = await getProjectFileContext(file);
153
+ const snapshot = await readDecodedFile(context);
154
+ const matches = input.multiline
155
+ ? (expression.test(snapshot.text) ? [{ line: 1, text: snapshot.text }] : [])
156
+ : searchLines(snapshot.text, expression, input['-o'] ?? false);
157
+ if (matches.length > 0)
158
+ results.push({ file, text: snapshot.text, matches });
159
+ }
160
+ catch (error) {
161
+ if (explicitFile) {
162
+ const message = error instanceof Error ? error.message : String(error);
163
+ throw new Error(`Failed to search ${file}: ${message}`, { cause: error });
164
+ }
165
+ // Directory searches skip binary, undecodable, inaccessible, or independently rooted files.
166
+ }
167
+ }
168
+ const mode = input.output_mode ?? 'files_with_matches';
169
+ let entries;
170
+ if (mode === 'files_with_matches')
171
+ entries = results.map(result => result.file);
172
+ else if (mode === 'count')
173
+ entries = results.map(result => `${result.file}:${result.matches.length}`);
174
+ else
175
+ entries = results.flatMap(result => formatContent(result.file, result.text, result.matches, input, results.length > 1));
176
+ const offset = input.offset ?? 0;
177
+ const limit = input.head_limit ?? 250;
178
+ const selected = limit === 0 ? entries.slice(offset) : entries.slice(offset, offset + limit);
179
+ const suffix = limit !== 0 && offset + selected.length < entries.length
180
+ ? `\n\n[Showing results with pagination = limit: ${limit}, offset: ${offset}]`
181
+ : '';
182
+ return {
183
+ content: [{ type: 'text', text: `${selected.join('\n')}${suffix}` }],
184
+ structuredContent: {
185
+ mode,
186
+ numFiles: results.length,
187
+ numMatches: results.reduce((sum, result) => sum + result.matches.length, 0),
188
+ entries: selected,
189
+ },
190
+ };
191
+ }
192
+ //# 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,3 @@
1
+ import type { ReadInput, ToolResponse } from '../toolTypes.js';
2
+ export declare function parseReadInput(value: unknown): ReadInput;
3
+ export declare function executeRead(input: ReadInput): Promise<ToolResponse>;
@@ -0,0 +1,137 @@
1
+ import { stat } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { getProjectFileContext, readDecodedFile, readRegistry } from '../core.js';
4
+ import { inspectProjectPath } from '../filesystem/index.js';
5
+ import { readImage, readPdf, parseNotebook, mapNotebook } from '../media/index.js';
6
+ import { assertObject, optionalInteger, optionalString, rejectUnknown, requiredString, } from '../validation.js';
7
+ const DEFAULT_MAX_BYTES = 256 * 1024;
8
+ const IMAGE_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp']);
9
+ const BINARY_EXTENSIONS = new Set([
10
+ '.7z', '.a', '.bin', '.class', '.dll', '.dylib', '.exe', '.gz', '.iso', '.jar',
11
+ '.lib', '.o', '.obj', '.rar', '.so', '.tar', '.wasm', '.zip',
12
+ ]);
13
+ export function parseReadInput(value) {
14
+ assertObject(value);
15
+ rejectUnknown(value, ['file_path', 'offset', 'limit', 'pages']);
16
+ const file_path = requiredString(value, 'file_path');
17
+ const offset = optionalInteger(value, 'offset', 0);
18
+ const limit = optionalInteger(value, 'limit', 1);
19
+ const pages = optionalString(value, 'pages');
20
+ return {
21
+ file_path,
22
+ ...(offset === undefined ? {} : { offset }),
23
+ ...(limit === undefined ? {} : { limit }),
24
+ ...(pages === undefined ? {} : { pages }),
25
+ };
26
+ }
27
+ function lineNumber(content, startLine) {
28
+ return content
29
+ .split('\n')
30
+ .map((line, index) => `${String(startLine + index).padStart(6)}\t${line}`)
31
+ .join('\n');
32
+ }
33
+ function notebookContent(text) {
34
+ const notebook = parseNotebook(text);
35
+ const cells = mapNotebook(notebook);
36
+ const blocks = [];
37
+ for (const [index, cell] of cells.entries()) {
38
+ const original = notebook.cells[index];
39
+ const cellId = original?.id ?? `cell-${index}`;
40
+ const source = Array.isArray(original?.source) ? original.source.join('') : (original?.source ?? '');
41
+ blocks.push({
42
+ type: 'text',
43
+ text: `<cell id="${cellId}"><cell_type>${cell.cellType}</cell_type>${source}</cell id="${cellId}">`,
44
+ });
45
+ for (const block of cell.content.slice(source.length === 0 ? 0 : 1)) {
46
+ blocks.push(block);
47
+ }
48
+ }
49
+ return blocks;
50
+ }
51
+ export async function executeRead(input) {
52
+ const context = await getProjectFileContext(input.file_path);
53
+ const safe = await inspectProjectPath(context.root, context.absolutePath);
54
+ const info = await stat(safe.target);
55
+ if (info.isDirectory())
56
+ throw new Error(`Cannot read a directory: ${input.file_path}`);
57
+ if (await readRegistry.isUnchanged(context.absolutePath, input.offset, input.limit)) {
58
+ return {
59
+ content: [{
60
+ type: 'text',
61
+ text: 'File unchanged since last read. The content from the earlier Read tool_result in this conversation is still current — refer to that instead of re-reading.',
62
+ }],
63
+ structuredContent: { type: 'file_unchanged', file: { filePath: context.absolutePath } },
64
+ };
65
+ }
66
+ const extension = path.extname(context.absolutePath).toLowerCase();
67
+ if (IMAGE_EXTENSIONS.has(extension)) {
68
+ const block = await readImage(context.absolutePath, { maxWidth: 2000, maxHeight: 2000, quality: 80 });
69
+ return { content: [block] };
70
+ }
71
+ if (extension === '.pdf') {
72
+ const blocks = await readPdf(context.absolutePath, input.pages === undefined ? {} : { pages: input.pages });
73
+ return {
74
+ content: [
75
+ { type: 'text', text: `PDF ${context.absolutePath}${input.pages ? `, pages ${input.pages}` : ''}` },
76
+ ...blocks,
77
+ ],
78
+ };
79
+ }
80
+ if (BINARY_EXTENSIONS.has(extension)) {
81
+ throw new Error(`Cannot read binary file: ${input.file_path}`);
82
+ }
83
+ if (extension === '.ipynb' && (input.offset !== undefined || input.limit !== undefined)) {
84
+ throw new Error('offset and limit are not supported for Jupyter notebooks; read the complete notebook');
85
+ }
86
+ if (input.limit === undefined && info.size > DEFAULT_MAX_BYTES) {
87
+ throw new Error(`File content (${info.size} bytes) exceeds maximum allowed size (${DEFAULT_MAX_BYTES} bytes). Use offset and limit to read a portion of the file.`);
88
+ }
89
+ const snapshot = await readDecodedFile(context);
90
+ const lines = snapshot.text.split('\n');
91
+ const offset = input.offset === undefined || input.offset === 0 ? 1 : input.offset;
92
+ const startIndex = offset - 1;
93
+ const endIndex = input.limit === undefined ? lines.length : startIndex + input.limit;
94
+ const selected = lines.slice(startIndex, endIndex);
95
+ const remembered = {
96
+ ...snapshot,
97
+ complete: false,
98
+ ...(input.offset === undefined ? {} : { offset: input.offset }),
99
+ ...(input.limit === undefined ? {} : { limit: input.limit }),
100
+ };
101
+ if (snapshot.text.length === 0) {
102
+ readRegistry.remember(remembered, { startLine: 1, endLine: 1, totalLines: 1 });
103
+ return { content: [{ type: 'text', text: '<system-reminder>Warning: the file exists but has empty contents.</system-reminder>' }] };
104
+ }
105
+ if (startIndex >= lines.length) {
106
+ return {
107
+ content: [{
108
+ type: 'text',
109
+ text: `<system-reminder>Warning: offset ${offset} exceeds file length (${lines.length} lines).</system-reminder>`,
110
+ }],
111
+ };
112
+ }
113
+ readRegistry.remember(remembered, {
114
+ startLine: offset,
115
+ endLine: offset + selected.length - 1,
116
+ totalLines: lines.length,
117
+ });
118
+ if (extension === '.ipynb') {
119
+ return { content: notebookContent(snapshot.text) };
120
+ }
121
+ const content = selected.join('\n');
122
+ return {
123
+ content: [{ type: 'text', text: lineNumber(content, offset) }],
124
+ structuredContent: {
125
+ type: 'text',
126
+ file: {
127
+ filePath: context.absolutePath,
128
+ content,
129
+ numLines: selected.length,
130
+ startLine: offset,
131
+ totalLines: lines.length,
132
+ encoding: snapshot.encoding,
133
+ },
134
+ },
135
+ };
136
+ }
137
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../../src/tools/read.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ToolResponse, WriteInput } from '../toolTypes.js';
2
+ export declare function parseWriteInput(value: unknown): WriteInput;
3
+ export declare function executeWrite(input: WriteInput): Promise<ToolResponse>;