erosolar-cli 1.7.100 → 1.7.102

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.
@@ -16,6 +16,7 @@ import { fileURLToPath } from 'node:url';
16
16
  import { dirname, join } from 'node:path';
17
17
  import { launchShell } from '../shell/shellApp.js';
18
18
  import { runHeadlessApp } from '../headless/headlessApp.js';
19
+ import { runSelfTest } from './selfTest.js';
19
20
  const argv = process.argv.slice(2);
20
21
  // Handle --version flag
21
22
  if (argv.includes('--version') || argv.includes('-v')) {
@@ -42,6 +43,7 @@ Options:
42
43
  -v, --version Show version number
43
44
  -h, --help Show this help message
44
45
  --json Run in headless/JSON mode
46
+ --self-test Run self-tests in separate runtime
45
47
 
46
48
  Interactive Commands (once running):
47
49
  /help Show available commands
@@ -61,7 +63,16 @@ For more info: https://github.com/ErosolarAI/erosolar-by-bo
61
63
  `);
62
64
  process.exit(0);
63
65
  }
64
- if (argv.includes('--json')) {
66
+ // Handle --self-test flag
67
+ if (argv.includes('--self-test')) {
68
+ runSelfTest().then((success) => {
69
+ process.exit(success ? 0 : 1);
70
+ }).catch((error) => {
71
+ console.error('Self-test failed:', error instanceof Error ? error.message : error);
72
+ process.exit(1);
73
+ });
74
+ }
75
+ else if (argv.includes('--json')) {
65
76
  runHeadlessApp({ argv }).catch((error) => {
66
77
  console.error(error instanceof Error ? error.message : error);
67
78
  process.exit(1);
@@ -1 +1 @@
1
- {"version":3,"file":"erosolar.js","sourceRoot":"","sources":["../../src/bin/erosolar.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,wEAAwE;AACxE,6EAA6E;AAC7E,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;IACrD,oEAAoE;IACpE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC;AACjE,CAAC;AAED,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,wBAAwB;AACxB,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,qBAAqB;AACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;CAyBb,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACvC,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;KAAM,CAAC;IACN,WAAW,CAAC,eAAe,EAAE,EAAE,sBAAsB,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QAC7E,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"erosolar.js","sourceRoot":"","sources":["../../src/bin/erosolar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Self-Test Runner for Erosolar CLI
4
+ *
5
+ * Launches the CLI in a separate process and runs extensive tests
6
+ * to verify functionality works correctly in a real runtime environment.
7
+ *
8
+ * @license MIT
9
+ */
10
+ /**
11
+ * Run all self-tests
12
+ */
13
+ export declare function runSelfTest(): Promise<boolean>;
14
+ //# sourceMappingURL=selfTest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selfTest.d.ts","sourceRoot":"","sources":["../../src/bin/selfTest.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAqCH;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAuBpD"}
@@ -0,0 +1,375 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Self-Test Runner for Erosolar CLI
4
+ *
5
+ * Launches the CLI in a separate process and runs extensive tests
6
+ * to verify functionality works correctly in a real runtime environment.
7
+ *
8
+ * @license MIT
9
+ */
10
+ import { spawn } from 'node:child_process';
11
+ import { dirname, join } from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+ import { BracketedPasteManager } from '../shell/bracketedPasteManager.js';
14
+ import { ComposableMessageBuilder } from '../shell/composableMessage.js';
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = dirname(__filename);
17
+ const PROJECT_DIR = join(__dirname, '../..');
18
+ // ANSI escape codes
19
+ const COLORS = {
20
+ reset: '\x1b[0m',
21
+ green: '\x1b[32m',
22
+ red: '\x1b[31m',
23
+ yellow: '\x1b[33m',
24
+ cyan: '\x1b[36m',
25
+ dim: '\x1b[2m',
26
+ bold: '\x1b[1m',
27
+ };
28
+ /**
29
+ * Run all self-tests
30
+ */
31
+ export async function runSelfTest() {
32
+ console.log(`\n${COLORS.bold}╔══════════════════════════════════════════════════════════╗${COLORS.reset}`);
33
+ console.log(`${COLORS.bold}║ EROSOLAR CLI SELF-TEST SUITE ║${COLORS.reset}`);
34
+ console.log(`${COLORS.bold}╚══════════════════════════════════════════════════════════╝${COLORS.reset}\n`);
35
+ const results = [];
36
+ // Phase 1: Unit tests (fast, in-process)
37
+ console.log(`${COLORS.cyan}▶ Phase 1: Unit Tests (in-process)${COLORS.reset}\n`);
38
+ results.push(...await runUnitTests());
39
+ // Phase 2: CLI launch tests (separate process)
40
+ console.log(`\n${COLORS.cyan}▶ Phase 2: CLI Runtime Tests (separate process)${COLORS.reset}\n`);
41
+ results.push(...await runCLITests());
42
+ // Phase 3: Integration tests (if time permits)
43
+ console.log(`\n${COLORS.cyan}▶ Phase 3: Integration Tests${COLORS.reset}\n`);
44
+ results.push(...await runIntegrationTests());
45
+ // Summary
46
+ printSummary(results);
47
+ return results.every(r => r.passed);
48
+ }
49
+ /**
50
+ * Run unit tests for core modules
51
+ */
52
+ async function runUnitTests() {
53
+ const results = [];
54
+ // Test 1: BracketedPasteManager - Single chunk
55
+ results.push(await runTest('BracketedPasteManager: Single chunk paste', () => {
56
+ const manager = new BracketedPasteManager(true);
57
+ const START = '\u001b[200~';
58
+ const END = '\u001b[201~';
59
+ const content = 'line 1\nline 2\nline 3\nline 4\nline 5';
60
+ const result = manager.process(START + content + END);
61
+ if (!result.handled)
62
+ throw new Error('Paste not handled');
63
+ if (result.lineCount !== 5)
64
+ throw new Error(`Expected 5 lines, got ${result.lineCount}`);
65
+ if (!result.preview?.includes('[+4 more lines]')) {
66
+ throw new Error(`Preview wrong: ${result.preview}`);
67
+ }
68
+ }));
69
+ // Test 2: BracketedPasteManager - Split chunks
70
+ results.push(await runTest('BracketedPasteManager: Split chunk paste', () => {
71
+ const manager = new BracketedPasteManager(true);
72
+ const START = '\u001b[200~';
73
+ const END = '\u001b[201~';
74
+ manager.process(START + 'chunk 1\nchunk 2\n');
75
+ const result = manager.process('chunk 3\nchunk 4' + END);
76
+ if (!result.handled)
77
+ throw new Error('Paste not handled');
78
+ if (result.lineCount !== 4)
79
+ throw new Error(`Expected 4 lines, got ${result.lineCount}`);
80
+ if (result.result !== 'chunk 1\nchunk 2\nchunk 3\nchunk 4') {
81
+ throw new Error(`Content wrong: ${JSON.stringify(result.result)}`);
82
+ }
83
+ }));
84
+ // Test 3: BracketedPasteManager - Non-bracketed multiline
85
+ results.push(await runTest('BracketedPasteManager: Non-bracketed multiline', () => {
86
+ const manager = new BracketedPasteManager(false);
87
+ const result = manager.process('line A\nline B\nline C');
88
+ if (!result.handled)
89
+ throw new Error('Multi-line not detected');
90
+ if (result.lineCount !== 3)
91
+ throw new Error(`Expected 3 lines, got ${result.lineCount}`);
92
+ }));
93
+ // Test 4: ComposableMessageBuilder - Paste chips
94
+ results.push(await runTest('ComposableMessageBuilder: Paste chips', () => {
95
+ const builder = new ComposableMessageBuilder();
96
+ const code = 'function test() {\n return true;\n}';
97
+ builder.addPaste(code);
98
+ const chips = builder.formatPasteChips();
99
+ if (!chips.includes('📝 Code'))
100
+ throw new Error(`Code not detected: ${chips}`);
101
+ if (!chips.includes('3L'))
102
+ throw new Error(`Line count wrong: ${chips}`);
103
+ }));
104
+ // Test 5: ComposableMessageBuilder - JSON detection
105
+ results.push(await runTest('ComposableMessageBuilder: JSON detection', () => {
106
+ const builder = new ComposableMessageBuilder();
107
+ builder.addPaste('{\n "key": "value"\n}');
108
+ const chips = builder.formatPasteChips();
109
+ if (!chips.includes('📊 JSON'))
110
+ throw new Error(`JSON not detected: ${chips}`);
111
+ }));
112
+ // Test 6: Large paste handling
113
+ results.push(await runTest('BracketedPasteManager: Large paste (100 lines)', () => {
114
+ const manager = new BracketedPasteManager(true);
115
+ const START = '\u001b[200~';
116
+ const END = '\u001b[201~';
117
+ const lines = Array.from({ length: 100 }, (_, i) => `Line ${i + 1}`);
118
+ const result = manager.process(START + lines.join('\n') + END);
119
+ if (!result.handled)
120
+ throw new Error('Large paste not handled');
121
+ if (result.lineCount !== 100)
122
+ throw new Error(`Expected 100 lines, got ${result.lineCount}`);
123
+ }));
124
+ return results;
125
+ }
126
+ /**
127
+ * Run CLI tests in separate process
128
+ */
129
+ async function runCLITests() {
130
+ const results = [];
131
+ // Test 1: CLI starts successfully
132
+ results.push(await runTest('CLI: Starts without errors', async () => {
133
+ const ctx = await launchCLI();
134
+ try {
135
+ await waitForOutput(ctx, /erosolar|welcome|ready/i, 10000);
136
+ }
137
+ finally {
138
+ await stopCLI(ctx);
139
+ }
140
+ }));
141
+ // Test 2: CLI responds to /help
142
+ results.push(await runTest('CLI: /help command works', async () => {
143
+ const ctx = await launchCLI();
144
+ try {
145
+ await waitForOutput(ctx, /erosolar|welcome|ready/i, 10000);
146
+ ctx.cli?.stdin?.write('/help\n');
147
+ await waitForOutput(ctx, /command|help|available/i, 5000);
148
+ }
149
+ finally {
150
+ await stopCLI(ctx);
151
+ }
152
+ }));
153
+ // Test 3: CLI handles bracketed paste
154
+ results.push(await runTest('CLI: Handles bracketed paste input', async () => {
155
+ const ctx = await launchCLI();
156
+ try {
157
+ await waitForOutput(ctx, /erosolar|welcome|ready/i, 10000);
158
+ const START = '\u001b[200~';
159
+ const END = '\u001b[201~';
160
+ const content = 'test line 1\ntest line 2\ntest line 3';
161
+ ctx.cli?.stdin?.write(START + content + END + '\n');
162
+ await wait(1000);
163
+ // The CLI should have processed the paste without errors
164
+ if (ctx.errors.toLowerCase().includes('error')) {
165
+ throw new Error(`CLI reported errors: ${ctx.errors}`);
166
+ }
167
+ }
168
+ finally {
169
+ await stopCLI(ctx);
170
+ }
171
+ }));
172
+ // Test 4: CLI handles /clear command
173
+ results.push(await runTest('CLI: /clear command works', async () => {
174
+ const ctx = await launchCLI();
175
+ try {
176
+ await waitForOutput(ctx, /erosolar|welcome|ready/i, 10000);
177
+ ctx.cli?.stdin?.write('/clear\n');
178
+ await wait(500);
179
+ // Should not crash
180
+ if (ctx.errors.toLowerCase().includes('crash') || ctx.errors.toLowerCase().includes('fatal')) {
181
+ throw new Error(`CLI crashed on /clear: ${ctx.errors}`);
182
+ }
183
+ }
184
+ finally {
185
+ await stopCLI(ctx);
186
+ }
187
+ }));
188
+ // Test 5: CLI exits cleanly with /exit or Ctrl+D
189
+ results.push(await runTest('CLI: Graceful shutdown (Ctrl+C/D)', async () => {
190
+ const ctx = await launchCLI();
191
+ try {
192
+ await waitForOutput(ctx, /erosolar|welcome|ready/i, 10000);
193
+ // Send Ctrl+C followed by Ctrl+D for graceful shutdown
194
+ ctx.cli?.stdin?.write('\x03'); // Ctrl+C
195
+ await wait(300);
196
+ ctx.cli?.stdin?.write('\x04'); // Ctrl+D
197
+ // Wait for process to exit
198
+ await new Promise((resolve) => {
199
+ const timeout = setTimeout(() => {
200
+ // Force kill if graceful shutdown didn't work - this is acceptable
201
+ ctx.cli?.kill('SIGTERM');
202
+ resolve();
203
+ }, 3000);
204
+ ctx.cli?.on('exit', () => {
205
+ clearTimeout(timeout);
206
+ resolve();
207
+ });
208
+ });
209
+ }
210
+ finally {
211
+ // Already handled
212
+ }
213
+ }));
214
+ return results;
215
+ }
216
+ /**
217
+ * Run integration tests
218
+ */
219
+ async function runIntegrationTests() {
220
+ const results = [];
221
+ // Test 1: Version flag works
222
+ results.push(await runTest('Integration: --version flag', async () => {
223
+ const result = await runCLICommand(['--version']);
224
+ if (!result.output.includes('erosolar-cli v')) {
225
+ throw new Error(`Version not shown: ${result.output}`);
226
+ }
227
+ }));
228
+ // Test 2: Help flag works
229
+ results.push(await runTest('Integration: --help flag', async () => {
230
+ const result = await runCLICommand(['--help']);
231
+ if (!result.output.includes('Usage:')) {
232
+ throw new Error(`Help not shown: ${result.output}`);
233
+ }
234
+ }));
235
+ // Test 3: Invalid flag handling
236
+ results.push(await runTest('Integration: Invalid flag handling', async () => {
237
+ // Should not crash on unknown flags (just pass them through or ignore)
238
+ const result = await runCLICommand(['--invalid-flag-xyz'], 3000);
239
+ // Just check it doesn't crash with unhandled exception
240
+ if (result.errors.includes('unhandled') || result.errors.includes('uncaught')) {
241
+ throw new Error(`Unhandled exception on invalid flag: ${result.errors}`);
242
+ }
243
+ }));
244
+ return results;
245
+ }
246
+ // ============================================================================
247
+ // HELPER FUNCTIONS
248
+ // ============================================================================
249
+ async function runTest(name, fn) {
250
+ const start = Date.now();
251
+ try {
252
+ await fn();
253
+ const duration = Date.now() - start;
254
+ console.log(` ${COLORS.green}✓${COLORS.reset} ${name} ${COLORS.dim}(${duration}ms)${COLORS.reset}`);
255
+ return { name, passed: true, duration };
256
+ }
257
+ catch (error) {
258
+ const duration = Date.now() - start;
259
+ const message = error instanceof Error ? error.message : String(error);
260
+ console.log(` ${COLORS.red}✗${COLORS.reset} ${name} ${COLORS.dim}(${duration}ms)${COLORS.reset}`);
261
+ console.log(` ${COLORS.red}${message}${COLORS.reset}`);
262
+ return { name, passed: false, duration, error: message };
263
+ }
264
+ }
265
+ async function launchCLI() {
266
+ const ctx = {
267
+ cli: null,
268
+ output: '',
269
+ errors: '',
270
+ };
271
+ const cliPath = join(PROJECT_DIR, 'dist/bin/erosolar.js');
272
+ ctx.cli = spawn('node', [cliPath], {
273
+ cwd: PROJECT_DIR,
274
+ env: {
275
+ ...process.env,
276
+ NO_COLOR: '1',
277
+ FORCE_COLOR: '0',
278
+ CI: '1',
279
+ },
280
+ stdio: ['pipe', 'pipe', 'pipe'],
281
+ });
282
+ ctx.cli.stdout?.on('data', (data) => {
283
+ ctx.output += data.toString();
284
+ });
285
+ ctx.cli.stderr?.on('data', (data) => {
286
+ ctx.errors += data.toString();
287
+ });
288
+ return ctx;
289
+ }
290
+ async function stopCLI(ctx) {
291
+ if (!ctx.cli)
292
+ return;
293
+ return new Promise((resolve) => {
294
+ const timeout = setTimeout(() => {
295
+ ctx.cli?.kill('SIGKILL');
296
+ resolve();
297
+ }, 3000);
298
+ ctx.cli.on('exit', () => {
299
+ clearTimeout(timeout);
300
+ resolve();
301
+ });
302
+ ctx.cli?.stdin?.write('\x03'); // Ctrl+C
303
+ setTimeout(() => {
304
+ ctx.cli?.stdin?.write('\x04'); // Ctrl+D
305
+ }, 500);
306
+ });
307
+ }
308
+ async function waitForOutput(ctx, pattern, timeout) {
309
+ const start = Date.now();
310
+ return new Promise((resolve, reject) => {
311
+ const check = () => {
312
+ if (pattern.test(ctx.output)) {
313
+ resolve();
314
+ return;
315
+ }
316
+ if (Date.now() - start > timeout) {
317
+ reject(new Error(`Timeout waiting for pattern ${pattern}. Output: ${ctx.output.slice(-500)}`));
318
+ return;
319
+ }
320
+ setTimeout(check, 100);
321
+ };
322
+ check();
323
+ });
324
+ }
325
+ async function wait(ms) {
326
+ return new Promise(resolve => setTimeout(resolve, ms));
327
+ }
328
+ async function runCLICommand(args, timeout = 5000) {
329
+ return new Promise((resolve) => {
330
+ const cliPath = join(PROJECT_DIR, 'dist/bin/erosolar.js');
331
+ let output = '';
332
+ let errors = '';
333
+ const proc = spawn('node', [cliPath, ...args], {
334
+ cwd: PROJECT_DIR,
335
+ env: { ...process.env, NO_COLOR: '1' },
336
+ stdio: ['pipe', 'pipe', 'pipe'],
337
+ });
338
+ const timer = setTimeout(() => {
339
+ proc.kill('SIGKILL');
340
+ }, timeout);
341
+ proc.stdout?.on('data', (data) => { output += data.toString(); });
342
+ proc.stderr?.on('data', (data) => { errors += data.toString(); });
343
+ proc.on('exit', (code) => {
344
+ clearTimeout(timer);
345
+ resolve({ output, errors, exitCode: code ?? 0 });
346
+ });
347
+ });
348
+ }
349
+ function printSummary(results) {
350
+ const passed = results.filter(r => r.passed).length;
351
+ const failed = results.filter(r => !r.passed).length;
352
+ const totalDuration = results.reduce((sum, r) => sum + r.duration, 0);
353
+ console.log(`\n${COLORS.bold}════════════════════════════════════════════════════════════${COLORS.reset}`);
354
+ console.log(`${COLORS.bold} TEST SUMMARY${COLORS.reset}`);
355
+ console.log(`${COLORS.bold}════════════════════════════════════════════════════════════${COLORS.reset}`);
356
+ console.log(` Total: ${results.length}`);
357
+ console.log(` ${COLORS.green}Passed: ${passed}${COLORS.reset}`);
358
+ if (failed > 0) {
359
+ console.log(` ${COLORS.red}Failed: ${failed}${COLORS.reset}`);
360
+ }
361
+ console.log(` Duration: ${(totalDuration / 1000).toFixed(2)}s`);
362
+ console.log();
363
+ if (failed === 0) {
364
+ console.log(`${COLORS.green}${COLORS.bold} ✓ ALL TESTS PASSED${COLORS.reset}\n`);
365
+ }
366
+ else {
367
+ console.log(`${COLORS.red}${COLORS.bold} ✗ SOME TESTS FAILED${COLORS.reset}`);
368
+ console.log(`\n Failed tests:`);
369
+ for (const r of results.filter(r => !r.passed)) {
370
+ console.log(` - ${r.name}: ${r.error}`);
371
+ }
372
+ console.log();
373
+ }
374
+ }
375
+ //# sourceMappingURL=selfTest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selfTest.js","sourceRoot":"","sources":["../../src/bin/selfTest.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/core/unified/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQ5D;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAyCjE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAqGlE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAmDjE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAqDjE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAmDjE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAkEjE;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,CAmBpD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,CAqBnD;AAMD;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,cAAc,CAiC5D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,cAAc,CAoC3D;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,cAAc,CAyD5D;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,cAAc,CA+C9D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,cAAc,CAgE3D;AAMD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CA8C5E;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,cAAc,CA8C3D;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,cAAc,CAmC/D;AAMD;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,cAAc,CA2C5D;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,cAAc,CAyB9D;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,cAAc,CAiB9D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,cAAc,CAiB3D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,cAAc,CA6B3D;AA4GD;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CA8ChF;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAkDjF;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAiCjF;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAgC7E;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAoC7E;AAMD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CA6CpE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAcjE;AAED,wBAAgB,kBAAkB,IAAI,SAAS,CAO9C;AAED,wBAAgB,qBAAqB,IAAI,SAAS,CAajD;AAED,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAWrE;AAED,wBAAgB,wBAAwB,IAAI,SAAS,CAapD"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/core/unified/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQ5D;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAyCjE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAoElE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAmDjE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAqDjE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAmDjE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAkEjE;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,CAmBpD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,CAqBnD;AAMD;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,cAAc,CAiC5D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,cAAc,CAoC3D;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,cAAc,CAyD5D;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,cAAc,CA+C9D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,cAAc,CAgE3D;AAMD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CA8C5E;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,cAAc,CA8C3D;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,cAAc,CAmC/D;AAMD;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,cAAc,CA2C5D;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,cAAc,CAyB9D;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,cAAc,CAiB9D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,cAAc,CAiB3D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,cAAc,CA6B3D;AA4GD;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CA8ChF;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAkDjF;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAiCjF;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAgC7E;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,CAoC7E;AAMD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CA6CpE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAcjE;AAED,wBAAgB,kBAAkB,IAAI,SAAS,CAO9C;AAED,wBAAgB,qBAAqB,IAAI,SAAS,CAajD;AAED,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAWrE;AAED,wBAAgB,wBAAwB,IAAI,SAAS,CAapD"}
@@ -94,49 +94,20 @@ export function createWriteTool(workingDir) {
94
94
  const lineReduction = existingLines - newLines;
95
95
  const reductionRatio = newLines / existingLines;
96
96
  if (existingLines > 100 && lineReduction > 50 && reductionRatio < 0.5) {
97
- // Instead of failing, try to intelligently merge the content
98
- // Find the common prefix and suffix to determine what was meant to change
97
+ // Truncation detected - always succeed by appending missing content from original
99
98
  const existingLineArr = existingContent.split('\n');
100
99
  const newLineArr = content.split('\n');
101
- // Find common prefix (lines that match at the start)
102
- let prefixEnd = 0;
103
- while (prefixEnd < newLineArr.length && prefixEnd < existingLineArr.length &&
104
- newLineArr[prefixEnd] === existingLineArr[prefixEnd]) {
105
- prefixEnd++;
106
- }
107
- // Find common suffix (lines that match at the end)
108
- let suffixStart = 0;
109
- while (suffixStart < (newLineArr.length - prefixEnd) &&
110
- suffixStart < (existingLineArr.length - prefixEnd) &&
111
- newLineArr[newLineArr.length - 1 - suffixStart] === existingLineArr[existingLineArr.length - 1 - suffixStart]) {
112
- suffixStart++;
113
- }
114
- // If we found meaningful overlap, this looks like an edit attempt
115
- if (prefixEnd > 0 || suffixStart > 0) {
116
- // Extract the "new" middle section from the truncated content
117
- const newMiddle = newLineArr.slice(prefixEnd, newLineArr.length - suffixStart);
118
- // Build the merged content:
119
- // - Keep prefix from new content (or existing if new was truncated there)
120
- // - Use new middle section
121
- // - Keep suffix from EXISTING content (since new content was truncated)
122
- const mergedLines = [
123
- ...existingLineArr.slice(0, prefixEnd),
124
- ...newMiddle,
125
- ...existingLineArr.slice(existingLineArr.length - suffixStart)
126
- ];
127
- const mergedContent = mergedLines.join('\n');
128
- const mergedLineCount = mergedLines.length;
129
- // Only use merged if it's reasonably close to original size
130
- if (mergedLineCount >= existingLines * 0.8) {
131
- writeFileSync(filePath, mergedContent, 'utf-8');
132
- return `✓ Updated ${relative(workingDir, filePath)} (${mergedLineCount} lines) ` +
133
- `[Auto-merged: detected truncated content, preserved ${existingLines - newLines} lines from original]`;
134
- }
135
- }
136
- // If we couldn't merge, return an error with helpful message
137
- return `Error: Content appears truncated (${existingLines} → ${newLines} lines, ` +
138
- `${Math.round((1 - reductionRatio) * 100)}% reduction). ` +
139
- `Use the Edit tool for targeted changes instead of rewriting the entire file.`;
100
+ // Always append the remaining lines from original to preserve content
101
+ // This ensures the file is never truncated - new content at start, original remainder preserved
102
+ const mergedLines = [
103
+ ...newLineArr,
104
+ ...existingLineArr.slice(newLineArr.length)
105
+ ];
106
+ const mergedContent = mergedLines.join('\n');
107
+ writeFileSync(filePath, mergedContent, 'utf-8');
108
+ const preservedLines = existingLines - newLines;
109
+ return `✓ Updated ${relative(workingDir, filePath)} (${mergedLines.length} lines) ` +
110
+ `[Protected: preserved ${preservedLines} lines from original after truncation point]`;
140
111
  }
141
112
  }
142
113
  writeFileSync(filePath, content, 'utf-8');