@visorcraft/idlehands 0.9.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.
Files changed (197) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -0
  3. package/dist/agent.js +2604 -0
  4. package/dist/agent.js.map +1 -0
  5. package/dist/anton/controller.js +341 -0
  6. package/dist/anton/controller.js.map +1 -0
  7. package/dist/anton/lock.js +110 -0
  8. package/dist/anton/lock.js.map +1 -0
  9. package/dist/anton/parser.js +303 -0
  10. package/dist/anton/parser.js.map +1 -0
  11. package/dist/anton/prompt.js +203 -0
  12. package/dist/anton/prompt.js.map +1 -0
  13. package/dist/anton/reporter.js +119 -0
  14. package/dist/anton/reporter.js.map +1 -0
  15. package/dist/anton/session.js +51 -0
  16. package/dist/anton/session.js.map +1 -0
  17. package/dist/anton/types.js +7 -0
  18. package/dist/anton/types.js.map +1 -0
  19. package/dist/anton/verifier.js +263 -0
  20. package/dist/anton/verifier.js.map +1 -0
  21. package/dist/bench/compare.js +239 -0
  22. package/dist/bench/compare.js.map +1 -0
  23. package/dist/bench/debug_hooks.js +17 -0
  24. package/dist/bench/debug_hooks.js.map +1 -0
  25. package/dist/bench/json_extract.js +22 -0
  26. package/dist/bench/json_extract.js.map +1 -0
  27. package/dist/bench/openclaw.js +86 -0
  28. package/dist/bench/openclaw.js.map +1 -0
  29. package/dist/bench/report.js +116 -0
  30. package/dist/bench/report.js.map +1 -0
  31. package/dist/bench/runner.js +312 -0
  32. package/dist/bench/runner.js.map +1 -0
  33. package/dist/bench/types.js +2 -0
  34. package/dist/bench/types.js.map +1 -0
  35. package/dist/bot/commands.js +444 -0
  36. package/dist/bot/commands.js.map +1 -0
  37. package/dist/bot/confirm-discord.js +133 -0
  38. package/dist/bot/confirm-discord.js.map +1 -0
  39. package/dist/bot/confirm-telegram.js +290 -0
  40. package/dist/bot/confirm-telegram.js.map +1 -0
  41. package/dist/bot/discord.js +826 -0
  42. package/dist/bot/discord.js.map +1 -0
  43. package/dist/bot/format.js +210 -0
  44. package/dist/bot/format.js.map +1 -0
  45. package/dist/bot/session-manager.js +270 -0
  46. package/dist/bot/session-manager.js.map +1 -0
  47. package/dist/bot/telegram.js +678 -0
  48. package/dist/bot/telegram.js.map +1 -0
  49. package/dist/cli/agent-turn.js +45 -0
  50. package/dist/cli/agent-turn.js.map +1 -0
  51. package/dist/cli/args.js +236 -0
  52. package/dist/cli/args.js.map +1 -0
  53. package/dist/cli/bot.js +252 -0
  54. package/dist/cli/bot.js.map +1 -0
  55. package/dist/cli/build-repl-context.js +365 -0
  56. package/dist/cli/build-repl-context.js.map +1 -0
  57. package/dist/cli/command-registry.js +20 -0
  58. package/dist/cli/command-registry.js.map +1 -0
  59. package/dist/cli/commands/anton.js +271 -0
  60. package/dist/cli/commands/anton.js.map +1 -0
  61. package/dist/cli/commands/editing.js +328 -0
  62. package/dist/cli/commands/editing.js.map +1 -0
  63. package/dist/cli/commands/model.js +274 -0
  64. package/dist/cli/commands/model.js.map +1 -0
  65. package/dist/cli/commands/project.js +255 -0
  66. package/dist/cli/commands/project.js.map +1 -0
  67. package/dist/cli/commands/runtime.js +63 -0
  68. package/dist/cli/commands/runtime.js.map +1 -0
  69. package/dist/cli/commands/session.js +281 -0
  70. package/dist/cli/commands/session.js.map +1 -0
  71. package/dist/cli/commands/tools.js +126 -0
  72. package/dist/cli/commands/tools.js.map +1 -0
  73. package/dist/cli/commands/trifecta.js +221 -0
  74. package/dist/cli/commands/trifecta.js.map +1 -0
  75. package/dist/cli/commands/tui.js +17 -0
  76. package/dist/cli/commands/tui.js.map +1 -0
  77. package/dist/cli/init.js +222 -0
  78. package/dist/cli/init.js.map +1 -0
  79. package/dist/cli/input.js +360 -0
  80. package/dist/cli/input.js.map +1 -0
  81. package/dist/cli/oneshot.js +254 -0
  82. package/dist/cli/oneshot.js.map +1 -0
  83. package/dist/cli/repl-context.js +2 -0
  84. package/dist/cli/repl-context.js.map +1 -0
  85. package/dist/cli/runtime-cmds.js +811 -0
  86. package/dist/cli/runtime-cmds.js.map +1 -0
  87. package/dist/cli/service.js +145 -0
  88. package/dist/cli/service.js.map +1 -0
  89. package/dist/cli/session-state.js +130 -0
  90. package/dist/cli/session-state.js.map +1 -0
  91. package/dist/cli/setup.js +815 -0
  92. package/dist/cli/setup.js.map +1 -0
  93. package/dist/cli/shell.js +79 -0
  94. package/dist/cli/shell.js.map +1 -0
  95. package/dist/cli/status.js +392 -0
  96. package/dist/cli/status.js.map +1 -0
  97. package/dist/cli/watch.js +33 -0
  98. package/dist/cli/watch.js.map +1 -0
  99. package/dist/client.js +676 -0
  100. package/dist/client.js.map +1 -0
  101. package/dist/commands.js +194 -0
  102. package/dist/commands.js.map +1 -0
  103. package/dist/config.js +507 -0
  104. package/dist/config.js.map +1 -0
  105. package/dist/confirm/auto.js +13 -0
  106. package/dist/confirm/auto.js.map +1 -0
  107. package/dist/confirm/headless.js +41 -0
  108. package/dist/confirm/headless.js.map +1 -0
  109. package/dist/confirm/terminal.js +90 -0
  110. package/dist/confirm/terminal.js.map +1 -0
  111. package/dist/context.js +49 -0
  112. package/dist/context.js.map +1 -0
  113. package/dist/git.js +136 -0
  114. package/dist/git.js.map +1 -0
  115. package/dist/harnesses.js +171 -0
  116. package/dist/harnesses.js.map +1 -0
  117. package/dist/history.js +139 -0
  118. package/dist/history.js.map +1 -0
  119. package/dist/index.js +700 -0
  120. package/dist/index.js.map +1 -0
  121. package/dist/indexer.js +374 -0
  122. package/dist/indexer.js.map +1 -0
  123. package/dist/jsonrpc.js +76 -0
  124. package/dist/jsonrpc.js.map +1 -0
  125. package/dist/lens.js +525 -0
  126. package/dist/lens.js.map +1 -0
  127. package/dist/lsp.js +605 -0
  128. package/dist/lsp.js.map +1 -0
  129. package/dist/markdown.js +275 -0
  130. package/dist/markdown.js.map +1 -0
  131. package/dist/mcp.js +554 -0
  132. package/dist/mcp.js.map +1 -0
  133. package/dist/recovery.js +178 -0
  134. package/dist/recovery.js.map +1 -0
  135. package/dist/replay.js +132 -0
  136. package/dist/replay.js.map +1 -0
  137. package/dist/replay_cli.js +24 -0
  138. package/dist/replay_cli.js.map +1 -0
  139. package/dist/runtime/executor.js +418 -0
  140. package/dist/runtime/executor.js.map +1 -0
  141. package/dist/runtime/planner.js +197 -0
  142. package/dist/runtime/planner.js.map +1 -0
  143. package/dist/runtime/store.js +289 -0
  144. package/dist/runtime/store.js.map +1 -0
  145. package/dist/runtime/types.js +2 -0
  146. package/dist/runtime/types.js.map +1 -0
  147. package/dist/safety.js +446 -0
  148. package/dist/safety.js.map +1 -0
  149. package/dist/spinner.js +224 -0
  150. package/dist/spinner.js.map +1 -0
  151. package/dist/sys/context.js +124 -0
  152. package/dist/sys/context.js.map +1 -0
  153. package/dist/sys/snapshot.sh +97 -0
  154. package/dist/term.js +61 -0
  155. package/dist/term.js.map +1 -0
  156. package/dist/themes.js +135 -0
  157. package/dist/themes.js.map +1 -0
  158. package/dist/tools.js +1114 -0
  159. package/dist/tools.js.map +1 -0
  160. package/dist/tui/branch-picker.js +65 -0
  161. package/dist/tui/branch-picker.js.map +1 -0
  162. package/dist/tui/command-handler.js +108 -0
  163. package/dist/tui/command-handler.js.map +1 -0
  164. package/dist/tui/confirm.js +90 -0
  165. package/dist/tui/confirm.js.map +1 -0
  166. package/dist/tui/controller.js +463 -0
  167. package/dist/tui/controller.js.map +1 -0
  168. package/dist/tui/event-bridge.js +44 -0
  169. package/dist/tui/event-bridge.js.map +1 -0
  170. package/dist/tui/events.js +2 -0
  171. package/dist/tui/events.js.map +1 -0
  172. package/dist/tui/keymap.js +144 -0
  173. package/dist/tui/keymap.js.map +1 -0
  174. package/dist/tui/layout.js +11 -0
  175. package/dist/tui/layout.js.map +1 -0
  176. package/dist/tui/render.js +186 -0
  177. package/dist/tui/render.js.map +1 -0
  178. package/dist/tui/screen.js +48 -0
  179. package/dist/tui/screen.js.map +1 -0
  180. package/dist/tui/state.js +167 -0
  181. package/dist/tui/state.js.map +1 -0
  182. package/dist/tui/theme.js +70 -0
  183. package/dist/tui/theme.js.map +1 -0
  184. package/dist/tui/types.js +2 -0
  185. package/dist/tui/types.js.map +1 -0
  186. package/dist/types.js +2 -0
  187. package/dist/types.js.map +1 -0
  188. package/dist/upgrade.js +412 -0
  189. package/dist/upgrade.js.map +1 -0
  190. package/dist/utils.js +87 -0
  191. package/dist/utils.js.map +1 -0
  192. package/dist/vault.js +520 -0
  193. package/dist/vault.js.map +1 -0
  194. package/dist/vim.js +160 -0
  195. package/dist/vim.js.map +1 -0
  196. package/package.json +67 -0
  197. package/src/sys/snapshot.sh +97 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trifecta.js","sourceRoot":"","sources":["../../../src/cli/commands/trifecta.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { TuiController } from '../../tui/controller.js';
2
+ import { validateTerminal } from '../../tui/screen.js';
3
+ /**
4
+ * Launch the fullscreen TUI. Validates terminal capabilities first;
5
+ * returns false if the terminal isn't suitable (caller should fall back to CLI).
6
+ */
7
+ export async function runTui(config, _args) {
8
+ const check = validateTerminal();
9
+ if (!check.ok) {
10
+ console.log(`[tui] ${check.reason ?? 'unsupported terminal'}. Falling back to classic CLI.`);
11
+ return false;
12
+ }
13
+ const controller = new TuiController(config);
14
+ await controller.run();
15
+ return true;
16
+ }
17
+ //# sourceMappingURL=tui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui.js","sourceRoot":"","sources":["../../../src/cli/commands/tui.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAuB,EAAE,KAAU;IAC9D,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,MAAM,IAAI,sBAAsB,gCAAgC,CAAC,CAAC;QAC7F,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,UAAU,CAAC,GAAG,EAAE,CAAC;IACvB,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Project init context generation, git snapshot helpers, change entry tracking.
3
+ */
4
+ import path from 'node:path';
5
+ import fs from 'node:fs/promises';
6
+ import { spawnSync } from 'node:child_process';
7
+ export async function collectProjectTree(cwd) {
8
+ const out = [];
9
+ const top = await fs.readdir(cwd, { withFileTypes: true }).catch(() => []);
10
+ for (const e of top) {
11
+ if (e.name.startsWith('.'))
12
+ continue;
13
+ const rel = e.name;
14
+ if (e.isFile()) {
15
+ out.push(`- ${rel}`);
16
+ continue;
17
+ }
18
+ if (e.isDirectory()) {
19
+ out.push(`- ${rel}/`);
20
+ const nested = await fs.readdir(path.join(cwd, rel), { withFileTypes: true }).catch(() => []);
21
+ for (const n of nested.slice(0, 8)) {
22
+ if (n.name.startsWith('.'))
23
+ continue;
24
+ out.push(` - ${rel}/${n.name}${n.isDirectory() ? '/' : ''}`);
25
+ }
26
+ }
27
+ }
28
+ return out.slice(0, 40);
29
+ }
30
+ export async function detectProjectLanguages(cwd) {
31
+ const exts = new Map([
32
+ ['.ts', 'TypeScript'], ['.tsx', 'TypeScript'], ['.js', 'JavaScript'], ['.jsx', 'JavaScript'],
33
+ ['.py', 'Python'], ['.rs', 'Rust'], ['.go', 'Go'], ['.cs', 'C#'], ['.php', 'PHP'],
34
+ ['.java', 'Java'], ['.kt', 'Kotlin'], ['.c', 'C'], ['.cpp', 'C++'], ['.h', 'C/C++'],
35
+ ['.swift', 'Swift'], ['.rb', 'Ruby'], ['.sh', 'Shell'], ['.yaml', 'YAML'], ['.yml', 'YAML'],
36
+ ]);
37
+ const found = new Set();
38
+ for await (const rel of fs.glob('**/*', { cwd, exclude: ['**/node_modules/**', '**/.git/**', '**/dist/**', '**/build/**'] })) {
39
+ const ext = path.extname(String(rel)).toLowerCase();
40
+ const lang = exts.get(ext);
41
+ if (lang)
42
+ found.add(lang);
43
+ if (found.size >= 8)
44
+ break;
45
+ }
46
+ return [...found];
47
+ }
48
+ export async function generateInitContext(cwd) {
49
+ const has = async (name) => {
50
+ try {
51
+ await fs.access(path.join(cwd, name));
52
+ return true;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ };
58
+ const projectName = path.basename(cwd);
59
+ const tree = await collectProjectTree(cwd);
60
+ const langs = await detectProjectLanguages(cwd);
61
+ const readmePath = (await has('README.md')) ? 'README.md' : ((await has('readme.md')) ? 'readme.md' : '');
62
+ let readmePreview = '';
63
+ if (readmePath) {
64
+ const raw = await fs.readFile(path.join(cwd, readmePath), 'utf8').catch(() => '');
65
+ readmePreview = raw.split(/\r?\n/).slice(0, 50).join('\n').trim();
66
+ }
67
+ const buildHints = [];
68
+ const testHints = [];
69
+ if (await has('package.json')) {
70
+ buildHints.push('npm run build');
71
+ testHints.push('npm test');
72
+ }
73
+ if (await has('Cargo.toml')) {
74
+ buildHints.push('cargo build');
75
+ testHints.push('cargo test');
76
+ }
77
+ if (await has('go.mod')) {
78
+ buildHints.push('go build ./...');
79
+ testHints.push('go test ./...');
80
+ }
81
+ if (await has('Makefile')) {
82
+ buildHints.push('make');
83
+ testHints.push('make test');
84
+ }
85
+ if (await has('pyproject.toml') || await has('requirements.txt')) {
86
+ buildHints.push('python -m build (if configured)');
87
+ testHints.push('pytest');
88
+ }
89
+ const content = [
90
+ `# Project: ${projectName}`,
91
+ '',
92
+ `Auto-generated by /init on ${new Date().toISOString()}.`,
93
+ '',
94
+ '## Stack',
95
+ langs.length ? `- Languages: ${langs.join(', ')}` : '- Languages: (not detected)',
96
+ '',
97
+ '## Structure (depth 2)',
98
+ ...(tree.length ? tree : ['- (empty)']),
99
+ '',
100
+ '## Build & Test Hints',
101
+ ...(buildHints.length ? buildHints.map((x) => `- Build: \`${x}\``) : ['- Build: (not detected)']),
102
+ ...(testHints.length ? testHints.map((x) => `- Test: \`${x}\``) : ['- Test: (not detected)']),
103
+ '',
104
+ '## README preview (first 50 lines)',
105
+ readmePreview ? '```markdown\n' + readmePreview + '\n```' : '_No README found._',
106
+ '',
107
+ '## Key patterns',
108
+ '- Keep this file concise and task-oriented.',
109
+ '- Add project-specific commands and architecture notes here over time.',
110
+ ].join('\n');
111
+ return { content, tokenEstimate: Math.ceil(content.length / 4) };
112
+ }
113
+ export function formatInitSummary(summary) {
114
+ return summary.content.endsWith('\n') ? summary.content : summary.content + '\n';
115
+ }
116
+ // ── Git helpers ──────────────────────────────────────────────────────
117
+ export function getGitSnapshot(cwd) {
118
+ const status = spawnSync('bash', ['-lc', 'git status -s'], {
119
+ cwd,
120
+ encoding: 'utf8',
121
+ timeout: 2000,
122
+ });
123
+ const diffStat = spawnSync('bash', ['-lc', 'git diff --stat'], {
124
+ cwd,
125
+ encoding: 'utf8',
126
+ timeout: 2000,
127
+ });
128
+ return {
129
+ status: status.status === 0 ? String(status.stdout || '').trim() : '',
130
+ diffStat: diffStat.status === 0 ? String(diffStat.stdout || '').trim() : '',
131
+ };
132
+ }
133
+ export function getGitShortStat(cwd) {
134
+ const short = spawnSync('bash', ['-lc', 'git diff --shortstat'], {
135
+ cwd,
136
+ encoding: 'utf8',
137
+ timeout: 2000,
138
+ });
139
+ return short.status === 0 ? String(short.stdout || '').trim() : '';
140
+ }
141
+ export function parseChangedFileCount(shortStat) {
142
+ const m = shortStat.match(/(\d+)\s+files? changed/i);
143
+ if (!m)
144
+ return 0;
145
+ return Number(m[1]) || 0;
146
+ }
147
+ export function countDiffAddsRemoves(diff) {
148
+ let adds = 0;
149
+ let removes = 0;
150
+ for (const line of diff.split(/\r?\n/)) {
151
+ if (line.startsWith('+++') || line.startsWith('---') || line.startsWith('@@'))
152
+ continue;
153
+ if (line.startsWith('+'))
154
+ adds++;
155
+ if (line.startsWith('-'))
156
+ removes++;
157
+ }
158
+ return { adds, removes };
159
+ }
160
+ export async function buildReplayChangeEntries(replay, sinceMs, lastN) {
161
+ if (!replay)
162
+ return [];
163
+ const cps = await replay.list(10000);
164
+ let rows = cps
165
+ .map((cp) => ({ ...cp, ms: Date.parse(cp.ts || '') }))
166
+ .filter((cp) => Number.isFinite(cp.ms));
167
+ if (sinceMs)
168
+ rows = rows.filter((cp) => cp.ms >= sinceMs);
169
+ if (lastN && lastN > 0)
170
+ rows = rows.slice(0, lastN);
171
+ const byFile = new Map();
172
+ for (const cp of rows) {
173
+ if (!cp.filePath)
174
+ continue;
175
+ const cur = byFile.get(cp.filePath) ?? { filePath: cp.filePath, edits: 0, opHint: cp.op };
176
+ cur.edits += 1;
177
+ byFile.set(cp.filePath, cur);
178
+ }
179
+ return [...byFile.values()].sort((a, b) => a.filePath.localeCompare(b.filePath));
180
+ }
181
+ export function getGitNumstatMap(cwd) {
182
+ const run = spawnSync('bash', ['-lc', 'git diff --numstat'], { cwd, encoding: 'utf8', timeout: 2500 });
183
+ const out = run.status === 0 ? String(run.stdout || '') : '';
184
+ const map = new Map();
185
+ for (const line of out.split(/\r?\n/)) {
186
+ if (!line.trim())
187
+ continue;
188
+ const parts = line.split(/\t/);
189
+ if (parts.length < 3)
190
+ continue;
191
+ const adds = Number(parts[0]) || 0;
192
+ const removes = Number(parts[1]) || 0;
193
+ const filePath = parts.slice(2).join('\t');
194
+ map.set(filePath, { adds, removes });
195
+ }
196
+ return map;
197
+ }
198
+ export function getGitPorcelainMap(cwd) {
199
+ const run = spawnSync('bash', ['-lc', 'git status --porcelain'], { cwd, encoding: 'utf8', timeout: 2500 });
200
+ const out = run.status === 0 ? String(run.stdout || '') : '';
201
+ const map = new Map();
202
+ for (const line of out.split(/\r?\n/)) {
203
+ if (!line.trim() || line.length < 4)
204
+ continue;
205
+ const status = line.slice(0, 2);
206
+ const filePath = line.slice(3).trim();
207
+ map.set(filePath, status);
208
+ }
209
+ return map;
210
+ }
211
+ export function formatChangePrefix(statusCode) {
212
+ if (!statusCode)
213
+ return '✎';
214
+ if (statusCode.includes('??'))
215
+ return '+';
216
+ if (statusCode.includes('D'))
217
+ return '−';
218
+ if (statusCode.includes('A'))
219
+ return '+';
220
+ return '✎';
221
+ }
222
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,360 @@
1
+ /**
2
+ * User input helpers: multi-line continuation, @-file expansion, image refs,
3
+ * clipboard, reverse-search, stdin pipe reading.
4
+ */
5
+ import path from 'node:path';
6
+ import os from 'node:os';
7
+ import fs from 'node:fs/promises';
8
+ import { spawnSync } from 'node:child_process';
9
+ import { escapeRegex } from '../utils.js';
10
+ // ── Multi-line continuation ──────────────────────────────────────────
11
+ export function hasUnclosedTripleQuote(s) {
12
+ const m = s.match(/"""/g);
13
+ return (m?.length ?? 0) % 2 === 1;
14
+ }
15
+ export function hasUnbalancedDelimiters(s) {
16
+ let paren = 0;
17
+ let brace = 0;
18
+ let bracket = 0;
19
+ let inSingle = false;
20
+ let inDouble = false;
21
+ const isWordChar = (c) => /[A-Za-z0-9_]/.test(c);
22
+ for (let i = 0; i < s.length; i++) {
23
+ const ch = s[i];
24
+ const prev = i > 0 ? s[i - 1] : '';
25
+ const next = i + 1 < s.length ? s[i + 1] : '';
26
+ const apostropheInWord = ch === "'" && isWordChar(prev) && isWordChar(next);
27
+ if (ch === "'" && prev !== '\\' && !inDouble && !apostropheInWord)
28
+ inSingle = !inSingle;
29
+ else if (ch === '"' && prev !== '\\' && !inSingle)
30
+ inDouble = !inDouble;
31
+ if (inSingle || inDouble)
32
+ continue;
33
+ if (ch === '(')
34
+ paren++;
35
+ else if (ch === ')')
36
+ paren--;
37
+ else if (ch === '{')
38
+ brace++;
39
+ else if (ch === '}')
40
+ brace--;
41
+ else if (ch === '[')
42
+ bracket++;
43
+ else if (ch === ']')
44
+ bracket--;
45
+ }
46
+ return paren > 0 || brace > 0 || bracket > 0 || inSingle || inDouble;
47
+ }
48
+ export function needsContinuation(text) {
49
+ const trimmed = text.trimEnd();
50
+ if (trimmed.endsWith('\\'))
51
+ return true;
52
+ if (hasUnclosedTripleQuote(text))
53
+ return true;
54
+ return hasUnbalancedDelimiters(text);
55
+ }
56
+ export async function readUserInput(rl, prompt) {
57
+ let text = await rl.question(prompt);
58
+ // Bracketed paste / multi-line chunks come through as embedded newlines.
59
+ if (text.includes('\n')) {
60
+ return text;
61
+ }
62
+ while (needsContinuation(text)) {
63
+ const next = await rl.question('... ');
64
+ if (text.trimEnd().endsWith('\\')) {
65
+ text = text.trimEnd().replace(/\\$/, '') + '\n' + next;
66
+ }
67
+ else {
68
+ text += '\n' + next;
69
+ }
70
+ }
71
+ return text;
72
+ }
73
+ export async function readStdinIfPiped() {
74
+ if (process.stdin.isTTY)
75
+ return '';
76
+ const chunks = [];
77
+ for await (const chunk of process.stdin) {
78
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
79
+ }
80
+ return Buffer.concat(chunks).toString('utf8').trim();
81
+ }
82
+ // ── Reverse search ───────────────────────────────────────────────────
83
+ export async function reverseSearchHistory(rl, styler) {
84
+ const q = (await rl.question('\n(reverse-i-search) query: ')).trim();
85
+ if (!q) {
86
+ rl.prompt(true);
87
+ return;
88
+ }
89
+ const hist = Array.isArray(rl.history) ? rl.history : [];
90
+ const found = hist.find((h) => h.includes(q));
91
+ if (!found) {
92
+ process.stderr.write(`${styler.dim(`\n(no match for "${q}")\n`)}`);
93
+ rl.prompt(true);
94
+ return;
95
+ }
96
+ rl.write(null, { ctrl: true, name: 'u' });
97
+ rl.write(found);
98
+ }
99
+ // ── Path / binary helpers ────────────────────────────────────────────
100
+ export function isLikelyBinary(buf) {
101
+ const sample = buf.subarray(0, Math.min(buf.length, 512));
102
+ return sample.includes(0);
103
+ }
104
+ export function isPathCompletionContext(line) {
105
+ const words = line.trim().split(/\s+/).filter(Boolean);
106
+ if (words.length < 2)
107
+ return false;
108
+ const first = words[0].toLowerCase();
109
+ const pathish = new Set([
110
+ 'read_file', 'write_file', 'edit_file', 'insert_file', 'list_dir', 'search_files',
111
+ 'cat', 'less', 'more', 'vim', 'nano', 'code', 'cd', 'ls',
112
+ ]);
113
+ return pathish.has(first);
114
+ }
115
+ // ── .gitignore / file collection ─────────────────────────────────────
116
+ export function matchIgnorePattern(relPath, pattern) {
117
+ const p = pattern.trim();
118
+ if (!p || p.startsWith('#') || p.startsWith('!'))
119
+ return false;
120
+ const normalized = relPath.replace(/\\/g, '/');
121
+ if (p.endsWith('/')) {
122
+ const dir = p.slice(0, -1).replace(/^\//, '');
123
+ return normalized === dir || normalized.startsWith(`${dir}/`);
124
+ }
125
+ if (!p.includes('*')) {
126
+ const plain = p.replace(/^\//, '');
127
+ return normalized === plain || normalized.startsWith(`${plain}/`);
128
+ }
129
+ const re = new RegExp('^' + p.replace(/^\//, '').split('*').map(escapeRegex).join('.*') + '$');
130
+ return re.test(normalized);
131
+ }
132
+ export async function loadGitIgnorePatterns(cwd) {
133
+ const fixed = ['.git/', 'node_modules/', 'dist/', 'build/'];
134
+ const raw = await fs.readFile(path.join(cwd, '.gitignore'), 'utf8').catch(() => '');
135
+ if (!raw.trim())
136
+ return fixed;
137
+ const fromFile = raw
138
+ .split(/\r?\n/)
139
+ .map((line) => line.trim())
140
+ .filter(Boolean)
141
+ .filter((line) => !line.startsWith('#'));
142
+ return [...fixed, ...fromFile];
143
+ }
144
+ export function isIgnored(relPath, patterns) {
145
+ return patterns.some((p) => matchIgnorePattern(relPath, p));
146
+ }
147
+ export async function collectDirectoryFiles(baseDir, relDir, maxDepth, patterns, acc) {
148
+ if (maxDepth < 0)
149
+ return;
150
+ const absDir = path.join(baseDir, relDir);
151
+ const entries = await fs.readdir(absDir, { withFileTypes: true }).catch(() => []);
152
+ for (const e of entries) {
153
+ const rel = path.posix.join(relDir.replace(/\\/g, '/'), e.name).replace(/^\.?\//, '');
154
+ if (!rel)
155
+ continue;
156
+ if (isIgnored(rel, patterns))
157
+ continue;
158
+ if (e.isDirectory()) {
159
+ await collectDirectoryFiles(baseDir, rel, maxDepth - 1, patterns, acc);
160
+ }
161
+ else if (e.isFile()) {
162
+ acc.push(rel);
163
+ }
164
+ }
165
+ }
166
+ async function resolveAtRefToFiles(ref, cwd, patterns) {
167
+ const hasGlob = /[*?[]/.test(ref);
168
+ if (hasGlob) {
169
+ const out = [];
170
+ try {
171
+ for await (const rel of fs.glob(ref, { cwd })) {
172
+ const clean = String(rel).replace(/\\/g, '/');
173
+ if (!clean)
174
+ continue;
175
+ if (isIgnored(clean, patterns))
176
+ continue;
177
+ const st = await fs.stat(path.join(cwd, clean)).catch(() => null);
178
+ if (st?.isFile())
179
+ out.push(clean);
180
+ }
181
+ }
182
+ catch { }
183
+ return out;
184
+ }
185
+ const abs = path.resolve(cwd, ref);
186
+ const st = await fs.stat(abs).catch(() => null);
187
+ if (!st)
188
+ return [];
189
+ if (st.isFile()) {
190
+ const rel = path.relative(cwd, abs).replace(/\\/g, '/');
191
+ if (!rel || isIgnored(rel, patterns))
192
+ return [];
193
+ return [rel];
194
+ }
195
+ if (st.isDirectory()) {
196
+ const rel = path.relative(cwd, abs).replace(/\\/g, '/');
197
+ const acc = [];
198
+ await collectDirectoryFiles(cwd, rel, 3, patterns, acc);
199
+ return acc;
200
+ }
201
+ return [];
202
+ }
203
+ export async function expandAtFileRefs(inputText, cwd, contextMaxTokens = 8192) {
204
+ const tokenRe = /(^|\s)@([^\s]+)/g;
205
+ const refs = [];
206
+ let m;
207
+ while ((m = tokenRe.exec(inputText)) !== null)
208
+ refs.push(m[2]);
209
+ if (refs.length === 0)
210
+ return { text: inputText, warnings: [] };
211
+ const patterns = await loadGitIgnorePatterns(cwd);
212
+ const warnings = [];
213
+ let expanded = inputText;
214
+ let usedTokens = Math.ceil(inputText.length / 4);
215
+ for (const ref of refs) {
216
+ const files = await resolveAtRefToFiles(ref, cwd, patterns);
217
+ if (!files.length)
218
+ continue;
219
+ let injection = '';
220
+ for (const relFile of files) {
221
+ const buf = await fs.readFile(path.join(cwd, relFile)).catch(() => null);
222
+ if (!buf)
223
+ continue;
224
+ if (isLikelyBinary(buf)) {
225
+ warnings.push(`[at-ref] skipped binary file @${relFile}`);
226
+ continue;
227
+ }
228
+ const block = `[Contents of ${relFile}]\n${buf.toString('utf8')}\n[End ${relFile}]\n`;
229
+ const blockTokens = Math.ceil(block.length / 4);
230
+ if (usedTokens + blockTokens > contextMaxTokens) {
231
+ warnings.push(`[at-ref] context_max_tokens (${contextMaxTokens}) reached while expanding @${ref}; remaining refs truncated`);
232
+ injection += `[truncated @${ref}: context_max_tokens reached]`;
233
+ break;
234
+ }
235
+ usedTokens += blockTokens;
236
+ injection += block;
237
+ }
238
+ if (!injection.trim())
239
+ continue;
240
+ expanded = expanded.replace(`@${ref}`, injection.trimEnd());
241
+ }
242
+ return { text: expanded, warnings };
243
+ }
244
+ // ── Image handling ───────────────────────────────────────────────────
245
+ export function isImagePathLike(value) {
246
+ return /\.(png|jpe?g|webp|gif|bmp|tiff?)$/i.test(value);
247
+ }
248
+ export function mimeForImagePath(value) {
249
+ const lower = value.toLowerCase();
250
+ if (lower.endsWith('.png'))
251
+ return 'image/png';
252
+ if (lower.endsWith('.jpg') || lower.endsWith('.jpeg'))
253
+ return 'image/jpeg';
254
+ if (lower.endsWith('.webp'))
255
+ return 'image/webp';
256
+ if (lower.endsWith('.gif'))
257
+ return 'image/gif';
258
+ if (lower.endsWith('.bmp'))
259
+ return 'image/bmp';
260
+ if (lower.endsWith('.tif') || lower.endsWith('.tiff'))
261
+ return 'image/tiff';
262
+ return 'application/octet-stream';
263
+ }
264
+ export function extractImageRefs(text) {
265
+ const refs = new Set();
266
+ // Markdown images: ![alt](path-or-url)
267
+ const mdRe = /!\[[^\]]*\]\(([^)]+)\)/g;
268
+ let mm;
269
+ while ((mm = mdRe.exec(text)) !== null) {
270
+ const v = mm[1].trim();
271
+ if (v)
272
+ refs.add(v.replace(/^['"]|['"]$/g, ''));
273
+ }
274
+ // Plain URLs and path-like image tokens
275
+ const tokenRe = /https?:\/\/[^\s)]+\.(?:png|jpe?g|webp|gif|bmp|tiff?)(?:\?[^\s)]*)?|(?:\.\.\/|\.\/|\/|~\/)?[^\s)]+\.(?:png|jpe?g|webp|gif|bmp|tiff?)/gi;
276
+ let m;
277
+ while ((m = tokenRe.exec(text)) !== null) {
278
+ refs.add(m[0].trim());
279
+ }
280
+ return [...refs];
281
+ }
282
+ export function hasClipboardImageToken(text) {
283
+ return /(?:^|\s)(@clipboard|clipboard:image|\[clipboard\]|\[\[clipboard\]\])(?:$|\s)/i.test(text);
284
+ }
285
+ function readClipboardImageDataUrl() {
286
+ const attempts = [
287
+ { cmd: 'wl-paste', args: ['--type', 'image/png'], mime: 'image/png' },
288
+ { cmd: 'wl-paste', args: ['--type', 'image/jpeg'], mime: 'image/jpeg' },
289
+ { cmd: 'xclip', args: ['-selection', 'clipboard', '-t', 'image/png', '-o'], mime: 'image/png' },
290
+ { cmd: 'xclip', args: ['-selection', 'clipboard', '-t', 'image/jpeg', '-o'], mime: 'image/jpeg' },
291
+ ];
292
+ for (const a of attempts) {
293
+ const run = spawnSync(a.cmd, a.args, { encoding: null, timeout: 1500 });
294
+ if (run.status === 0 && run.stdout && Buffer.isBuffer(run.stdout) && run.stdout.length > 0) {
295
+ return `data:${a.mime};base64,${run.stdout.toString('base64')}`;
296
+ }
297
+ }
298
+ return null;
299
+ }
300
+ export async function expandPromptImages(text, cwd, supportsVision) {
301
+ const refs = extractImageRefs(text);
302
+ const wantsClipboard = hasClipboardImageToken(text);
303
+ if (!refs.length && !wantsClipboard)
304
+ return { content: text, warnings: [], imageCount: 0 };
305
+ if (!supportsVision) {
306
+ const detected = refs.length + (wantsClipboard ? 1 : 0);
307
+ return {
308
+ content: text,
309
+ warnings: [`[vision] detected ${detected} image reference(s), but current model does not advertise vision input support.`],
310
+ imageCount: 0,
311
+ };
312
+ }
313
+ const warnings = [];
314
+ const parts = [{ type: 'text', text }];
315
+ let imageCount = 0;
316
+ for (const ref of refs) {
317
+ if (/^https?:\/\//i.test(ref)) {
318
+ parts.push({ type: 'image_url', image_url: { url: ref } });
319
+ imageCount++;
320
+ continue;
321
+ }
322
+ const cleaned = ref.replace(/^['"]|['"]$/g, '');
323
+ const abs = cleaned.startsWith('~/')
324
+ ? path.join(os.homedir(), cleaned.slice(2))
325
+ : path.resolve(cwd, cleaned);
326
+ const exists = await fs.stat(abs).catch(() => null);
327
+ if (!exists?.isFile()) {
328
+ warnings.push(`[vision] image path not found: ${cleaned}`);
329
+ continue;
330
+ }
331
+ if (!isImagePathLike(abs)) {
332
+ warnings.push(`[vision] skipped non-image path: ${cleaned}`);
333
+ continue;
334
+ }
335
+ const buf = await fs.readFile(abs).catch(() => null);
336
+ if (!buf) {
337
+ warnings.push(`[vision] failed to read: ${cleaned}`);
338
+ continue;
339
+ }
340
+ const mime = mimeForImagePath(abs);
341
+ const b64 = buf.toString('base64');
342
+ parts.push({ type: 'image_url', image_url: { url: `data:${mime};base64,${b64}` } });
343
+ imageCount++;
344
+ }
345
+ if (wantsClipboard) {
346
+ const clip = readClipboardImageDataUrl();
347
+ if (clip) {
348
+ parts.push({ type: 'image_url', image_url: { url: clip } });
349
+ imageCount++;
350
+ }
351
+ else {
352
+ warnings.push('[vision] clipboard image token detected, but no image was available from clipboard (tried wl-paste/xclip).');
353
+ }
354
+ }
355
+ if (imageCount === 0) {
356
+ return { content: text, warnings, imageCount: 0 };
357
+ }
358
+ return { content: parts, warnings, imageCount };
359
+ }
360
+ //# sourceMappingURL=input.js.map