squeezr-ai 1.80.15 → 1.81.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.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { preprocess } from '../deterministic.js';
3
+ describe('deduplicateLines is code-aware (never corrupts editable content)', () => {
4
+ it('does NOT collapse repeated markup lines (<div> / </div>)', () => {
5
+ const html = ['<div>', '</div>', '<div>', '</div>', '<div>', '</div>'].join('\n');
6
+ const out = preprocess(html);
7
+ expect(out).not.toContain('repeated');
8
+ expect((out.match(/<\/div>/g) || []).length).toBe(3);
9
+ expect((out.match(/<div>/g) || []).length).toBe(3);
10
+ });
11
+ it('does NOT collapse repeated code closers (})', () => {
12
+ const code = ['if (a) {', ' doX()', '}', 'if (b) {', ' doY()', '}', 'if (c) {', ' doZ()', '}'].join('\n');
13
+ const out = preprocess(code);
14
+ expect((out.match(/^}$/gm) || []).length).toBe(3);
15
+ expect(out).not.toContain('repeated');
16
+ });
17
+ it('STILL collapses repeated log-like prose lines', () => {
18
+ const log = Array.from({ length: 6 }, () => 'processing the next item now').join('\n');
19
+ const out = preprocess(log);
20
+ expect(out).toContain('repeated');
21
+ expect((out.match(/processing the next item now/g) || []).length).toBe(1);
22
+ });
23
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,94 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { preprocessForTool } from '../deterministic.js';
3
+ import { storeSegments, storeOriginal, retrieveOriginal } from '../expand.js';
4
+ const idsIn = (s) => [...s.matchAll(/squeezr_expand\("([^"]+)"\)/g)].map(m => m[1]);
5
+ describe('storeSegments', () => {
6
+ it('parent returns the whole; sub-ids return their part', () => {
7
+ const orig = 'AAA\nBBB\nCCC';
8
+ const { id, subIds } = storeSegments(orig, ['AAA', 'BBB']);
9
+ expect(retrieveOriginal(id)).toBe(orig);
10
+ expect(retrieveOriginal(subIds[0])).toBe('AAA');
11
+ expect(retrieveOriginal(subIds[1])).toBe('BBB');
12
+ expect(subIds[0]).toMatch(/~0$/);
13
+ expect(subIds[1]).toMatch(/~1$/);
14
+ });
15
+ it('parent id is deterministic and equals storeOriginal(original)', () => {
16
+ const orig = 'some original content for the determinism check';
17
+ const { id } = storeSegments(orig, ['some']);
18
+ expect(id).toBe(storeOriginal(orig));
19
+ });
20
+ });
21
+ describe('code structure → per-symbol expand (read)', () => {
22
+ it('big code file keeps signatures and recovers a single function body', () => {
23
+ const filler = (n) => Array.from({ length: n }, (_, i) => ` const v${i} = ${i}`).join('\n');
24
+ const code = [
25
+ "import { Foo } from './foo'",
26
+ 'export class AuthService {',
27
+ ' async login(req, res) {',
28
+ filler(180),
29
+ ' }',
30
+ ' async refresh(token) {',
31
+ filler(180),
32
+ ' }',
33
+ ' async logout(id) {',
34
+ filler(180),
35
+ ' }',
36
+ '}',
37
+ ].join('\n');
38
+ expect(code.split('\n').length).toBeGreaterThan(500);
39
+ const out = preprocessForTool(code, 'read');
40
+ expect(out).toContain('async login');
41
+ expect(out).toContain('async refresh');
42
+ const ids = idsIn(out);
43
+ expect(ids.length).toBeGreaterThan(1);
44
+ // A per-symbol id recovers a contiguous slice that includes that function.
45
+ const bodies = ids.map(retrieveOriginal).filter(Boolean);
46
+ expect(bodies.some(b => b.includes('async refresh') && b.includes('v17'))).toBe(true);
47
+ // The whole-file id (no "~") recovers the exact original.
48
+ const whole = ids.find(i => !i.includes('~'));
49
+ expect(whole).toBeTruthy();
50
+ expect(retrieveOriginal(whole)).toBe(code);
51
+ });
52
+ });
53
+ describe('big non-code file → recover middle by range (read)', () => {
54
+ it('head/tail keeps ends and makes the omitted middle recoverable in chunks', () => {
55
+ const lines = Array.from({ length: 400 }, (_, i) => `req ${i + 1} GET /api 200`);
56
+ const text = lines.join('\n');
57
+ const out = preprocessForTool(text, 'read');
58
+ expect(out).toContain('req 1 GET'); // head kept
59
+ expect(out).toContain('req 400 GET'); // tail kept
60
+ expect(out).toContain('lines omitted');
61
+ expect(out).toMatch(/lines \d+-\d+ → squeezr_expand/);
62
+ const ids = idsIn(out);
63
+ expect(ids.length).toBeGreaterThan(0);
64
+ const bodies = ids.map(retrieveOriginal).filter(Boolean);
65
+ // a middle request (around line 200) is recoverable
66
+ expect(bodies.some(b => b.includes('req 200 GET'))).toBe(true);
67
+ });
68
+ });
69
+ describe('git diff → per-file expand (bash)', () => {
70
+ it('multi-file diff offers a full-diff expand per file', () => {
71
+ const diff = [
72
+ 'diff --git a/src/auth.ts b/src/auth.ts',
73
+ 'index 1a..2b 100644',
74
+ '--- a/src/auth.ts',
75
+ '+++ b/src/auth.ts',
76
+ '@@ -1,3 +1,4 @@ login()',
77
+ '+ const token = sign(user)',
78
+ 'diff --git a/src/user.ts b/src/user.ts',
79
+ 'index 3c..4d 100644',
80
+ '--- a/src/user.ts',
81
+ '+++ b/src/user.ts',
82
+ '@@ -2,2 +2,2 @@ find()',
83
+ '- return null',
84
+ '+ return user',
85
+ ].join('\n');
86
+ const out = preprocessForTool(diff, 'bash');
87
+ expect(out).toContain('Full diff per file');
88
+ expect(out).toContain('src/auth.ts');
89
+ expect(out).toContain('src/user.ts');
90
+ const ids = idsIn(out);
91
+ const bodies = ids.map(retrieveOriginal).filter(Boolean);
92
+ expect(bodies.some(b => b.includes('b/src/user.ts') && b.includes('return user'))).toBe(true);
93
+ });
94
+ });