@camaradesuk/git-worktree-tools 1.0.5 → 1.1.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/README.md +7 -0
- package/dist/cli/cleanpr.d.ts +1 -6
- package/dist/cli/cleanpr.d.ts.map +1 -1
- package/dist/cli/cleanpr.js +110 -302
- package/dist/cli/cleanpr.js.map +1 -1
- package/dist/cli/cleanpr.test.d.ts +2 -0
- package/dist/cli/cleanpr.test.d.ts.map +1 -0
- package/dist/cli/cleanpr.test.js +225 -0
- package/dist/cli/cleanpr.test.js.map +1 -0
- package/dist/cli/lswt.d.ts +1 -4
- package/dist/cli/lswt.d.ts.map +1 -1
- package/dist/cli/lswt.js +32 -251
- package/dist/cli/lswt.js.map +1 -1
- package/dist/cli/lswt.test.d.ts +2 -0
- package/dist/cli/lswt.test.d.ts.map +1 -0
- package/dist/cli/lswt.test.js +165 -0
- package/dist/cli/lswt.test.js.map +1 -0
- package/dist/cli/newpr.d.ts +1 -4
- package/dist/cli/newpr.d.ts.map +1 -1
- package/dist/cli/newpr.js +98 -493
- package/dist/cli/newpr.js.map +1 -1
- package/dist/cli/newpr.test.d.ts +2 -0
- package/dist/cli/newpr.test.d.ts.map +1 -0
- package/dist/cli/newpr.test.js +329 -0
- package/dist/cli/newpr.test.js.map +1 -0
- package/dist/cli/wtlink.test.d.ts +2 -0
- package/dist/cli/wtlink.test.d.ts.map +1 -0
- package/dist/cli/wtlink.test.js +148 -0
- package/dist/cli/wtlink.test.js.map +1 -0
- package/dist/e2e/cli.e2e.test.js +44 -1
- package/dist/e2e/cli.e2e.test.js.map +1 -1
- package/dist/lib/cleanpr/args.d.ts +14 -0
- package/dist/lib/cleanpr/args.d.ts.map +1 -0
- package/dist/lib/cleanpr/args.js +82 -0
- package/dist/lib/cleanpr/args.js.map +1 -0
- package/dist/lib/cleanpr/args.test.d.ts +2 -0
- package/dist/lib/cleanpr/args.test.d.ts.map +1 -0
- package/dist/lib/cleanpr/args.test.js +192 -0
- package/dist/lib/cleanpr/args.test.js.map +1 -0
- package/dist/lib/cleanpr/cleanup.d.ts +61 -0
- package/dist/lib/cleanpr/cleanup.d.ts.map +1 -0
- package/dist/lib/cleanpr/cleanup.js +97 -0
- package/dist/lib/cleanpr/cleanup.js.map +1 -0
- package/dist/lib/cleanpr/cleanup.test.d.ts +2 -0
- package/dist/lib/cleanpr/cleanup.test.d.ts.map +1 -0
- package/dist/lib/cleanpr/cleanup.test.js +264 -0
- package/dist/lib/cleanpr/cleanup.test.js.map +1 -0
- package/dist/lib/cleanpr/index.d.ts +10 -0
- package/dist/lib/cleanpr/index.d.ts.map +1 -0
- package/dist/lib/cleanpr/index.js +8 -0
- package/dist/lib/cleanpr/index.js.map +1 -0
- package/dist/lib/cleanpr/types.d.ts +49 -0
- package/dist/lib/cleanpr/types.d.ts.map +1 -0
- package/dist/lib/cleanpr/types.js +5 -0
- package/dist/lib/cleanpr/types.js.map +1 -0
- package/dist/lib/cleanpr/worktree-info.d.ts +27 -0
- package/dist/lib/cleanpr/worktree-info.d.ts.map +1 -0
- package/dist/lib/cleanpr/worktree-info.js +95 -0
- package/dist/lib/cleanpr/worktree-info.js.map +1 -0
- package/dist/lib/cleanpr/worktree-info.test.d.ts +2 -0
- package/dist/lib/cleanpr/worktree-info.test.d.ts.map +1 -0
- package/dist/lib/cleanpr/worktree-info.test.js +160 -0
- package/dist/lib/cleanpr/worktree-info.test.js.map +1 -0
- package/dist/lib/colors.test.js +73 -0
- package/dist/lib/colors.test.js.map +1 -1
- package/dist/lib/config.test.js +79 -2
- package/dist/lib/config.test.js.map +1 -1
- package/dist/lib/git.d.ts.map +1 -1
- package/dist/lib/git.js +4 -3
- package/dist/lib/git.js.map +1 -1
- package/dist/lib/git.test.js +7 -7
- package/dist/lib/git.test.js.map +1 -1
- package/dist/lib/github.d.ts.map +1 -1
- package/dist/lib/github.js +23 -30
- package/dist/lib/github.js.map +1 -1
- package/dist/lib/github.test.js +49 -12
- package/dist/lib/github.test.js.map +1 -1
- package/dist/lib/lswt/args.d.ts +14 -0
- package/dist/lib/lswt/args.d.ts.map +1 -0
- package/dist/lib/lswt/args.js +67 -0
- package/dist/lib/lswt/args.js.map +1 -0
- package/dist/lib/lswt/args.test.d.ts +2 -0
- package/dist/lib/lswt/args.test.d.ts.map +1 -0
- package/dist/lib/lswt/args.test.js +135 -0
- package/dist/lib/lswt/args.test.js.map +1 -0
- package/dist/lib/lswt/formatters.d.ts +29 -0
- package/dist/lib/lswt/formatters.d.ts.map +1 -0
- package/dist/lib/lswt/formatters.js +113 -0
- package/dist/lib/lswt/formatters.js.map +1 -0
- package/dist/lib/lswt/formatters.test.d.ts +2 -0
- package/dist/lib/lswt/formatters.test.d.ts.map +1 -0
- package/dist/lib/lswt/formatters.test.js +233 -0
- package/dist/lib/lswt/formatters.test.js.map +1 -0
- package/dist/lib/lswt/index.d.ts +9 -0
- package/dist/lib/lswt/index.d.ts.map +1 -0
- package/dist/lib/lswt/index.js +9 -0
- package/dist/lib/lswt/index.js.map +1 -0
- package/dist/lib/lswt/types.d.ts +44 -0
- package/dist/lib/lswt/types.d.ts.map +1 -0
- package/dist/lib/lswt/types.js +5 -0
- package/dist/lib/lswt/types.js.map +1 -0
- package/dist/lib/lswt/worktree-info.d.ts +23 -0
- package/dist/lib/lswt/worktree-info.d.ts.map +1 -0
- package/dist/lib/lswt/worktree-info.js +81 -0
- package/dist/lib/lswt/worktree-info.js.map +1 -0
- package/dist/lib/lswt/worktree-info.test.d.ts +2 -0
- package/dist/lib/lswt/worktree-info.test.d.ts.map +1 -0
- package/dist/lib/lswt/worktree-info.test.js +190 -0
- package/dist/lib/lswt/worktree-info.test.js.map +1 -0
- package/dist/lib/newpr/actions.d.ts +56 -0
- package/dist/lib/newpr/actions.d.ts.map +1 -0
- package/dist/lib/newpr/actions.js +130 -0
- package/dist/lib/newpr/actions.js.map +1 -0
- package/dist/lib/newpr/actions.test.d.ts +2 -0
- package/dist/lib/newpr/actions.test.d.ts.map +1 -0
- package/dist/lib/newpr/actions.test.js +254 -0
- package/dist/lib/newpr/actions.test.js.map +1 -0
- package/dist/lib/newpr/args.d.ts +17 -0
- package/dist/lib/newpr/args.d.ts.map +1 -0
- package/dist/lib/newpr/args.js +123 -0
- package/dist/lib/newpr/args.js.map +1 -0
- package/dist/lib/newpr/args.test.d.ts +2 -0
- package/dist/lib/newpr/args.test.d.ts.map +1 -0
- package/dist/lib/newpr/args.test.js +271 -0
- package/dist/lib/newpr/args.test.js.map +1 -0
- package/dist/lib/newpr/index.d.ts +10 -0
- package/dist/lib/newpr/index.d.ts.map +1 -0
- package/dist/lib/newpr/index.js +8 -0
- package/dist/lib/newpr/index.js.map +1 -0
- package/dist/lib/newpr/scenario-handler.d.ts +40 -0
- package/dist/lib/newpr/scenario-handler.d.ts.map +1 -0
- package/dist/lib/newpr/scenario-handler.js +261 -0
- package/dist/lib/newpr/scenario-handler.js.map +1 -0
- package/dist/lib/newpr/scenario-handler.test.d.ts +2 -0
- package/dist/lib/newpr/scenario-handler.test.d.ts.map +1 -0
- package/dist/lib/newpr/scenario-handler.test.js +250 -0
- package/dist/lib/newpr/scenario-handler.test.js.map +1 -0
- package/dist/lib/newpr/types.d.ts +76 -0
- package/dist/lib/newpr/types.d.ts.map +1 -0
- package/dist/lib/newpr/types.js +5 -0
- package/dist/lib/newpr/types.js.map +1 -0
- package/dist/lib/state-detection.d.ts.map +1 -1
- package/dist/lib/state-detection.js +12 -3
- package/dist/lib/state-detection.js.map +1 -1
- package/dist/lib/state-detection.test.js +253 -2
- package/dist/lib/state-detection.test.js.map +1 -1
- package/dist/lib/wtlink/link-configs.d.ts +40 -0
- package/dist/lib/wtlink/link-configs.d.ts.map +1 -1
- package/dist/lib/wtlink/link-configs.js +126 -11
- package/dist/lib/wtlink/link-configs.js.map +1 -1
- package/dist/lib/wtlink/link-configs.test.js +237 -84
- package/dist/lib/wtlink/link-configs.test.js.map +1 -1
- package/dist/lib/wtlink/manage-manifest.d.ts +86 -0
- package/dist/lib/wtlink/manage-manifest.d.ts.map +1 -1
- package/dist/lib/wtlink/manage-manifest.js +16 -15
- package/dist/lib/wtlink/manage-manifest.js.map +1 -1
- package/dist/lib/wtlink/manage-manifest.test.d.ts +2 -0
- package/dist/lib/wtlink/manage-manifest.test.d.ts.map +1 -0
- package/dist/lib/wtlink/manage-manifest.test.js +383 -0
- package/dist/lib/wtlink/manage-manifest.test.js.map +1 -0
- package/dist/lib/wtlink/validate-manifest.d.ts +27 -0
- package/dist/lib/wtlink/validate-manifest.d.ts.map +1 -1
- package/dist/lib/wtlink/validate-manifest.js +103 -28
- package/dist/lib/wtlink/validate-manifest.js.map +1 -1
- package/dist/lib/wtlink/validate-manifest.test.js +170 -65
- package/dist/lib/wtlink/validate-manifest.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as os from 'os';
|
|
5
|
+
import { parseWorktreeList, parseManifest, isAlreadyLinked, detectConflicts, updateManifest, isBaseBranch, } from './link-configs.js';
|
|
4
6
|
describe('wtlink/link-configs', () => {
|
|
5
7
|
describe('parseWorktreeList', () => {
|
|
6
|
-
// Since parseWorktreeList is not exported, we test it indirectly
|
|
7
|
-
// by testing the behavior of functions that use it
|
|
8
|
-
// or we create a separate testable module
|
|
9
|
-
// For now, let's document the expected parsing behavior
|
|
10
8
|
it('should parse empty worktree list', () => {
|
|
11
9
|
const raw = '';
|
|
12
|
-
const entries =
|
|
10
|
+
const entries = parseWorktreeList(raw);
|
|
13
11
|
expect(entries).toEqual([]);
|
|
14
12
|
});
|
|
15
13
|
it('should parse single worktree entry', () => {
|
|
@@ -18,7 +16,7 @@ HEAD abc123
|
|
|
18
16
|
branch refs/heads/main
|
|
19
17
|
|
|
20
18
|
`;
|
|
21
|
-
const entries =
|
|
19
|
+
const entries = parseWorktreeList(raw);
|
|
22
20
|
expect(entries).toHaveLength(1);
|
|
23
21
|
expect(entries[0]).toEqual({
|
|
24
22
|
path: '/home/user/project',
|
|
@@ -36,7 +34,7 @@ HEAD def456
|
|
|
36
34
|
branch refs/heads/feature/auth
|
|
37
35
|
|
|
38
36
|
`;
|
|
39
|
-
const entries =
|
|
37
|
+
const entries = parseWorktreeList(raw);
|
|
40
38
|
expect(entries).toHaveLength(2);
|
|
41
39
|
expect(entries[0].path).toBe('/home/user/project');
|
|
42
40
|
expect(entries[0].branch).toBe('refs/heads/main');
|
|
@@ -48,7 +46,7 @@ branch refs/heads/feature/auth
|
|
|
48
46
|
bare
|
|
49
47
|
|
|
50
48
|
`;
|
|
51
|
-
const entries =
|
|
49
|
+
const entries = parseWorktreeList(raw);
|
|
52
50
|
expect(entries).toHaveLength(1);
|
|
53
51
|
expect(entries[0].isBare).toBe(true);
|
|
54
52
|
});
|
|
@@ -58,24 +56,32 @@ HEAD abc123
|
|
|
58
56
|
detached
|
|
59
57
|
|
|
60
58
|
`;
|
|
61
|
-
const entries =
|
|
59
|
+
const entries = parseWorktreeList(raw);
|
|
62
60
|
expect(entries).toHaveLength(1);
|
|
63
61
|
expect(entries[0].branch).toBeUndefined();
|
|
64
62
|
});
|
|
63
|
+
it('should handle worktree entry without trailing newlines', () => {
|
|
64
|
+
const raw = `worktree /home/user/project
|
|
65
|
+
HEAD abc123
|
|
66
|
+
branch refs/heads/main`;
|
|
67
|
+
const entries = parseWorktreeList(raw);
|
|
68
|
+
expect(entries).toHaveLength(1);
|
|
69
|
+
expect(entries[0].path).toBe('/home/user/project');
|
|
70
|
+
});
|
|
65
71
|
});
|
|
66
|
-
describe('
|
|
72
|
+
describe('parseManifest', () => {
|
|
67
73
|
it('should parse active entries', () => {
|
|
68
74
|
const manifest = `.env
|
|
69
75
|
.vscode/settings.json
|
|
70
76
|
config/local.json`;
|
|
71
|
-
const entries =
|
|
77
|
+
const entries = parseManifest(manifest);
|
|
72
78
|
expect(entries.active).toEqual(['.env', '.vscode/settings.json', 'config/local.json']);
|
|
73
79
|
expect(entries.commented).toEqual([]);
|
|
74
80
|
});
|
|
75
81
|
it('should parse commented entries', () => {
|
|
76
82
|
const manifest = `# .env.local
|
|
77
83
|
# .vscode/launch.json`;
|
|
78
|
-
const entries =
|
|
84
|
+
const entries = parseManifest(manifest);
|
|
79
85
|
expect(entries.active).toEqual([]);
|
|
80
86
|
expect(entries.commented).toEqual(['.env.local', '.vscode/launch.json']);
|
|
81
87
|
});
|
|
@@ -85,7 +91,7 @@ config/local.json`;
|
|
|
85
91
|
.vscode/settings.json
|
|
86
92
|
# .vscode/launch.json
|
|
87
93
|
`;
|
|
88
|
-
const entries =
|
|
94
|
+
const entries = parseManifest(manifest);
|
|
89
95
|
expect(entries.active).toEqual(['.env', '.vscode/settings.json']);
|
|
90
96
|
expect(entries.commented).toEqual(['.env.local', '.vscode/launch.json']);
|
|
91
97
|
});
|
|
@@ -95,7 +101,7 @@ config/local.json`;
|
|
|
95
101
|
.vscode/settings.json
|
|
96
102
|
|
|
97
103
|
`;
|
|
98
|
-
const entries =
|
|
104
|
+
const entries = parseManifest(manifest);
|
|
99
105
|
expect(entries.active).toEqual(['.env', '.vscode/settings.json']);
|
|
100
106
|
});
|
|
101
107
|
it('should handle header comments (multiple #)', () => {
|
|
@@ -103,77 +109,224 @@ config/local.json`;
|
|
|
103
109
|
# This is a comment about the manifest
|
|
104
110
|
.env
|
|
105
111
|
# .env.local`;
|
|
106
|
-
const entries =
|
|
112
|
+
const entries = parseManifest(manifest);
|
|
107
113
|
// Lines starting with ## are header comments, not file entries
|
|
114
|
+
// "This is a comment about the manifest" doesn't look like a file path, so skipped
|
|
108
115
|
expect(entries.active).toEqual(['.env']);
|
|
109
116
|
expect(entries.commented).toEqual(['.env.local']);
|
|
110
117
|
});
|
|
118
|
+
it('should detect file paths with extensions', () => {
|
|
119
|
+
const manifest = `# config.yaml
|
|
120
|
+
# data.json`;
|
|
121
|
+
const entries = parseManifest(manifest);
|
|
122
|
+
expect(entries.commented).toEqual(['config.yaml', 'data.json']);
|
|
123
|
+
});
|
|
124
|
+
it('should skip descriptive comments', () => {
|
|
125
|
+
const manifest = `# This is just a regular comment
|
|
126
|
+
# Remember to update this file
|
|
127
|
+
.env`;
|
|
128
|
+
const entries = parseManifest(manifest);
|
|
129
|
+
expect(entries.active).toEqual(['.env']);
|
|
130
|
+
expect(entries.commented).toEqual([]);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
describe('isAlreadyLinked', () => {
|
|
134
|
+
let tempDir;
|
|
135
|
+
beforeEach(() => {
|
|
136
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'link-configs-test-'));
|
|
137
|
+
});
|
|
138
|
+
afterEach(() => {
|
|
139
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
140
|
+
});
|
|
141
|
+
it('should return false when dest does not exist', () => {
|
|
142
|
+
const sourcePath = path.join(tempDir, 'source.txt');
|
|
143
|
+
const destPath = path.join(tempDir, 'dest.txt');
|
|
144
|
+
fs.writeFileSync(sourcePath, 'content');
|
|
145
|
+
expect(isAlreadyLinked(sourcePath, destPath)).toBe(false);
|
|
146
|
+
});
|
|
147
|
+
it('should return true for hard-linked files', () => {
|
|
148
|
+
const sourcePath = path.join(tempDir, 'source.txt');
|
|
149
|
+
const destPath = path.join(tempDir, 'dest.txt');
|
|
150
|
+
fs.writeFileSync(sourcePath, 'content');
|
|
151
|
+
fs.linkSync(sourcePath, destPath);
|
|
152
|
+
expect(isAlreadyLinked(sourcePath, destPath)).toBe(true);
|
|
153
|
+
});
|
|
154
|
+
it('should return true for symbolic links pointing to source', () => {
|
|
155
|
+
const sourcePath = path.join(tempDir, 'source.txt');
|
|
156
|
+
const destPath = path.join(tempDir, 'dest.txt');
|
|
157
|
+
fs.writeFileSync(sourcePath, 'content');
|
|
158
|
+
fs.symlinkSync(sourcePath, destPath);
|
|
159
|
+
expect(isAlreadyLinked(sourcePath, destPath)).toBe(true);
|
|
160
|
+
});
|
|
161
|
+
it('should return false for different files with same content', () => {
|
|
162
|
+
const sourcePath = path.join(tempDir, 'source.txt');
|
|
163
|
+
const destPath = path.join(tempDir, 'dest.txt');
|
|
164
|
+
fs.writeFileSync(sourcePath, 'content');
|
|
165
|
+
fs.writeFileSync(destPath, 'content');
|
|
166
|
+
expect(isAlreadyLinked(sourcePath, destPath)).toBe(false);
|
|
167
|
+
});
|
|
168
|
+
it('should return false for different files', () => {
|
|
169
|
+
const sourcePath = path.join(tempDir, 'source.txt');
|
|
170
|
+
const destPath = path.join(tempDir, 'dest.txt');
|
|
171
|
+
fs.writeFileSync(sourcePath, 'source content');
|
|
172
|
+
fs.writeFileSync(destPath, 'dest content');
|
|
173
|
+
expect(isAlreadyLinked(sourcePath, destPath)).toBe(false);
|
|
174
|
+
});
|
|
175
|
+
it('should return false on error', () => {
|
|
176
|
+
// Non-existent paths should return false, not throw
|
|
177
|
+
expect(isAlreadyLinked('/nonexistent/source', '/nonexistent/dest')).toBe(false);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
describe('detectConflicts', () => {
|
|
181
|
+
let tempDir;
|
|
182
|
+
let sourceDir;
|
|
183
|
+
let destDir;
|
|
184
|
+
beforeEach(() => {
|
|
185
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'link-configs-test-'));
|
|
186
|
+
sourceDir = path.join(tempDir, 'source');
|
|
187
|
+
destDir = path.join(tempDir, 'dest');
|
|
188
|
+
fs.mkdirSync(sourceDir, { recursive: true });
|
|
189
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
190
|
+
});
|
|
191
|
+
afterEach(() => {
|
|
192
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
193
|
+
});
|
|
194
|
+
it('should detect safe files (no conflict)', () => {
|
|
195
|
+
fs.writeFileSync(path.join(sourceDir, 'file.txt'), 'content');
|
|
196
|
+
const report = detectConflicts(['file.txt'], sourceDir, destDir);
|
|
197
|
+
expect(report.safe).toHaveLength(1);
|
|
198
|
+
expect(report.safe[0].file).toBe('file.txt');
|
|
199
|
+
expect(report.alreadyLinked).toHaveLength(0);
|
|
200
|
+
expect(report.conflicts).toHaveLength(0);
|
|
201
|
+
});
|
|
202
|
+
it('should detect already linked files', () => {
|
|
203
|
+
const sourceFile = path.join(sourceDir, 'file.txt');
|
|
204
|
+
const destFile = path.join(destDir, 'file.txt');
|
|
205
|
+
fs.writeFileSync(sourceFile, 'content');
|
|
206
|
+
fs.linkSync(sourceFile, destFile);
|
|
207
|
+
const report = detectConflicts(['file.txt'], sourceDir, destDir);
|
|
208
|
+
expect(report.safe).toHaveLength(0);
|
|
209
|
+
expect(report.alreadyLinked).toHaveLength(1);
|
|
210
|
+
expect(report.alreadyLinked[0].file).toBe('file.txt');
|
|
211
|
+
expect(report.conflicts).toHaveLength(0);
|
|
212
|
+
});
|
|
213
|
+
it('should detect conflicts', () => {
|
|
214
|
+
fs.writeFileSync(path.join(sourceDir, 'file.txt'), 'source content');
|
|
215
|
+
fs.writeFileSync(path.join(destDir, 'file.txt'), 'different content');
|
|
216
|
+
const report = detectConflicts(['file.txt'], sourceDir, destDir);
|
|
217
|
+
expect(report.safe).toHaveLength(0);
|
|
218
|
+
expect(report.alreadyLinked).toHaveLength(0);
|
|
219
|
+
expect(report.conflicts).toHaveLength(1);
|
|
220
|
+
expect(report.conflicts[0].file).toBe('file.txt');
|
|
221
|
+
});
|
|
222
|
+
it('should skip files that do not exist in source', () => {
|
|
223
|
+
const report = detectConflicts(['nonexistent.txt'], sourceDir, destDir);
|
|
224
|
+
expect(report.safe).toHaveLength(0);
|
|
225
|
+
expect(report.alreadyLinked).toHaveLength(0);
|
|
226
|
+
expect(report.conflicts).toHaveLength(0);
|
|
227
|
+
});
|
|
228
|
+
it('should handle multiple files with mixed states', () => {
|
|
229
|
+
// Safe file
|
|
230
|
+
fs.writeFileSync(path.join(sourceDir, 'safe.txt'), 'content');
|
|
231
|
+
// Already linked file
|
|
232
|
+
const linkedSource = path.join(sourceDir, 'linked.txt');
|
|
233
|
+
const linkedDest = path.join(destDir, 'linked.txt');
|
|
234
|
+
fs.writeFileSync(linkedSource, 'linked content');
|
|
235
|
+
fs.linkSync(linkedSource, linkedDest);
|
|
236
|
+
// Conflict file
|
|
237
|
+
fs.writeFileSync(path.join(sourceDir, 'conflict.txt'), 'source');
|
|
238
|
+
fs.writeFileSync(path.join(destDir, 'conflict.txt'), 'dest');
|
|
239
|
+
const report = detectConflicts(['safe.txt', 'linked.txt', 'conflict.txt'], sourceDir, destDir);
|
|
240
|
+
expect(report.safe).toHaveLength(1);
|
|
241
|
+
expect(report.safe[0].file).toBe('safe.txt');
|
|
242
|
+
expect(report.alreadyLinked).toHaveLength(1);
|
|
243
|
+
expect(report.alreadyLinked[0].file).toBe('linked.txt');
|
|
244
|
+
expect(report.conflicts).toHaveLength(1);
|
|
245
|
+
expect(report.conflicts[0].file).toBe('conflict.txt');
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
describe('updateManifest', () => {
|
|
249
|
+
let tempDir;
|
|
250
|
+
let manifestPath;
|
|
251
|
+
beforeEach(() => {
|
|
252
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'link-configs-test-'));
|
|
253
|
+
manifestPath = path.join(tempDir, '.wtlink');
|
|
254
|
+
});
|
|
255
|
+
afterEach(() => {
|
|
256
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
257
|
+
});
|
|
258
|
+
it('should remove specified files from manifest', () => {
|
|
259
|
+
fs.writeFileSync(manifestPath, `.env
|
|
260
|
+
.vscode/settings.json
|
|
261
|
+
config/local.json`);
|
|
262
|
+
updateManifest(manifestPath, ['.vscode/settings.json']);
|
|
263
|
+
const result = fs.readFileSync(manifestPath, 'utf-8');
|
|
264
|
+
expect(result).toBe(`.env
|
|
265
|
+
config/local.json`);
|
|
266
|
+
});
|
|
267
|
+
it('should keep empty lines and header comments', () => {
|
|
268
|
+
fs.writeFileSync(manifestPath, `## Header
|
|
269
|
+
.env
|
|
270
|
+
|
|
271
|
+
.vscode/settings.json`);
|
|
272
|
+
updateManifest(manifestPath, ['.vscode/settings.json']);
|
|
273
|
+
const result = fs.readFileSync(manifestPath, 'utf-8');
|
|
274
|
+
expect(result).toBe(`## Header
|
|
275
|
+
.env
|
|
276
|
+
`);
|
|
277
|
+
});
|
|
278
|
+
it('should remove commented entries when they match', () => {
|
|
279
|
+
fs.writeFileSync(manifestPath, `.env
|
|
280
|
+
# .env.local
|
|
281
|
+
.vscode/settings.json`);
|
|
282
|
+
updateManifest(manifestPath, ['.env.local']);
|
|
283
|
+
const result = fs.readFileSync(manifestPath, 'utf-8');
|
|
284
|
+
expect(result).toBe(`.env
|
|
285
|
+
.vscode/settings.json`);
|
|
286
|
+
});
|
|
287
|
+
it('should handle entries with TRACKED/DELETED/STALE prefixes', () => {
|
|
288
|
+
fs.writeFileSync(manifestPath, `.env
|
|
289
|
+
# TRACKED: old-file.txt
|
|
290
|
+
# DELETED: removed.txt
|
|
291
|
+
.vscode/settings.json`);
|
|
292
|
+
updateManifest(manifestPath, ['old-file.txt', 'removed.txt']);
|
|
293
|
+
const result = fs.readFileSync(manifestPath, 'utf-8');
|
|
294
|
+
expect(result).toBe(`.env
|
|
295
|
+
.vscode/settings.json`);
|
|
296
|
+
});
|
|
297
|
+
it('should handle empty removal list', () => {
|
|
298
|
+
const original = `.env
|
|
299
|
+
.vscode/settings.json`;
|
|
300
|
+
fs.writeFileSync(manifestPath, original);
|
|
301
|
+
updateManifest(manifestPath, []);
|
|
302
|
+
const result = fs.readFileSync(manifestPath, 'utf-8');
|
|
303
|
+
expect(result).toBe(original);
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
describe('isBaseBranch', () => {
|
|
307
|
+
it('should return true for main branch', () => {
|
|
308
|
+
expect(isBaseBranch('main')).toBe(true);
|
|
309
|
+
});
|
|
310
|
+
it('should return true for master branch', () => {
|
|
311
|
+
expect(isBaseBranch('master')).toBe(true);
|
|
312
|
+
});
|
|
313
|
+
it('should return true for develop branch', () => {
|
|
314
|
+
expect(isBaseBranch('develop')).toBe(true);
|
|
315
|
+
});
|
|
316
|
+
it('should return false for feature branches', () => {
|
|
317
|
+
expect(isBaseBranch('feature/auth')).toBe(false);
|
|
318
|
+
expect(isBaseBranch('feature-123')).toBe(false);
|
|
319
|
+
});
|
|
320
|
+
it('should return false for PR branches', () => {
|
|
321
|
+
expect(isBaseBranch('claude/fix-issue-123')).toBe(false);
|
|
322
|
+
expect(isBaseBranch('pr-42')).toBe(false);
|
|
323
|
+
});
|
|
324
|
+
it('should return false for null', () => {
|
|
325
|
+
expect(isBaseBranch(null)).toBe(false);
|
|
326
|
+
});
|
|
327
|
+
it('should return false for empty string', () => {
|
|
328
|
+
expect(isBaseBranch('')).toBe(false);
|
|
329
|
+
});
|
|
111
330
|
});
|
|
112
331
|
});
|
|
113
|
-
function parseWorktreeListHelper(raw) {
|
|
114
|
-
const entries = [];
|
|
115
|
-
const lines = raw.split('\n');
|
|
116
|
-
let current = null;
|
|
117
|
-
for (const rawLine of lines) {
|
|
118
|
-
const line = rawLine.trim();
|
|
119
|
-
if (!line) {
|
|
120
|
-
if (current && current.path) {
|
|
121
|
-
entries.push(current);
|
|
122
|
-
}
|
|
123
|
-
current = null;
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
if (!current) {
|
|
127
|
-
current = { path: '', isBare: false };
|
|
128
|
-
}
|
|
129
|
-
if (line.startsWith('worktree ')) {
|
|
130
|
-
current.path = line.substring('worktree '.length).trim();
|
|
131
|
-
}
|
|
132
|
-
else if (line.startsWith('branch ')) {
|
|
133
|
-
current.branch = line.substring('branch '.length).trim();
|
|
134
|
-
}
|
|
135
|
-
else if (line === 'bare') {
|
|
136
|
-
current.isBare = true;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
if (current && current.path) {
|
|
140
|
-
entries.push(current);
|
|
141
|
-
}
|
|
142
|
-
return entries;
|
|
143
|
-
}
|
|
144
|
-
function parseManifestHelper(content) {
|
|
145
|
-
const active = [];
|
|
146
|
-
const commented = [];
|
|
147
|
-
for (const rawLine of content.split('\n')) {
|
|
148
|
-
const line = rawLine.trim();
|
|
149
|
-
if (!line) {
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
// Skip header comments (lines starting with ##)
|
|
153
|
-
if (line.startsWith('##')) {
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
if (line.startsWith('#')) {
|
|
157
|
-
// Extract file path from comment
|
|
158
|
-
const filePath = line.substring(1).trim();
|
|
159
|
-
// Skip if it's another comment marker or empty
|
|
160
|
-
if (!filePath || filePath.startsWith('#')) {
|
|
161
|
-
continue;
|
|
162
|
-
}
|
|
163
|
-
// Only count as a commented file entry if it looks like a file path
|
|
164
|
-
// (starts with . or / or contains / or has a file extension)
|
|
165
|
-
if (filePath.startsWith('.') ||
|
|
166
|
-
filePath.startsWith('/') ||
|
|
167
|
-
filePath.includes('/') ||
|
|
168
|
-
/\.\w+$/.test(filePath)) {
|
|
169
|
-
commented.push(filePath);
|
|
170
|
-
}
|
|
171
|
-
// Otherwise it's a descriptive comment, skip it
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
active.push(line);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return { active, commented };
|
|
178
|
-
}
|
|
179
332
|
//# sourceMappingURL=link-configs.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link-configs.test.js","sourceRoot":"","sources":["../../../src/lib/wtlink/link-configs.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"link-configs.test.js","sourceRoot":"","sources":["../../../src/lib/wtlink/link-configs.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
export type FileDecision = 'add' | 'comment' | 'skip';
|
|
2
|
+
export type ItemState = FileDecision | 'undecided';
|
|
3
|
+
export type ViewMode = 'flat' | 'hierarchical';
|
|
4
|
+
export interface FileNode {
|
|
5
|
+
readonly path: string;
|
|
6
|
+
readonly isDirectory: boolean;
|
|
7
|
+
readonly children: ReadonlyArray<FileNode>;
|
|
8
|
+
}
|
|
9
|
+
export interface AppState {
|
|
10
|
+
readonly fileTree: FileNode;
|
|
11
|
+
readonly decisions: ReadonlyMap<string, FileDecision>;
|
|
12
|
+
readonly viewMode: ViewMode;
|
|
13
|
+
readonly activeFilters: ReadonlySet<ItemState>;
|
|
14
|
+
readonly showHelp: boolean;
|
|
15
|
+
readonly navigationStack: ReadonlyArray<string>;
|
|
16
|
+
readonly cursorIndex: number;
|
|
17
|
+
readonly scrollOffset: number;
|
|
18
|
+
}
|
|
19
|
+
export interface DisplayItem {
|
|
20
|
+
readonly path: string;
|
|
21
|
+
readonly isDirectory: boolean;
|
|
22
|
+
readonly node?: FileNode;
|
|
23
|
+
readonly states: ReadonlySet<ItemState>;
|
|
24
|
+
}
|
|
1
25
|
export interface ManageArgv {
|
|
2
26
|
nonInteractive: boolean;
|
|
3
27
|
clean: boolean;
|
|
@@ -5,5 +29,67 @@ export interface ManageArgv {
|
|
|
5
29
|
manifestFile: string;
|
|
6
30
|
backup: boolean;
|
|
7
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Get all file paths from a node (recursively)
|
|
34
|
+
*/
|
|
35
|
+
export declare function getAllFiles(node: FileNode): string[];
|
|
36
|
+
/**
|
|
37
|
+
* Get all directory nodes from a tree (recursively)
|
|
38
|
+
*/
|
|
39
|
+
export declare function getAllDirectories(node: FileNode): FileNode[];
|
|
40
|
+
/**
|
|
41
|
+
* Get the computed state for a single file
|
|
42
|
+
* Returns 'undecided' (explicit state) if file not in decisions map
|
|
43
|
+
*/
|
|
44
|
+
export declare function getFileDecision(decisions: ReadonlyMap<string, FileDecision>, filePath: string): ItemState;
|
|
45
|
+
/**
|
|
46
|
+
* Get all computed states present in a folder's descendants
|
|
47
|
+
* A folder can have multiple states if children have different states
|
|
48
|
+
* This is DERIVED from children - folders don't have their own decision
|
|
49
|
+
* 'undecided' is an explicit state for items with no decision
|
|
50
|
+
*/
|
|
51
|
+
export declare function getFolderStates(node: FileNode, decisions: ReadonlyMap<string, FileDecision>): ReadonlySet<ItemState>;
|
|
52
|
+
/**
|
|
53
|
+
* Get state breakdown counts for a folder
|
|
54
|
+
*/
|
|
55
|
+
export declare function getFolderStateBreakdown(node: FileNode, decisions: ReadonlyMap<string, FileDecision>): {
|
|
56
|
+
add: number;
|
|
57
|
+
comment: number;
|
|
58
|
+
skip: number;
|
|
59
|
+
undecided: number;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Check if an item should be visible based on current filters
|
|
63
|
+
* An item is visible if it has at least one state matching the active filters
|
|
64
|
+
* Default: only 'undecided' filter is active (shows undecided items)
|
|
65
|
+
*/
|
|
66
|
+
export declare function isItemVisible(item: DisplayItem, activeFilters: ReadonlySet<ItemState>): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Build file tree from flat list of file paths
|
|
69
|
+
*/
|
|
70
|
+
export declare function buildFileTree(filePaths: string[]): FileNode;
|
|
71
|
+
/**
|
|
72
|
+
* Find a node by path in the tree
|
|
73
|
+
*/
|
|
74
|
+
export declare function findNodeByPath(tree: FileNode, targetPath: string): FileNode | null;
|
|
75
|
+
/**
|
|
76
|
+
* Get items to display in hierarchical view
|
|
77
|
+
* Folders appear first, then files (both alphabetically sorted within their groups)
|
|
78
|
+
*/
|
|
79
|
+
export declare function getHierarchicalViewItems(tree: FileNode, navigationStack: ReadonlyArray<string>, decisions: ReadonlyMap<string, FileDecision>): DisplayItem[];
|
|
80
|
+
/**
|
|
81
|
+
* Get items to display in flat view
|
|
82
|
+
*/
|
|
83
|
+
export declare function getFlatViewItems(tree: FileNode, decisions: ReadonlyMap<string, FileDecision>): DisplayItem[];
|
|
84
|
+
/**
|
|
85
|
+
* Get all visible items for current state (SINGLE SOURCE OF TRUTH)
|
|
86
|
+
*/
|
|
87
|
+
export declare function getVisibleItems(state: AppState): DisplayItem[];
|
|
88
|
+
/**
|
|
89
|
+
* Get display items with back navigation if needed
|
|
90
|
+
*/
|
|
91
|
+
export declare function getDisplayItems(state: AppState): DisplayItem[];
|
|
92
|
+
export declare const COMMON_IGNORE_DIRS: string[];
|
|
93
|
+
export declare function isCommonIgnoreDir(dirPath: string): boolean;
|
|
8
94
|
export declare function run(argv: ManageArgv): Promise<void>;
|
|
9
95
|
//# sourceMappingURL=manage-manifest.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manage-manifest.d.ts","sourceRoot":"","sources":["../../../src/lib/wtlink/manage-manifest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manage-manifest.d.ts","sourceRoot":"","sources":["../../../src/lib/wtlink/manage-manifest.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;AAGtD,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,WAAW,CAAC;AAEnD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,cAAc,CAAC;AAE/C,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAC/C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;CACjB;AAMD;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CAKpD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAa5D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,EAC5C,QAAQ,EAAE,MAAM,GACf,SAAS,CAEX;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,GAC3C,WAAW,CAAC,SAAS,CAAC,CAaxB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,GAC3C;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAUnE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,CAAC,SAAS,CAAC,GAAG,OAAO,CAc/F;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,QAAQ,CAoD3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAWlF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,QAAQ,EACd,eAAe,EAAE,aAAa,CAAC,MAAM,CAAC,EACtC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,GAC3C,WAAW,EAAE,CA4Bf;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,GAC3C,WAAW,EAAE,CA2Bf;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,WAAW,EAAE,CAS9D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,WAAW,EAAE,CAsB9D;AA0ID,eAAO,MAAM,kBAAkB,UAmB9B,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAG1D;AA23BD,wBAAsB,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA+LzD"}
|
|
@@ -13,7 +13,7 @@ import { signal, computed } from '@preact/signals-core';
|
|
|
13
13
|
/**
|
|
14
14
|
* Get all file paths from a node (recursively)
|
|
15
15
|
*/
|
|
16
|
-
function getAllFiles(node) {
|
|
16
|
+
export function getAllFiles(node) {
|
|
17
17
|
if (!node.isDirectory) {
|
|
18
18
|
return [node.path];
|
|
19
19
|
}
|
|
@@ -22,7 +22,7 @@ function getAllFiles(node) {
|
|
|
22
22
|
/**
|
|
23
23
|
* Get all directory nodes from a tree (recursively)
|
|
24
24
|
*/
|
|
25
|
-
function getAllDirectories(node) {
|
|
25
|
+
export function getAllDirectories(node) {
|
|
26
26
|
if (!node.isDirectory) {
|
|
27
27
|
return [];
|
|
28
28
|
}
|
|
@@ -39,7 +39,7 @@ function getAllDirectories(node) {
|
|
|
39
39
|
* Get the computed state for a single file
|
|
40
40
|
* Returns 'undecided' (explicit state) if file not in decisions map
|
|
41
41
|
*/
|
|
42
|
-
function getFileDecision(decisions, filePath) {
|
|
42
|
+
export function getFileDecision(decisions, filePath) {
|
|
43
43
|
return decisions.get(filePath) ?? 'undecided';
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
@@ -48,7 +48,7 @@ function getFileDecision(decisions, filePath) {
|
|
|
48
48
|
* This is DERIVED from children - folders don't have their own decision
|
|
49
49
|
* 'undecided' is an explicit state for items with no decision
|
|
50
50
|
*/
|
|
51
|
-
function getFolderStates(node, decisions) {
|
|
51
|
+
export function getFolderStates(node, decisions) {
|
|
52
52
|
if (!node.isDirectory) {
|
|
53
53
|
return new Set([getFileDecision(decisions, node.path)]);
|
|
54
54
|
}
|
|
@@ -62,7 +62,7 @@ function getFolderStates(node, decisions) {
|
|
|
62
62
|
/**
|
|
63
63
|
* Get state breakdown counts for a folder
|
|
64
64
|
*/
|
|
65
|
-
function getFolderStateBreakdown(node, decisions) {
|
|
65
|
+
export function getFolderStateBreakdown(node, decisions) {
|
|
66
66
|
const breakdown = { add: 0, comment: 0, skip: 0, undecided: 0 };
|
|
67
67
|
const allFiles = getAllFiles(node);
|
|
68
68
|
for (const filePath of allFiles) {
|
|
@@ -76,7 +76,7 @@ function getFolderStateBreakdown(node, decisions) {
|
|
|
76
76
|
* An item is visible if it has at least one state matching the active filters
|
|
77
77
|
* Default: only 'undecided' filter is active (shows undecided items)
|
|
78
78
|
*/
|
|
79
|
-
function isItemVisible(item, activeFilters) {
|
|
79
|
+
export function isItemVisible(item, activeFilters) {
|
|
80
80
|
// If no filters active, nothing is visible (edge case)
|
|
81
81
|
if (activeFilters.size === 0) {
|
|
82
82
|
return false;
|
|
@@ -92,7 +92,7 @@ function isItemVisible(item, activeFilters) {
|
|
|
92
92
|
/**
|
|
93
93
|
* Build file tree from flat list of file paths
|
|
94
94
|
*/
|
|
95
|
-
function buildFileTree(filePaths) {
|
|
95
|
+
export function buildFileTree(filePaths) {
|
|
96
96
|
const root = {
|
|
97
97
|
path: '',
|
|
98
98
|
isDirectory: true,
|
|
@@ -134,7 +134,7 @@ function buildFileTree(filePaths) {
|
|
|
134
134
|
/**
|
|
135
135
|
* Find a node by path in the tree
|
|
136
136
|
*/
|
|
137
|
-
function findNodeByPath(tree, targetPath) {
|
|
137
|
+
export function findNodeByPath(tree, targetPath) {
|
|
138
138
|
if (tree.path === targetPath) {
|
|
139
139
|
return tree;
|
|
140
140
|
}
|
|
@@ -149,7 +149,7 @@ function findNodeByPath(tree, targetPath) {
|
|
|
149
149
|
* Get items to display in hierarchical view
|
|
150
150
|
* Folders appear first, then files (both alphabetically sorted within their groups)
|
|
151
151
|
*/
|
|
152
|
-
function getHierarchicalViewItems(tree, navigationStack, decisions) {
|
|
152
|
+
export function getHierarchicalViewItems(tree, navigationStack, decisions) {
|
|
153
153
|
// Navigate to current directory
|
|
154
154
|
let currentNode = tree;
|
|
155
155
|
for (const dirPath of navigationStack) {
|
|
@@ -177,7 +177,7 @@ function getHierarchicalViewItems(tree, navigationStack, decisions) {
|
|
|
177
177
|
/**
|
|
178
178
|
* Get items to display in flat view
|
|
179
179
|
*/
|
|
180
|
-
function getFlatViewItems(tree, decisions) {
|
|
180
|
+
export function getFlatViewItems(tree, decisions) {
|
|
181
181
|
const items = [];
|
|
182
182
|
// Add all directories
|
|
183
183
|
const allDirs = getAllDirectories(tree);
|
|
@@ -205,7 +205,7 @@ function getFlatViewItems(tree, decisions) {
|
|
|
205
205
|
/**
|
|
206
206
|
* Get all visible items for current state (SINGLE SOURCE OF TRUTH)
|
|
207
207
|
*/
|
|
208
|
-
function getVisibleItems(state) {
|
|
208
|
+
export function getVisibleItems(state) {
|
|
209
209
|
// Get items based on view mode
|
|
210
210
|
const allItems = state.viewMode === 'flat'
|
|
211
211
|
? getFlatViewItems(state.fileTree, state.decisions)
|
|
@@ -216,7 +216,7 @@ function getVisibleItems(state) {
|
|
|
216
216
|
/**
|
|
217
217
|
* Get display items with back navigation if needed
|
|
218
218
|
*/
|
|
219
|
-
function getDisplayItems(state) {
|
|
219
|
+
export function getDisplayItems(state) {
|
|
220
220
|
const items = getVisibleItems(state);
|
|
221
221
|
// Add back navigation in hierarchical view when in default undecided-only mode
|
|
222
222
|
const showingUndecidedOnly = state.activeFilters.size === 1 && state.activeFilters.has('undecided');
|
|
@@ -332,7 +332,8 @@ function _updateScroll(state) {
|
|
|
332
332
|
const headerLines = 8;
|
|
333
333
|
const footerLines = 3;
|
|
334
334
|
const maxVisibleItems = Math.max(5, terminalHeight - headerLines - footerLines);
|
|
335
|
-
|
|
335
|
+
const { cursorIndex } = state;
|
|
336
|
+
let { scrollOffset } = state;
|
|
336
337
|
// Auto-scroll to keep cursor in view
|
|
337
338
|
if (cursorIndex < scrollOffset) {
|
|
338
339
|
scrollOffset = cursorIndex;
|
|
@@ -347,7 +348,7 @@ function _updateScroll(state) {
|
|
|
347
348
|
// ============================================================================
|
|
348
349
|
// COMMON DIRECTORIES
|
|
349
350
|
// ============================================================================
|
|
350
|
-
const COMMON_IGNORE_DIRS = [
|
|
351
|
+
export const COMMON_IGNORE_DIRS = [
|
|
351
352
|
'node_modules',
|
|
352
353
|
'bin',
|
|
353
354
|
'obj',
|
|
@@ -367,7 +368,7 @@ const COMMON_IGNORE_DIRS = [
|
|
|
367
368
|
'.gradle',
|
|
368
369
|
'vendor',
|
|
369
370
|
];
|
|
370
|
-
function isCommonIgnoreDir(dirPath) {
|
|
371
|
+
export function isCommonIgnoreDir(dirPath) {
|
|
371
372
|
const parts = dirPath.split('/');
|
|
372
373
|
return COMMON_IGNORE_DIRS.some((ignoreDir) => parts.includes(ignoreDir));
|
|
373
374
|
}
|