@camaradesuk/git-worktree-tools 1.5.0 → 1.6.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 (135) hide show
  1. package/README.md +82 -11
  2. package/dist/cli/cleanpr.js +35 -4
  3. package/dist/cli/cleanpr.js.map +1 -1
  4. package/dist/cli/cleanpr.test.js +254 -0
  5. package/dist/cli/cleanpr.test.js.map +1 -1
  6. package/dist/cli/lswt.js +54 -6
  7. package/dist/cli/lswt.js.map +1 -1
  8. package/dist/cli/lswt.test.js +207 -0
  9. package/dist/cli/lswt.test.js.map +1 -1
  10. package/dist/cli/newpr.js +87 -65
  11. package/dist/cli/newpr.js.map +1 -1
  12. package/dist/cli/newpr.test.js +2 -1
  13. package/dist/cli/newpr.test.js.map +1 -1
  14. package/dist/cli/wt/clean.d.ts +16 -0
  15. package/dist/cli/wt/clean.d.ts.map +1 -0
  16. package/dist/cli/wt/clean.js +64 -0
  17. package/dist/cli/wt/clean.js.map +1 -0
  18. package/dist/cli/wt/completion.d.ts +12 -0
  19. package/dist/cli/wt/completion.d.ts.map +1 -0
  20. package/dist/cli/wt/completion.js +246 -0
  21. package/dist/cli/wt/completion.js.map +1 -0
  22. package/dist/cli/wt/completion.test.d.ts +5 -0
  23. package/dist/cli/wt/completion.test.d.ts.map +1 -0
  24. package/dist/cli/wt/completion.test.js +173 -0
  25. package/dist/cli/wt/completion.test.js.map +1 -0
  26. package/dist/cli/wt/config.d.ts +13 -0
  27. package/dist/cli/wt/config.d.ts.map +1 -0
  28. package/dist/cli/wt/config.js +40 -0
  29. package/dist/cli/wt/config.js.map +1 -0
  30. package/dist/cli/wt/entry.test.d.ts +8 -0
  31. package/dist/cli/wt/entry.test.d.ts.map +1 -0
  32. package/dist/cli/wt/entry.test.js +198 -0
  33. package/dist/cli/wt/entry.test.js.map +1 -0
  34. package/dist/cli/wt/link.d.ts +13 -0
  35. package/dist/cli/wt/link.d.ts.map +1 -0
  36. package/dist/cli/wt/link.js +88 -0
  37. package/dist/cli/wt/link.js.map +1 -0
  38. package/dist/cli/wt/list.d.ts +16 -0
  39. package/dist/cli/wt/list.d.ts.map +1 -0
  40. package/dist/cli/wt/list.js +65 -0
  41. package/dist/cli/wt/list.js.map +1 -0
  42. package/dist/cli/wt/new.d.ts +18 -0
  43. package/dist/cli/wt/new.d.ts.map +1 -0
  44. package/dist/cli/wt/new.js +78 -0
  45. package/dist/cli/wt/new.js.map +1 -0
  46. package/dist/cli/wt/run-command.d.ts +31 -0
  47. package/dist/cli/wt/run-command.d.ts.map +1 -0
  48. package/dist/cli/wt/run-command.js +49 -0
  49. package/dist/cli/wt/run-command.js.map +1 -0
  50. package/dist/cli/wt/run-command.test.d.ts +5 -0
  51. package/dist/cli/wt/run-command.test.d.ts.map +1 -0
  52. package/dist/cli/wt/run-command.test.js +88 -0
  53. package/dist/cli/wt/run-command.test.js.map +1 -0
  54. package/dist/cli/wt/state.d.ts +13 -0
  55. package/dist/cli/wt/state.d.ts.map +1 -0
  56. package/dist/cli/wt/state.js +38 -0
  57. package/dist/cli/wt/state.js.map +1 -0
  58. package/dist/cli/wt/wt.test.d.ts +8 -0
  59. package/dist/cli/wt/wt.test.d.ts.map +1 -0
  60. package/dist/cli/wt/wt.test.js +378 -0
  61. package/dist/cli/wt/wt.test.js.map +1 -0
  62. package/dist/cli/wt.d.ts +25 -0
  63. package/dist/cli/wt.d.ts.map +1 -0
  64. package/dist/cli/wt.js +74 -0
  65. package/dist/cli/wt.js.map +1 -0
  66. package/dist/cli/wtconfig.js +4 -4
  67. package/dist/cli/wtconfig.js.map +1 -1
  68. package/dist/cli/wtlink.js +66 -9
  69. package/dist/cli/wtlink.js.map +1 -1
  70. package/dist/cli/wtlink.test.js +101 -0
  71. package/dist/cli/wtlink.test.js.map +1 -1
  72. package/dist/e2e/cli.e2e.test.js +97 -1
  73. package/dist/e2e/cli.e2e.test.js.map +1 -1
  74. package/dist/e2e/lswt/lswt.e2e.test.js +33 -0
  75. package/dist/e2e/lswt/lswt.e2e.test.js.map +1 -1
  76. package/dist/e2e/wtlink/wtlink.e2e.test.js +52 -0
  77. package/dist/e2e/wtlink/wtlink.e2e.test.js.map +1 -1
  78. package/dist/lib/json-output.d.ts +11 -1
  79. package/dist/lib/json-output.d.ts.map +1 -1
  80. package/dist/lib/json-output.js +42 -1
  81. package/dist/lib/json-output.js.map +1 -1
  82. package/dist/lib/json-output.test.js +2 -0
  83. package/dist/lib/json-output.test.js.map +1 -1
  84. package/dist/lib/lswt/formatters.d.ts +1 -0
  85. package/dist/lib/lswt/formatters.d.ts.map +1 -1
  86. package/dist/lib/lswt/formatters.js +6 -1
  87. package/dist/lib/lswt/formatters.js.map +1 -1
  88. package/dist/lib/lswt/formatters.test.js +2 -2
  89. package/dist/lib/lswt/formatters.test.js.map +1 -1
  90. package/dist/lib/lswt/fuzzy-search.d.ts +27 -0
  91. package/dist/lib/lswt/fuzzy-search.d.ts.map +1 -0
  92. package/dist/lib/lswt/fuzzy-search.js +130 -0
  93. package/dist/lib/lswt/fuzzy-search.js.map +1 -0
  94. package/dist/lib/lswt/fuzzy-search.test.d.ts +5 -0
  95. package/dist/lib/lswt/fuzzy-search.test.d.ts.map +1 -0
  96. package/dist/lib/lswt/fuzzy-search.test.js +207 -0
  97. package/dist/lib/lswt/fuzzy-search.test.js.map +1 -0
  98. package/dist/lib/lswt/index.d.ts +1 -0
  99. package/dist/lib/lswt/index.d.ts.map +1 -1
  100. package/dist/lib/lswt/index.js +2 -0
  101. package/dist/lib/lswt/index.js.map +1 -1
  102. package/dist/lib/lswt/interactive.d.ts +8 -0
  103. package/dist/lib/lswt/interactive.d.ts.map +1 -1
  104. package/dist/lib/lswt/interactive.js +169 -20
  105. package/dist/lib/lswt/interactive.js.map +1 -1
  106. package/dist/lib/newpr/action-deps.test.d.ts +5 -0
  107. package/dist/lib/newpr/action-deps.test.d.ts.map +1 -0
  108. package/dist/lib/newpr/action-deps.test.js +111 -0
  109. package/dist/lib/newpr/action-deps.test.js.map +1 -0
  110. package/dist/lib/newpr/args.d.ts.map +1 -1
  111. package/dist/lib/newpr/args.js +6 -2
  112. package/dist/lib/newpr/args.js.map +1 -1
  113. package/dist/lib/newpr/args.test.js +209 -1
  114. package/dist/lib/newpr/args.test.js.map +1 -1
  115. package/dist/lib/prompts.d.ts +4 -0
  116. package/dist/lib/prompts.d.ts.map +1 -1
  117. package/dist/lib/prompts.js +178 -1
  118. package/dist/lib/prompts.js.map +1 -1
  119. package/dist/lib/prompts.test.js +279 -0
  120. package/dist/lib/prompts.test.js.map +1 -1
  121. package/dist/lib/wtlink/link-configs.test.js +282 -2
  122. package/dist/lib/wtlink/link-configs.test.js.map +1 -1
  123. package/dist/lib/wtlink/main-menu.js +1 -0
  124. package/dist/lib/wtlink/main-menu.js.map +1 -1
  125. package/dist/lib/wtlink/main-menu.test.d.ts +5 -0
  126. package/dist/lib/wtlink/main-menu.test.d.ts.map +1 -0
  127. package/dist/lib/wtlink/main-menu.test.js +124 -0
  128. package/dist/lib/wtlink/main-menu.test.js.map +1 -0
  129. package/dist/lib/wtlink/manage-manifest.d.ts +5 -0
  130. package/dist/lib/wtlink/manage-manifest.d.ts.map +1 -1
  131. package/dist/lib/wtlink/manage-manifest.js +65 -2
  132. package/dist/lib/wtlink/manage-manifest.js.map +1 -1
  133. package/dist/lib/wtlink/manage-manifest.test.js +144 -2
  134. package/dist/lib/wtlink/manage-manifest.test.js.map +1 -1
  135. package/package.json +2 -1
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Fuzzy search functionality for lswt interactive mode
3
+ */
4
+ import type { WorktreeDisplay } from './types.js';
5
+ /**
6
+ * Simple fuzzy match - checks if characters appear in order
7
+ * Returns a score (higher = better match) or -1 if no match
8
+ */
9
+ export declare function fuzzyScore(pattern: string, text: string): number;
10
+ /**
11
+ * Get searchable text from a worktree for fuzzy matching
12
+ */
13
+ export declare function getSearchableText(worktree: WorktreeDisplay): string;
14
+ /**
15
+ * Filter worktrees by fuzzy search pattern
16
+ * Returns worktrees sorted by match score (best first)
17
+ */
18
+ export declare function filterWorktrees(worktrees: WorktreeDisplay[], pattern: string): {
19
+ worktree: WorktreeDisplay;
20
+ score: number;
21
+ originalIndex: number;
22
+ }[];
23
+ /**
24
+ * Highlight matched characters in text
25
+ */
26
+ export declare function highlightMatches(text: string, pattern: string, highlightFn: (s: string) => string): string;
27
+ //# sourceMappingURL=fuzzy-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fuzzy-search.d.ts","sourceRoot":"","sources":["../../../src/lib/lswt/fuzzy-search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAqDhE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CA2BnE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,eAAe,EAAE,EAC5B,OAAO,EAAE,MAAM,GACd;IAAE,QAAQ,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,EAAE,CAqBvE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GACjC,MAAM,CAgCR"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Fuzzy search functionality for lswt interactive mode
3
+ */
4
+ /**
5
+ * Simple fuzzy match - checks if characters appear in order
6
+ * Returns a score (higher = better match) or -1 if no match
7
+ */
8
+ export function fuzzyScore(pattern, text) {
9
+ const patternLower = pattern.toLowerCase();
10
+ const textLower = text.toLowerCase();
11
+ if (patternLower.length === 0) {
12
+ return 0; // Empty pattern matches everything
13
+ }
14
+ if (patternLower.length > textLower.length) {
15
+ return -1; // Pattern longer than text can't match
16
+ }
17
+ // Check for exact substring match first (highest score)
18
+ const exactIndex = textLower.indexOf(patternLower);
19
+ if (exactIndex !== -1) {
20
+ // Bonus for match at start
21
+ const startBonus = exactIndex === 0 ? 100 : 0;
22
+ return 1000 + startBonus - exactIndex;
23
+ }
24
+ // Fuzzy match - characters must appear in order
25
+ let score = 0;
26
+ let patternIndex = 0;
27
+ let consecutiveMatches = 0;
28
+ let lastMatchIndex = -2;
29
+ for (let i = 0; i < textLower.length && patternIndex < patternLower.length; i++) {
30
+ if (textLower[i] === patternLower[patternIndex]) {
31
+ // Score based on position and consecutive matches
32
+ if (lastMatchIndex === i - 1) {
33
+ consecutiveMatches++;
34
+ score += 10 * consecutiveMatches; // Bonus for consecutive matches
35
+ }
36
+ else {
37
+ consecutiveMatches = 0;
38
+ score += 1;
39
+ }
40
+ // Bonus for matching at word boundaries
41
+ if (i === 0 || text[i - 1] === ' ' || text[i - 1] === '-' || text[i - 1] === '_') {
42
+ score += 20;
43
+ }
44
+ lastMatchIndex = i;
45
+ patternIndex++;
46
+ }
47
+ }
48
+ // Return -1 if not all pattern characters matched
49
+ if (patternIndex < patternLower.length) {
50
+ return -1;
51
+ }
52
+ return score;
53
+ }
54
+ /**
55
+ * Get searchable text from a worktree for fuzzy matching
56
+ */
57
+ export function getSearchableText(worktree) {
58
+ const parts = [];
59
+ // Branch name is primary search target
60
+ if (worktree.branch) {
61
+ parts.push(worktree.branch);
62
+ }
63
+ // PR title and number for PR worktrees
64
+ if (worktree.prNumber) {
65
+ parts.push(`PR#${worktree.prNumber}`);
66
+ parts.push(`#${worktree.prNumber}`);
67
+ }
68
+ if (worktree.prTitle) {
69
+ parts.push(worktree.prTitle);
70
+ }
71
+ // PR state
72
+ if (worktree.prState) {
73
+ parts.push(worktree.prState);
74
+ }
75
+ // Type
76
+ parts.push(worktree.type);
77
+ return parts.join(' ');
78
+ }
79
+ /**
80
+ * Filter worktrees by fuzzy search pattern
81
+ * Returns worktrees sorted by match score (best first)
82
+ */
83
+ export function filterWorktrees(worktrees, pattern) {
84
+ if (!pattern || pattern.trim().length === 0) {
85
+ return worktrees.map((wt, i) => ({ worktree: wt, score: 0, originalIndex: i }));
86
+ }
87
+ const results = [];
88
+ for (let i = 0; i < worktrees.length; i++) {
89
+ const wt = worktrees[i];
90
+ const searchText = getSearchableText(wt);
91
+ const score = fuzzyScore(pattern, searchText);
92
+ if (score >= 0) {
93
+ results.push({ worktree: wt, score, originalIndex: i });
94
+ }
95
+ }
96
+ // Sort by score (highest first)
97
+ results.sort((a, b) => b.score - a.score);
98
+ return results;
99
+ }
100
+ /**
101
+ * Highlight matched characters in text
102
+ */
103
+ export function highlightMatches(text, pattern, highlightFn) {
104
+ if (!pattern || pattern.length === 0) {
105
+ return text;
106
+ }
107
+ const patternLower = pattern.toLowerCase();
108
+ const textLower = text.toLowerCase();
109
+ // Try exact substring first
110
+ const exactIndex = textLower.indexOf(patternLower);
111
+ if (exactIndex !== -1) {
112
+ return (text.substring(0, exactIndex) +
113
+ highlightFn(text.substring(exactIndex, exactIndex + pattern.length)) +
114
+ text.substring(exactIndex + pattern.length));
115
+ }
116
+ // Fuzzy highlight - highlight matched characters
117
+ const result = [];
118
+ let patternIndex = 0;
119
+ for (let i = 0; i < text.length; i++) {
120
+ if (patternIndex < patternLower.length && textLower[i] === patternLower[patternIndex]) {
121
+ result.push(highlightFn(text[i]));
122
+ patternIndex++;
123
+ }
124
+ else {
125
+ result.push(text[i]);
126
+ }
127
+ }
128
+ return result.join('');
129
+ }
130
+ //# sourceMappingURL=fuzzy-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fuzzy-search.js","sourceRoot":"","sources":["../../../src/lib/lswt/fuzzy-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for fuzzy search functionality
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=fuzzy-search.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fuzzy-search.test.d.ts","sourceRoot":"","sources":["../../../src/lib/lswt/fuzzy-search.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Tests for fuzzy search functionality
3
+ */
4
+ import { describe, it, expect } from 'vitest';
5
+ import { fuzzyScore, getSearchableText, filterWorktrees, highlightMatches, } from './fuzzy-search.js';
6
+ describe('fuzzyScore', () => {
7
+ it('returns 0 for empty pattern', () => {
8
+ expect(fuzzyScore('', 'hello')).toBe(0);
9
+ });
10
+ it('returns -1 when pattern is longer than text', () => {
11
+ expect(fuzzyScore('hello world', 'hi')).toBe(-1);
12
+ });
13
+ it('returns high score for exact substring match', () => {
14
+ expect(fuzzyScore('dark', 'add-dark-mode')).toBeGreaterThan(100);
15
+ });
16
+ it('returns higher score for match at start', () => {
17
+ const startScore = fuzzyScore('add', 'add-feature');
18
+ const middleScore = fuzzyScore('feat', 'add-feature');
19
+ expect(startScore).toBeGreaterThan(middleScore);
20
+ });
21
+ it('returns positive score for fuzzy match', () => {
22
+ const score = fuzzyScore('adm', 'add-dark-mode');
23
+ expect(score).toBeGreaterThan(0);
24
+ });
25
+ it('returns -1 when characters do not appear in order', () => {
26
+ expect(fuzzyScore('xyz', 'hello')).toBe(-1);
27
+ });
28
+ it('gives bonus for consecutive matches', () => {
29
+ const consecutiveScore = fuzzyScore('dark', 'dark-mode');
30
+ const spreadScore = fuzzyScore('drmd', 'dark-mode');
31
+ expect(consecutiveScore).toBeGreaterThan(spreadScore);
32
+ });
33
+ it('gives bonus for word boundary matches', () => {
34
+ // 'dm' hits word boundaries: d at start, m after hyphen
35
+ // 'am' has mid-word match: a is mid-word (position 1)
36
+ const boundaryScore = fuzzyScore('dm', 'dark-mode');
37
+ const midScore = fuzzyScore('am', 'dark-mode');
38
+ expect(boundaryScore).toBeGreaterThan(midScore);
39
+ });
40
+ });
41
+ describe('getSearchableText', () => {
42
+ it('includes branch name', () => {
43
+ const wt = {
44
+ path: '/path/to/repo',
45
+ name: 'repo',
46
+ branch: 'feat/dark-mode',
47
+ commit: 'abc123',
48
+ type: 'branch',
49
+ prNumber: null,
50
+ prState: null,
51
+ isDraft: null,
52
+ hasChanges: false,
53
+ };
54
+ expect(getSearchableText(wt)).toContain('feat/dark-mode');
55
+ });
56
+ it('includes PR number with # prefix', () => {
57
+ const wt = {
58
+ path: '/path/to/repo.pr42',
59
+ name: 'repo.pr42',
60
+ branch: 'feat/dark-mode',
61
+ commit: 'abc123',
62
+ type: 'pr',
63
+ prNumber: 42,
64
+ prState: 'OPEN',
65
+ isDraft: false,
66
+ hasChanges: false,
67
+ };
68
+ const text = getSearchableText(wt);
69
+ expect(text).toContain('PR#42');
70
+ expect(text).toContain('#42');
71
+ });
72
+ it('includes PR title', () => {
73
+ const wt = {
74
+ path: '/path/to/repo.pr42',
75
+ name: 'repo.pr42',
76
+ branch: 'feat/dark-mode',
77
+ commit: 'abc123',
78
+ type: 'pr',
79
+ prNumber: 42,
80
+ prTitle: 'Add dark mode support',
81
+ prState: 'OPEN',
82
+ isDraft: false,
83
+ hasChanges: false,
84
+ };
85
+ expect(getSearchableText(wt)).toContain('Add dark mode support');
86
+ });
87
+ it('includes PR state', () => {
88
+ const wt = {
89
+ path: '/path/to/repo.pr42',
90
+ name: 'repo.pr42',
91
+ branch: 'feat/dark-mode',
92
+ commit: 'abc123',
93
+ type: 'pr',
94
+ prNumber: 42,
95
+ prState: 'MERGED',
96
+ isDraft: false,
97
+ hasChanges: false,
98
+ };
99
+ expect(getSearchableText(wt)).toContain('MERGED');
100
+ });
101
+ it('includes type', () => {
102
+ const wt = {
103
+ path: '/path/to/repo',
104
+ name: 'repo',
105
+ branch: 'main',
106
+ commit: 'abc123',
107
+ type: 'main',
108
+ prNumber: null,
109
+ prState: null,
110
+ isDraft: null,
111
+ hasChanges: false,
112
+ };
113
+ expect(getSearchableText(wt)).toContain('main');
114
+ });
115
+ });
116
+ describe('filterWorktrees', () => {
117
+ const worktrees = [
118
+ {
119
+ path: '/path/to/repo',
120
+ name: 'repo',
121
+ branch: 'main',
122
+ commit: 'abc123',
123
+ type: 'main',
124
+ prNumber: null,
125
+ prState: null,
126
+ isDraft: null,
127
+ hasChanges: false,
128
+ },
129
+ {
130
+ path: '/path/to/repo.pr42',
131
+ name: 'repo.pr42',
132
+ branch: 'feat/dark-mode',
133
+ commit: 'def456',
134
+ type: 'pr',
135
+ prNumber: 42,
136
+ prTitle: 'Add dark mode',
137
+ prState: 'OPEN',
138
+ isDraft: false,
139
+ hasChanges: true,
140
+ },
141
+ {
142
+ path: '/path/to/repo.pr43',
143
+ name: 'repo.pr43',
144
+ branch: 'fix/light-theme',
145
+ commit: 'ghi789',
146
+ type: 'pr',
147
+ prNumber: 43,
148
+ prTitle: 'Fix light theme bug',
149
+ prState: 'MERGED',
150
+ isDraft: false,
151
+ hasChanges: false,
152
+ },
153
+ ];
154
+ it('returns all worktrees for empty pattern', () => {
155
+ const results = filterWorktrees(worktrees, '');
156
+ expect(results).toHaveLength(3);
157
+ });
158
+ it('filters by branch name', () => {
159
+ const results = filterWorktrees(worktrees, 'dark');
160
+ expect(results).toHaveLength(1);
161
+ expect(results[0].worktree.branch).toBe('feat/dark-mode');
162
+ });
163
+ it('filters by PR number', () => {
164
+ const results = filterWorktrees(worktrees, '42');
165
+ expect(results).toHaveLength(1);
166
+ expect(results[0].worktree.prNumber).toBe(42);
167
+ });
168
+ it('filters by PR title', () => {
169
+ const results = filterWorktrees(worktrees, 'theme');
170
+ expect(results).toHaveLength(1);
171
+ expect(results[0].worktree.prNumber).toBe(43);
172
+ });
173
+ it('filters by state', () => {
174
+ const results = filterWorktrees(worktrees, 'MERGED');
175
+ expect(results).toHaveLength(1);
176
+ expect(results[0].worktree.prState).toBe('MERGED');
177
+ });
178
+ it('returns results sorted by score (best first)', () => {
179
+ const results = filterWorktrees(worktrees, 'mode');
180
+ expect(results.length).toBeGreaterThan(0);
181
+ // Dark mode should come first as it has "mode" in the title
182
+ expect(results[0].worktree.prTitle).toContain('dark mode');
183
+ });
184
+ it('preserves original indices', () => {
185
+ const results = filterWorktrees(worktrees, 'dark');
186
+ expect(results[0].originalIndex).toBe(1); // Second worktree in original array
187
+ });
188
+ });
189
+ describe('highlightMatches', () => {
190
+ const highlight = (s) => `[${s}]`;
191
+ it('returns unchanged text for empty pattern', () => {
192
+ expect(highlightMatches('hello', '', highlight)).toBe('hello');
193
+ });
194
+ it('highlights exact substring match', () => {
195
+ expect(highlightMatches('dark-mode', 'dark', highlight)).toBe('[dark]-mode');
196
+ });
197
+ it('highlights fuzzy matches', () => {
198
+ expect(highlightMatches('dark-mode', 'dm', highlight)).toBe('[d]ark-[m]ode');
199
+ });
200
+ it('handles case-insensitive matching', () => {
201
+ expect(highlightMatches('DarkMode', 'dark', highlight)).toBe('[Dark]Mode');
202
+ });
203
+ it('handles no match gracefully', () => {
204
+ expect(highlightMatches('hello', 'xyz', highlight)).toBe('hello');
205
+ });
206
+ });
207
+ //# sourceMappingURL=fuzzy-search.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fuzzy-search.test.js","sourceRoot":"","sources":["../../../src/lib/lswt/fuzzy-search.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAG3B,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QACtD,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,gBAAgB,GAAG,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACzD,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACpD,MAAM,CAAC,gBAAgB,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,wDAAwD;QACxD,sDAAsD;QACtD,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC/C,MAAM,CAAC,aAAa,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,EAAE,GAAoB;YAC1B,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,gBAAgB;YACxB,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,KAAK;SAClB,CAAC;QACF,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,EAAE,GAAoB;YAC1B,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,gBAAgB;YACxB,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,KAAK;SAClB,CAAC;QACF,MAAM,IAAI,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAC3B,MAAM,EAAE,GAAoB;YAC1B,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,gBAAgB;YACxB,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,uBAAuB;YAChC,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,KAAK;SAClB,CAAC;QACF,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAC3B,MAAM,EAAE,GAAoB;YAC1B,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,gBAAgB;YACxB,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,QAAQ;YACjB,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,KAAK;SAClB,CAAC;QACF,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;QACvB,MAAM,EAAE,GAAoB;YAC1B,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,KAAK;SAClB,CAAC;QACF,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,MAAM,SAAS,GAAsB;QACnC;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,KAAK;SAClB;QACD;YACE,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,gBAAgB;YACxB,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,IAAI;SACjB;QACD;YACE,IAAI,EAAE,oBAAoB;YAC1B,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,iBAAiB;YACzB,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,qBAAqB;YAC9B,OAAO,EAAE,QAAQ;YACjB,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,KAAK;SAClB;KACF,CAAC;IAEF,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/C,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC1B,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC1C,4DAA4D;QAC5D,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,oCAAoC;IAChF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,MAAM,SAAS,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;IAE1C,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -12,4 +12,5 @@ export type { ExecutorDeps } from './action-executors.js';
12
12
  export { executeAction, createDefaultExecutorDeps } from './action-executors.js';
13
13
  export type { InteractiveDeps } from './interactive.js';
14
14
  export { runInteractiveMode, createDefaultInteractiveDeps } from './interactive.js';
15
+ export { fuzzyScore, getSearchableText, filterWorktrees, highlightMatches, } from './fuzzy-search.js';
15
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/lswt/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,WAAW,EACX,eAAe,EACf,WAAW,EACX,SAAS,EACT,cAAc,EACd,cAAc,EACd,YAAY,EACZ,eAAe,EACf,UAAU,GACX,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGnD,OAAO,EACL,eAAe,EACf,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG3E,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,EACR,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAGjF,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/lswt/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,WAAW,EACX,eAAe,EACf,WAAW,EACX,SAAS,EACT,cAAc,EACd,cAAc,EACd,YAAY,EACZ,eAAe,EACf,UAAU,GACX,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGnD,OAAO,EACL,eAAe,EACf,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG3E,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,EACR,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAGjF,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAGpF,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
@@ -12,4 +12,6 @@ export { detectEnvironment, isCommandAvailable, getGitVersion, parseGitVersion,
12
12
  export { buildActionMenu, formatWorktreeChoice, formatShortcutLegend, getActionShortcut, ACTION_SHORTCUTS, } from './actions.js';
13
13
  export { executeAction, createDefaultExecutorDeps } from './action-executors.js';
14
14
  export { runInteractiveMode, createDefaultInteractiveDeps } from './interactive.js';
15
+ // Fuzzy search
16
+ export { fuzzyScore, getSearchableText, filterWorktrees, highlightMatches, } from './fuzzy-search.js';
15
17
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/lswt/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,mBAAmB;AACnB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEnD,aAAa;AACb,OAAO,EACL,eAAe,EACf,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE3E,wBAAwB;AACxB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,EACR,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAE1B,UAAU;AACV,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAItB,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAIjF,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/lswt/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,mBAAmB;AACnB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEnD,aAAa;AACb,OAAO,EACL,eAAe,EACf,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE3E,wBAAwB;AACxB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,EACR,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAE1B,UAAU;AACV,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAItB,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAIjF,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAEpF,eAAe;AACf,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
@@ -39,6 +39,14 @@ export declare function createDefaultInteractiveDeps(): InteractiveDeps;
39
39
  * Run the interactive mode loop
40
40
  */
41
41
  export declare function runInteractiveMode(initialWorktrees: WorktreeDisplay[], options: ListOptions, interactiveDeps?: InteractiveDeps): Promise<void>;
42
+ /**
43
+ * Format worktree choice with search highlighting
44
+ * @param worktree - The worktree to format
45
+ * @param badgeWidth - The width to pad the badge to
46
+ * @param searchPattern - Optional search pattern to highlight matches
47
+ * Exported for testing
48
+ */
49
+ export declare function formatWorktreeChoiceWithSearch(worktree: WorktreeDisplay, badgeWidth: number, searchPattern?: string): string;
42
50
  /**
43
51
  * Format worktree choice with colors for display
44
52
  * @param worktree - The worktree to format
@@ -1 +1 @@
1
- {"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../../src/lib/lswt/interactive.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAehG;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAqB9D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,MAAM,CAIzE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,eAAe,GACxB,cAAc,GAAG,IAAI,CAoCvB;AAED,yDAAyD;AACzD,UAAU,eAAe;IACvB,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;CAC/B;AAED,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IACjG,YAAY,EAAE,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3F,oBAAoB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAM9D;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,gBAAgB,EAAE,eAAe,EAAE,EACnC,OAAO,EAAE,WAAW,EACpB,eAAe,CAAC,EAAE,eAAe,GAChC,OAAO,CAAC,IAAI,CAAC,CAmFf;AAkND;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,eAAe,EACzB,UAAU,EAAE,MAAM,GACjB,MAAM,CAsBR;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAwB/F;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CA8BxE"}
1
+ {"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../../src/lib/lswt/interactive.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAehG;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAqB9D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,MAAM,CAIzE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,eAAe,GACxB,cAAc,GAAG,IAAI,CAoCvB;AAED,yDAAyD;AACzD,UAAU,eAAe;IACvB,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;CAC/B;AAED,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IACjG,YAAY,EAAE,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3F,oBAAoB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAM9D;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,gBAAgB,EAAE,eAAe,EAAE,EACnC,OAAO,EAAE,WAAW,EACpB,eAAe,CAAC,EAAE,eAAe,GAChC,OAAO,CAAC,IAAI,CAAC,CAmFf;AA8DD;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,eAAe,EACzB,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,CAwBR;AA+RD;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,eAAe,EACzB,UAAU,EAAE,MAAM,GACjB,MAAM,CAsBR;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAwB/F;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CA8BxE"}