@agi-fans/dsh-tui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -0
  3. package/lib/autocomplete.d.ts +80 -0
  4. package/lib/autocomplete.js +320 -0
  5. package/lib/autocomplete.js.map +1 -0
  6. package/lib/box.d.ts +79 -0
  7. package/lib/box.js +276 -0
  8. package/lib/box.js.map +1 -0
  9. package/lib/clipboard.d.ts +19 -0
  10. package/lib/clipboard.js +77 -0
  11. package/lib/clipboard.js.map +1 -0
  12. package/lib/command-integrations.d.ts +10 -0
  13. package/lib/command-integrations.js +49 -0
  14. package/lib/command-integrations.js.map +1 -0
  15. package/lib/command-mode.d.ts +5 -0
  16. package/lib/command-mode.js +73 -0
  17. package/lib/command-mode.js.map +1 -0
  18. package/lib/command-model.d.ts +5 -0
  19. package/lib/command-model.js +87 -0
  20. package/lib/command-model.js.map +1 -0
  21. package/lib/command-output.d.ts +6 -0
  22. package/lib/command-output.js +33 -0
  23. package/lib/command-output.js.map +1 -0
  24. package/lib/command-queue.d.ts +5 -0
  25. package/lib/command-queue.js +62 -0
  26. package/lib/command-queue.js.map +1 -0
  27. package/lib/command-registration.d.ts +5 -0
  28. package/lib/command-registration.js +20 -0
  29. package/lib/command-registration.js.map +1 -0
  30. package/lib/command-session.d.ts +5 -0
  31. package/lib/command-session.js +153 -0
  32. package/lib/command-session.js.map +1 -0
  33. package/lib/command-transcript.d.ts +5 -0
  34. package/lib/command-transcript.js +85 -0
  35. package/lib/command-transcript.js.map +1 -0
  36. package/lib/copy-selector.d.ts +52 -0
  37. package/lib/copy-selector.js +136 -0
  38. package/lib/copy-selector.js.map +1 -0
  39. package/lib/copy-targets.d.ts +34 -0
  40. package/lib/copy-targets.js +170 -0
  41. package/lib/copy-targets.js.map +1 -0
  42. package/lib/definition.d.ts +171 -0
  43. package/lib/definition.js +14 -0
  44. package/lib/definition.js.map +1 -0
  45. package/lib/editor.d.ts +66 -0
  46. package/lib/editor.js +365 -0
  47. package/lib/editor.js.map +1 -0
  48. package/lib/event-views.d.ts +188 -0
  49. package/lib/event-views.js +678 -0
  50. package/lib/event-views.js.map +1 -0
  51. package/lib/external-editor.d.ts +2 -0
  52. package/lib/external-editor.js +31 -0
  53. package/lib/external-editor.js.map +1 -0
  54. package/lib/history-search.d.ts +61 -0
  55. package/lib/history-search.js +239 -0
  56. package/lib/history-search.js.map +1 -0
  57. package/lib/history-store.d.ts +8 -0
  58. package/lib/history-store.js +36 -0
  59. package/lib/history-store.js.map +1 -0
  60. package/lib/hotkeys.d.ts +14 -0
  61. package/lib/hotkeys.js +115 -0
  62. package/lib/hotkeys.js.map +1 -0
  63. package/lib/human-interaction.d.ts +5 -0
  64. package/lib/human-interaction.js +8 -0
  65. package/lib/human-interaction.js.map +1 -0
  66. package/lib/image-paste.d.ts +21 -0
  67. package/lib/image-paste.js +277 -0
  68. package/lib/image-paste.js.map +1 -0
  69. package/lib/index.d.ts +10 -0
  70. package/lib/index.js +11 -0
  71. package/lib/index.js.map +1 -0
  72. package/lib/interaction-adapter.d.ts +18 -0
  73. package/lib/interaction-adapter.js +93 -0
  74. package/lib/interaction-adapter.js.map +1 -0
  75. package/lib/keybindings-config.d.ts +5 -0
  76. package/lib/keybindings-config.js +28 -0
  77. package/lib/keybindings-config.js.map +1 -0
  78. package/lib/keys.d.ts +59 -0
  79. package/lib/keys.js +263 -0
  80. package/lib/keys.js.map +1 -0
  81. package/lib/markdown.d.ts +13 -0
  82. package/lib/markdown.js +453 -0
  83. package/lib/markdown.js.map +1 -0
  84. package/lib/path-complete.d.ts +85 -0
  85. package/lib/path-complete.js +231 -0
  86. package/lib/path-complete.js.map +1 -0
  87. package/lib/path-mentions.d.ts +4 -0
  88. package/lib/path-mentions.js +50 -0
  89. package/lib/path-mentions.js.map +1 -0
  90. package/lib/project-context.d.ts +13 -0
  91. package/lib/project-context.js +52 -0
  92. package/lib/project-context.js.map +1 -0
  93. package/lib/project-file-search.d.ts +25 -0
  94. package/lib/project-file-search.js +207 -0
  95. package/lib/project-file-search.js.map +1 -0
  96. package/lib/prompt-selector.d.ts +56 -0
  97. package/lib/prompt-selector.js +297 -0
  98. package/lib/prompt-selector.js.map +1 -0
  99. package/lib/provider-local.d.ts +115 -0
  100. package/lib/provider-local.js +1760 -0
  101. package/lib/provider-local.js.map +1 -0
  102. package/lib/pwd.d.ts +13 -0
  103. package/lib/pwd.js +14 -0
  104. package/lib/pwd.js.map +1 -0
  105. package/lib/relative-time.d.ts +2 -0
  106. package/lib/relative-time.js +11 -0
  107. package/lib/relative-time.js.map +1 -0
  108. package/lib/renderer.d.ts +112 -0
  109. package/lib/renderer.js +181 -0
  110. package/lib/renderer.js.map +1 -0
  111. package/lib/runner.d.ts +9 -0
  112. package/lib/runner.js +94 -0
  113. package/lib/runner.js.map +1 -0
  114. package/lib/session-controller.d.ts +92 -0
  115. package/lib/session-controller.js +571 -0
  116. package/lib/session-controller.js.map +1 -0
  117. package/lib/session-runtime.d.ts +16 -0
  118. package/lib/session-runtime.js +17 -0
  119. package/lib/session-runtime.js.map +1 -0
  120. package/lib/settings-list.d.ts +67 -0
  121. package/lib/settings-list.js +380 -0
  122. package/lib/settings-list.js.map +1 -0
  123. package/lib/status-config.d.ts +32 -0
  124. package/lib/status-config.js +52 -0
  125. package/lib/status-config.js.map +1 -0
  126. package/lib/status-line.d.ts +41 -0
  127. package/lib/status-line.js +351 -0
  128. package/lib/status-line.js.map +1 -0
  129. package/lib/style.d.ts +22 -0
  130. package/lib/style.js +23 -0
  131. package/lib/style.js.map +1 -0
  132. package/lib/theme.d.ts +83 -0
  133. package/lib/theme.js +317 -0
  134. package/lib/theme.js.map +1 -0
  135. package/lib/tool-presentation.d.ts +20 -0
  136. package/lib/tool-presentation.js +79 -0
  137. package/lib/tool-presentation.js.map +1 -0
  138. package/lib/tool-renderers.d.ts +21 -0
  139. package/lib/tool-renderers.js +133 -0
  140. package/lib/tool-renderers.js.map +1 -0
  141. package/lib/tools-list.d.ts +14 -0
  142. package/lib/tools-list.js +61 -0
  143. package/lib/tools-list.js.map +1 -0
  144. package/lib/transcript-export.d.ts +4 -0
  145. package/lib/transcript-export.js +66 -0
  146. package/lib/transcript-export.js.map +1 -0
  147. package/lib/tui-settings.d.ts +20 -0
  148. package/lib/tui-settings.js +23 -0
  149. package/lib/tui-settings.js.map +1 -0
  150. package/lib/welcome-tips.d.ts +10 -0
  151. package/lib/welcome-tips.js +36 -0
  152. package/lib/welcome-tips.js.map +1 -0
  153. package/lib/width.d.ts +54 -0
  154. package/lib/width.js +323 -0
  155. package/lib/width.js.map +1 -0
  156. package/package.json +119 -0
@@ -0,0 +1,231 @@
1
+ /**
2
+ * `@` and explicit path autocomplete: immediate directory browsing plus
3
+ * asynchronous project-wide fuzzy search. Tab can force a bare-word token.
4
+ * Filesystem access stays behind injected directory and project-search seams.
5
+ * @module @agi-fans/dsh-tui
6
+ */
7
+ import { readdirSync, statSync } from 'node:fs';
8
+ import { homedir } from 'node:os';
9
+ import path from 'node:path';
10
+ import { ProjectFileSearch, } from "./project-file-search.js";
11
+ import { BUILTIN_SLASH_COMMANDS, findLeadingSlashCommandStart, resolveSlashCommand, } from "./autocomplete.js";
12
+ const PATH_DELIMITERS = new Set([' ', '\t', '"', "'", '=']);
13
+ /** Last path-token delimiter before the cursor, or -1. */
14
+ export function findLastPathDelimiter(text) {
15
+ for (let i = text.length - 1; i >= 0; i -= 1) {
16
+ if (PATH_DELIMITERS.has(text[i] ?? ''))
17
+ return i;
18
+ }
19
+ return -1;
20
+ }
21
+ function isExplicitPath(token) {
22
+ return (token.startsWith('./')
23
+ || token.startsWith('../')
24
+ || token === '~'
25
+ || token.startsWith('~/')
26
+ || token.startsWith('/')
27
+ || /^[A-Za-z]:[\\/]/.test(token));
28
+ }
29
+ /** Path token immediately before `cursor`, or null. */
30
+ export function findPathToken(text, cursor, force = false) {
31
+ const lineStart = text.lastIndexOf('\n', cursor - 1) + 1;
32
+ const before = text.slice(lineStart, cursor);
33
+ const delim = findLastPathDelimiter(before);
34
+ const start = delim === -1 ? 0 : delim + 1;
35
+ const token = before.slice(start);
36
+ if (token.startsWith('@'))
37
+ return { start: lineStart + start, prefix: token, kind: 'at' };
38
+ if (isExplicitPath(token))
39
+ return { start: lineStart + start, prefix: token, kind: 'path' };
40
+ if (force)
41
+ return { start: lineStart + start, prefix: token, kind: 'path' };
42
+ return null;
43
+ }
44
+ /** Strip a leading `@` from a live prefix. */
45
+ export function parsePathPrefix(prefix) {
46
+ if (prefix.startsWith('@'))
47
+ return { raw: prefix.slice(1), at: true };
48
+ return { raw: prefix, at: false };
49
+ }
50
+ /** Directory to list and the display prefix for each match. */
51
+ export function resolveSearch(raw, cwd, home) {
52
+ const posix = raw.replaceAll('\\', '/');
53
+ const listing = posix === '' || posix.endsWith('/') || posix === '~';
54
+ if (listing) {
55
+ return {
56
+ searchDir: resolveDir(posix === '~' ? '~/' : posix, cwd, home),
57
+ searchPrefix: '',
58
+ displayBase: posix === '~' ? '~/' : posix,
59
+ };
60
+ }
61
+ const slash = posix.lastIndexOf('/');
62
+ const dirRaw = slash === -1 ? '' : posix.slice(0, slash + 1);
63
+ return {
64
+ searchDir: resolveDir(dirRaw, cwd, home),
65
+ searchPrefix: slash === -1 ? posix : posix.slice(slash + 1),
66
+ displayBase: dirRaw,
67
+ };
68
+ }
69
+ function resolveDir(dirRaw, cwd, home) {
70
+ if (dirRaw === '' || dirRaw === './')
71
+ return cwd;
72
+ if (dirRaw === '~' || dirRaw === '~/')
73
+ return home;
74
+ if (dirRaw.startsWith('~/'))
75
+ return path.resolve(home, dirRaw.slice(2));
76
+ if (dirRaw.startsWith('/') || /^[A-Za-z]:[\\/]/.test(dirRaw))
77
+ return path.resolve(dirRaw);
78
+ return path.resolve(cwd, dirRaw);
79
+ }
80
+ /** Quote a path that contains spaces; keep directory trailing slashes open. */
81
+ export function formatPathValue(pathValue, at) {
82
+ const prefix = at ? '@' : '';
83
+ if (!pathValue.includes(' '))
84
+ return prefix + pathValue;
85
+ return pathValue.endsWith('/')
86
+ ? prefix + '"' + pathValue
87
+ : prefix + '"' + pathValue + '"';
88
+ }
89
+ /** Ranked path rows from a directory listing. */
90
+ export function buildPathCompletions(entries, displayBase, searchPrefix, at) {
91
+ const lower = searchPrefix.toLowerCase();
92
+ const showHidden = lower.startsWith('.');
93
+ const items = [];
94
+ for (const entry of entries) {
95
+ if (entry.name === '.git')
96
+ continue;
97
+ if (entry.name.startsWith('.') && !showHidden)
98
+ continue;
99
+ if (lower !== '' && !entry.name.toLowerCase().startsWith(lower))
100
+ continue;
101
+ const rel = displayBase + entry.name;
102
+ const pathValue = entry.directory ? rel + '/' : rel;
103
+ items.push({
104
+ value: formatPathValue(pathValue, at),
105
+ label: entry.name + (entry.directory ? '/' : ''),
106
+ kind: 'path',
107
+ });
108
+ }
109
+ items.sort((a, b) => {
110
+ const aDir = a.label.endsWith('/');
111
+ const bDir = b.label.endsWith('/');
112
+ if (aDir !== bDir)
113
+ return aDir ? -1 : 1;
114
+ return a.label.localeCompare(b.label);
115
+ });
116
+ return items;
117
+ }
118
+ /** List completions for a live `@` / path prefix. */
119
+ export function listPathCompletions(prefix, opts) {
120
+ const parsed = parsePathPrefix(prefix);
121
+ const search = resolveSearch(parsed.raw, parsed.at ? (opts.projectRoot ?? opts.cwd) : opts.cwd, opts.home);
122
+ const entries = opts.listDir(search.searchDir);
123
+ if (entries === undefined)
124
+ return [];
125
+ return buildPathCompletions(entries, search.displayBase, search.searchPrefix, parsed.at);
126
+ }
127
+ function slashCommandOwnsInput(text, cursor, commands) {
128
+ const before = text.slice(0, cursor);
129
+ const start = findLeadingSlashCommandStart(before);
130
+ if (start === null)
131
+ return false;
132
+ const token = before.slice(start);
133
+ if (token === '/')
134
+ return true;
135
+ if (token.includes(' '))
136
+ return true;
137
+ if (token.slice(1).includes('/'))
138
+ return false;
139
+ return resolveSlashCommand(token.slice(1), commands) !== undefined;
140
+ }
141
+ /** Suggestions for a path token, or null when the cursor is not in one. */
142
+ export function pathSuggestions(text, cursor, opts, commands = BUILTIN_SLASH_COMMANDS) {
143
+ if (slashCommandOwnsInput(text, cursor, commands))
144
+ return null;
145
+ const token = findPathToken(text, cursor, opts.force === true);
146
+ if (token === null)
147
+ return null;
148
+ const items = listPathCompletions(token.prefix, opts);
149
+ if (items.length === 0)
150
+ return null;
151
+ return { items, prefix: text.slice(token.start, cursor) };
152
+ }
153
+ /** Async `@query` search with prefix-listing fallback. */
154
+ export async function searchPathSuggestions(text, cursor, opts, commands = BUILTIN_SLASH_COMMANDS) {
155
+ if (slashCommandOwnsInput(text, cursor, commands))
156
+ return null;
157
+ const token = findPathToken(text, cursor);
158
+ if (token === null || token.kind !== 'at')
159
+ return pathSuggestions(text, cursor, opts, commands);
160
+ const parsed = parsePathPrefix(token.prefix);
161
+ if (parsed.raw === '' || parsed.raw.replaceAll('\\', '/').endsWith('/')) {
162
+ return pathSuggestions(text, cursor, opts, commands);
163
+ }
164
+ const normalized = parsed.raw.replaceAll('\\', '/');
165
+ const slash = normalized.lastIndexOf('/');
166
+ const displayBase = slash < 0 ? '' : normalized.slice(0, slash + 1);
167
+ const query = slash < 0 ? normalized : normalized.slice(slash + 1);
168
+ const searchDir = resolveDir(displayBase, opts.projectRoot, opts.home);
169
+ const relative = path.relative(opts.projectRoot, searchDir);
170
+ const outside = path.isAbsolute(relative) || relative === '..' || relative.startsWith('..' + path.sep);
171
+ if (outside)
172
+ return pathSuggestions(text, cursor, opts, commands);
173
+ const matches = await opts.searchFiles(searchDir, query, {
174
+ ...(opts.signal === undefined ? {} : { signal: opts.signal }),
175
+ maxResults: 100,
176
+ });
177
+ if (matches.length === 0)
178
+ return pathSuggestions(text, cursor, opts, commands);
179
+ const items = matches.flatMap((entry) => {
180
+ const relativePath = entry.path.replaceAll('\\', '/').replace(/^\.\//u, '').replace(/\/$/u, '');
181
+ if (relativePath === '' || /(^|\/)\.git(\/|$)/u.test(relativePath))
182
+ return [];
183
+ const displayPath = displayBase + relativePath;
184
+ const pathValue = entry.directory ? displayPath + '/' : displayPath;
185
+ const basename = path.posix.basename(relativePath);
186
+ return [{
187
+ value: formatPathValue(pathValue, true),
188
+ label: basename + (entry.directory ? '/' : ''),
189
+ ...(displayPath === basename ? {} : { description: displayPath }),
190
+ kind: 'path',
191
+ }];
192
+ });
193
+ if (items.length === 0)
194
+ return pathSuggestions(text, cursor, opts, commands);
195
+ return { items, prefix: text.slice(token.start, cursor) };
196
+ }
197
+ /** Replace the live path token with the selected value. */
198
+ export function applyPathCompletion(text, cursor, item) {
199
+ const token = findPathToken(text, cursor, true);
200
+ if (token === null)
201
+ return { text, cursor };
202
+ const after = text.slice(cursor);
203
+ const insert = item.value.endsWith('/') ? item.value : item.value + ' ';
204
+ return { text: text.slice(0, token.start) + insert + after, cursor: token.start + insert.length };
205
+ }
206
+ /** Default reader: `readdir` plus symlink-to-directory. */
207
+ export function readDirEntries(dir) {
208
+ try {
209
+ return readdirSync(dir, { withFileTypes: true }).map((entry) => {
210
+ let directory = entry.isDirectory();
211
+ if (!directory && entry.isSymbolicLink()) {
212
+ try {
213
+ directory = statSync(path.join(dir, entry.name)).isDirectory();
214
+ }
215
+ catch {
216
+ directory = false;
217
+ }
218
+ }
219
+ return { name: entry.name, directory };
220
+ });
221
+ }
222
+ catch {
223
+ return undefined;
224
+ }
225
+ }
226
+ /** Filesystem options the provider uses for path completion. */
227
+ export function defaultPathSource() {
228
+ const search = new ProjectFileSearch();
229
+ return { cwd: process.cwd(), home: homedir(), listDir: readDirEntries, searchFiles: search.search };
230
+ }
231
+ //# sourceMappingURL=path-complete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-complete.js","sourceRoot":"","sources":["../src/path-complete.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /** Theme-aware rendering for `@path` mentions in submitted user messages. */
2
+ import type { Theme } from './theme.ts';
3
+ /** Wrap plain user text, then paint every visible slice of an `@path` mention. */
4
+ export declare function renderPathMentionRows(text: string, width: number, theme: Theme): string[];
@@ -0,0 +1,50 @@
1
+ /** Theme-aware rendering for `@path` mentions in submitted user messages. */
2
+ import { wrapIndexed } from "./width.js";
3
+ const PATH_MENTION = /@(?:"[^"\n]+"|'[^'\n]+'|[^\s@]+)/gu;
4
+ const MENTION_BOUNDARY = /[\s([{<"'`,。;:!?(【《]/u;
5
+ const TRAILING_PUNCTUATION = /[)\]}>.,;:!?"'`,。;:!?)】》]/u;
6
+ function mentionRanges(text) {
7
+ const ranges = [];
8
+ for (const match of text.matchAll(PATH_MENTION)) {
9
+ const start = match.index;
10
+ if (start === undefined || (start > 0 && !MENTION_BOUNDARY.test(text[start - 1] ?? '')))
11
+ continue;
12
+ const raw = match[0];
13
+ const quoted = raw.startsWith('@"') || raw.startsWith("@'");
14
+ let end = start + raw.length;
15
+ if (!quoted) {
16
+ while (end > start + 1 && TRAILING_PUNCTUATION.test(text[end - 1] ?? ''))
17
+ end -= 1;
18
+ }
19
+ if (end > start + 1)
20
+ ranges.push({ start, end });
21
+ }
22
+ return ranges;
23
+ }
24
+ function paintMentionSlice(text, sourceStart, ranges, theme) {
25
+ if (!theme.colors || ranges.length === 0)
26
+ return text;
27
+ const sourceEnd = sourceStart + text.length;
28
+ const open = theme.getFgAnsi('accent') + '\x1b[1m';
29
+ const close = '\x1b[22m' + (theme.getFgAnsi('userMessageText') || '\x1b[39m');
30
+ let output = '';
31
+ let cursor = 0;
32
+ for (const range of ranges) {
33
+ const start = Math.max(range.start, sourceStart);
34
+ const end = Math.min(range.end, sourceEnd);
35
+ if (start >= end)
36
+ continue;
37
+ const localStart = start - sourceStart;
38
+ const localEnd = end - sourceStart;
39
+ output += text.slice(cursor, localStart);
40
+ output += open + text.slice(localStart, localEnd) + close;
41
+ cursor = localEnd;
42
+ }
43
+ return output + text.slice(cursor);
44
+ }
45
+ /** Wrap plain user text, then paint every visible slice of an `@path` mention. */
46
+ export function renderPathMentionRows(text, width, theme) {
47
+ const ranges = mentionRanges(text);
48
+ return wrapIndexed(text, width).map(row => paintMentionSlice(row.text, row.start, ranges, theme));
49
+ }
50
+ //# sourceMappingURL=path-mentions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-mentions.js","sourceRoot":"","sources":["../src/path-mentions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /** Read-only Git workspace projection used by composer and workspace commands. */
2
+ export interface ProjectContext {
3
+ /** Git worktree root, or the supplied cwd outside a repository. */
4
+ root: string;
5
+ branch?: string;
6
+ modified: number;
7
+ untracked: number;
8
+ /** Compact composer label such as `main *3 ?2`. */
9
+ gitLabel?: string;
10
+ }
11
+ export type GitRunner = (cwd: string, args: readonly string[]) => string;
12
+ /** Resolve a cwd to its worktree root, branch, and compact dirty counters. */
13
+ export declare function resolveProjectContext(cwd: string, runner?: GitRunner): ProjectContext;
@@ -0,0 +1,52 @@
1
+ /** Read-only Git workspace projection used by composer and workspace commands. */
2
+ import { execFileSync } from 'node:child_process';
3
+ const runGit = (cwd, args) => execFileSync('git', ['-C', cwd, ...args], {
4
+ encoding: 'utf8',
5
+ stdio: ['ignore', 'pipe', 'ignore'],
6
+ });
7
+ const defaultCache = new Map();
8
+ function attempt(runner, cwd, args) {
9
+ try {
10
+ const value = runner(cwd, args).trim();
11
+ return value === '' ? undefined : value;
12
+ }
13
+ catch {
14
+ return undefined;
15
+ }
16
+ }
17
+ /** Resolve a cwd to its worktree root, branch, and compact dirty counters. */
18
+ export function resolveProjectContext(cwd, runner = runGit) {
19
+ const cached = runner === runGit ? defaultCache.get(cwd) : undefined;
20
+ if (cached !== undefined)
21
+ return cached;
22
+ const root = attempt(runner, cwd, ['rev-parse', '--show-toplevel']);
23
+ if (root === undefined) {
24
+ const result = { root: cwd, modified: 0, untracked: 0 };
25
+ if (runner === runGit)
26
+ defaultCache.set(cwd, result);
27
+ return result;
28
+ }
29
+ const branch = attempt(runner, root, ['symbolic-ref', '--quiet', '--short', 'HEAD'])
30
+ ?? attempt(runner, root, ['rev-parse', '--short', 'HEAD'])
31
+ ?? 'detached';
32
+ const status = attempt(runner, root, ['status', '--porcelain=v1', '--untracked-files=normal']) ?? '';
33
+ let modified = 0;
34
+ let untracked = 0;
35
+ for (const row of status.split('\n')) {
36
+ if (row === '')
37
+ continue;
38
+ const code = row.slice(0, 2);
39
+ if (code === '??')
40
+ untracked += 1;
41
+ else if (code !== '!!')
42
+ modified += 1;
43
+ }
44
+ const gitLabel = branch
45
+ + (modified > 0 ? ` *${modified}` : '')
46
+ + (untracked > 0 ? ` ?${untracked}` : '');
47
+ const result = { root, branch, modified, untracked, gitLabel };
48
+ if (runner === runGit)
49
+ defaultCache.set(cwd, result);
50
+ return result;
51
+ }
52
+ //# sourceMappingURL=project-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-context.js","sourceRoot":"","sources":["../src/project-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /** Cached project-file discovery and fuzzy ranking for composer `@query`. */
2
+ /** One project-relative path returned by the asynchronous file index. */
3
+ export interface ProjectPathEntry {
4
+ path: string;
5
+ directory: boolean;
6
+ }
7
+ /** Recursive project-file search used by `@query`. */
8
+ export type PathSearcher = (root: string, query: string, options?: {
9
+ signal?: AbortSignal;
10
+ maxResults?: number;
11
+ }) => Promise<readonly ProjectPathEntry[]>;
12
+ export type ProjectPathLoader = (root: string, signal?: AbortSignal) => Promise<readonly ProjectPathEntry[]>;
13
+ /** Load files tracked or visible to Git; fall back to a bounded async walk. */
14
+ export declare function loadProjectPaths(root: string, signal?: AbortSignal): Promise<readonly ProjectPathEntry[]>;
15
+ /** Lower scores are better; undefined means the query does not match. */
16
+ export declare function fuzzyProjectPathScore(query: string, candidate: string): number | undefined;
17
+ /** Rank a stable project index for one live query. */
18
+ export declare function rankProjectPaths(entries: readonly ProjectPathEntry[], query: string, maxResults?: number): ProjectPathEntry[];
19
+ /** Per-TUI project index cache; search remains asynchronous and cancellable. */
20
+ export declare class ProjectFileSearch {
21
+ #private;
22
+ constructor(loader?: ProjectPathLoader, cacheTtlMs?: number);
23
+ readonly search: PathSearcher;
24
+ invalidate(root?: string): void;
25
+ }
@@ -0,0 +1,207 @@
1
+ /** Cached project-file discovery and fuzzy ranking for composer `@query`. */
2
+ import { execFile } from 'node:child_process';
3
+ import { opendir } from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ const DEFAULT_CACHE_TTL_MS = 2_000;
6
+ const DEFAULT_MAX_RESULTS = 100;
7
+ const MAX_WALK_ENTRIES = 200_000;
8
+ const FALLBACK_SKIPPED_DIRECTORIES = new Set(['.git', '.hg', '.svn', 'node_modules']);
9
+ function abortError() {
10
+ const error = new Error('Project file search aborted');
11
+ error.name = 'AbortError';
12
+ return error;
13
+ }
14
+ function throwIfAborted(signal) {
15
+ if (signal?.aborted === true)
16
+ throw abortError();
17
+ }
18
+ function normalizedRelativePath(value) {
19
+ const normalized = value.replaceAll('\\', '/').replace(/^\.\//u, '').replace(/\/+$/u, '');
20
+ if (normalized === '' || normalized.startsWith('/') || normalized === '..' || normalized.startsWith('../'))
21
+ return undefined;
22
+ if (normalized.split('/').includes('.git'))
23
+ return undefined;
24
+ return normalized;
25
+ }
26
+ function indexedGitPaths(stdout) {
27
+ const entries = new Map();
28
+ for (const value of stdout.split('\0')) {
29
+ const file = normalizedRelativePath(value);
30
+ if (file === undefined)
31
+ continue;
32
+ entries.set(file, false);
33
+ const parts = file.split('/');
34
+ for (let index = 1; index < parts.length; index += 1) {
35
+ entries.set(parts.slice(0, index).join('/'), true);
36
+ }
37
+ }
38
+ return [...entries].map(([entryPath, directory]) => ({
39
+ path: directory ? entryPath + '/' : entryPath,
40
+ directory,
41
+ }));
42
+ }
43
+ async function gitProjectPaths(root, signal) {
44
+ throwIfAborted(signal);
45
+ return new Promise((resolve, reject) => {
46
+ const options = {
47
+ cwd: root,
48
+ encoding: 'utf8',
49
+ maxBuffer: 32 * 1024 * 1024,
50
+ ...(signal === undefined ? {} : { signal }),
51
+ };
52
+ execFile('git', ['ls-files', '--cached', '--others', '--exclude-standard', '-z'], options, (error, stdout) => {
53
+ if (signal?.aborted === true) {
54
+ reject(abortError());
55
+ return;
56
+ }
57
+ if (error !== null) {
58
+ resolve(undefined);
59
+ return;
60
+ }
61
+ resolve(indexedGitPaths(stdout));
62
+ });
63
+ });
64
+ }
65
+ async function walkedProjectPaths(root, signal) {
66
+ const entries = [];
67
+ const pending = [''];
68
+ while (pending.length > 0 && entries.length < MAX_WALK_ENTRIES) {
69
+ throwIfAborted(signal);
70
+ const relativeDir = pending.shift() ?? '';
71
+ let directory;
72
+ try {
73
+ directory = await opendir(path.join(root, relativeDir));
74
+ }
75
+ catch {
76
+ continue;
77
+ }
78
+ for await (const entry of directory) {
79
+ throwIfAborted(signal);
80
+ if (entry.name === '.git')
81
+ continue;
82
+ if (entry.isDirectory() && FALLBACK_SKIPPED_DIRECTORIES.has(entry.name))
83
+ continue;
84
+ const relative = (relativeDir === '' ? entry.name : relativeDir + '/' + entry.name).replaceAll('\\', '/');
85
+ if (entry.isDirectory()) {
86
+ entries.push({ path: relative + '/', directory: true });
87
+ pending.push(relative);
88
+ }
89
+ else {
90
+ entries.push({ path: relative, directory: false });
91
+ }
92
+ if (entries.length >= MAX_WALK_ENTRIES)
93
+ break;
94
+ }
95
+ }
96
+ return entries;
97
+ }
98
+ /** Load files tracked or visible to Git; fall back to a bounded async walk. */
99
+ export async function loadProjectPaths(root, signal) {
100
+ const git = await gitProjectPaths(root, signal);
101
+ if (git !== undefined)
102
+ return git;
103
+ return walkedProjectPaths(root, signal);
104
+ }
105
+ function subsequenceScore(query, target) {
106
+ let queryIndex = 0;
107
+ let first = -1;
108
+ let previous = -1;
109
+ let gaps = 0;
110
+ for (let index = 0; index < target.length && queryIndex < query.length; index += 1) {
111
+ if (target[index] !== query[queryIndex])
112
+ continue;
113
+ if (first < 0)
114
+ first = index;
115
+ if (previous >= 0)
116
+ gaps += Math.max(0, index - previous - 1);
117
+ previous = index;
118
+ queryIndex += 1;
119
+ }
120
+ if (queryIndex !== query.length)
121
+ return undefined;
122
+ return Math.max(0, first) * 2 + gaps * 3 + target.length - query.length;
123
+ }
124
+ /** Lower scores are better; undefined means the query does not match. */
125
+ export function fuzzyProjectPathScore(query, candidate) {
126
+ const needle = query.trim().toLowerCase().replaceAll('\\', '/');
127
+ const target = candidate.toLowerCase().replaceAll('\\', '/').replace(/\/$/u, '');
128
+ if (needle === '')
129
+ return target.split('/').length * 10;
130
+ const basename = target.slice(target.lastIndexOf('/') + 1);
131
+ const depthPenalty = Math.max(0, target.split('/').length - 1) * 2;
132
+ if (basename === needle)
133
+ return depthPenalty;
134
+ if (basename.startsWith(needle))
135
+ return 20 + basename.length - needle.length + depthPenalty;
136
+ const basenameContains = basename.indexOf(needle);
137
+ if (basenameContains >= 0)
138
+ return 60 + basenameContains + depthPenalty;
139
+ const targetContains = target.indexOf(needle);
140
+ if (targetContains >= 0)
141
+ return 100 + targetContains + depthPenalty;
142
+ const basenameFuzzy = subsequenceScore(needle, basename);
143
+ if (basenameFuzzy !== undefined)
144
+ return 160 + basenameFuzzy + depthPenalty;
145
+ const pathFuzzy = subsequenceScore(needle, target);
146
+ if (pathFuzzy !== undefined)
147
+ return 260 + pathFuzzy + depthPenalty;
148
+ return undefined;
149
+ }
150
+ /** Rank a stable project index for one live query. */
151
+ export function rankProjectPaths(entries, query, maxResults = DEFAULT_MAX_RESULTS) {
152
+ if (maxResults <= 0)
153
+ return [];
154
+ return entries
155
+ .flatMap((entry) => {
156
+ const entryPath = normalizedRelativePath(entry.path);
157
+ if (entryPath === undefined)
158
+ return [];
159
+ const score = fuzzyProjectPathScore(query, entryPath);
160
+ if (score === undefined)
161
+ return [];
162
+ return [{
163
+ entry: { path: entry.directory ? entryPath + '/' : entryPath, directory: entry.directory },
164
+ score,
165
+ depth: entryPath.split('/').length,
166
+ }];
167
+ })
168
+ .sort((left, right) => left.score - right.score
169
+ || Number(right.entry.directory) - Number(left.entry.directory)
170
+ || left.depth - right.depth
171
+ || left.entry.path.localeCompare(right.entry.path))
172
+ .slice(0, maxResults)
173
+ .map(result => result.entry);
174
+ }
175
+ /** Per-TUI project index cache; search remains asynchronous and cancellable. */
176
+ export class ProjectFileSearch {
177
+ #cache = new Map();
178
+ #loader;
179
+ #cacheTtlMs;
180
+ constructor(loader = loadProjectPaths, cacheTtlMs = DEFAULT_CACHE_TTL_MS) {
181
+ this.#loader = loader;
182
+ this.#cacheTtlMs = cacheTtlMs;
183
+ }
184
+ search = async (root, query, options = {}) => {
185
+ throwIfAborted(options.signal);
186
+ const cacheKey = path.resolve(root);
187
+ const now = Date.now();
188
+ const cached = this.#cache.get(cacheKey);
189
+ let entries;
190
+ if (cached !== undefined && cached.expiresAt >= now) {
191
+ entries = cached.entries;
192
+ }
193
+ else {
194
+ entries = await this.#loader(cacheKey, options.signal);
195
+ throwIfAborted(options.signal);
196
+ this.#cache.set(cacheKey, { entries, expiresAt: Date.now() + this.#cacheTtlMs });
197
+ }
198
+ return rankProjectPaths(entries, query, options.maxResults ?? DEFAULT_MAX_RESULTS);
199
+ };
200
+ invalidate(root) {
201
+ if (root === undefined)
202
+ this.#cache.clear();
203
+ else
204
+ this.#cache.delete(path.resolve(root));
205
+ }
206
+ }
207
+ //# sourceMappingURL=project-file-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-file-search.js","sourceRoot":"","sources":["../src/project-file-search.ts"],"names":[],"mappings":"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"}