flashlite 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,62 @@
1
+ // Presentation only: bounded, sanitized result excerpts. Never change model history.
2
+ import { sanitizeCommandOutput } from "./terminal.js";
3
+ const MAX_LINE = 180;
4
+ const MAX_EXPANDED_LINES = 250;
5
+ export function toolResultView(name, content, isError, redactValues = []) {
6
+ const safe = sanitizeCommandOutput(content, redactValues);
7
+ const excerpt = (text, tail = false) => {
8
+ const lines = text.split(/\r?\n/).filter((line) => line.trim());
9
+ const selected = tail ? lines.slice(-MAX_EXPANDED_LINES) : lines.slice(0, MAX_EXPANDED_LINES);
10
+ const rows = selected.map((line) => line.length > MAX_LINE ? line.slice(0, MAX_LINE - 1) + '…' : line);
11
+ if (lines.length > MAX_EXPANDED_LINES) {
12
+ if (tail)
13
+ rows.unshift(`… (${lines.length - MAX_EXPANDED_LINES} earlier lines omitted; full result in session transcript)`);
14
+ else
15
+ rows.push('… remaining lines omitted; full result in session transcript');
16
+ }
17
+ return rows;
18
+ };
19
+ if (name === 'run_command') {
20
+ try {
21
+ const result = JSON.parse(safe);
22
+ if (typeof result.status === 'string') {
23
+ const stdout = typeof result.stdout === 'string' ? result.stdout : '';
24
+ const stderr = typeof result.stderr === 'string' ? result.stderr : '';
25
+ const output = [stdout, stderr].filter(Boolean).join('\n');
26
+ const lines = excerpt(output, true);
27
+ const summary = `${result.status}${typeof result.exit_code === 'number' ? ` · exit ${result.exit_code}` : ''}`;
28
+ return { summary: `${summary}${output ? ` · ${output.split('\n').filter(Boolean).length} output lines` : ''}`, lines };
29
+ }
30
+ }
31
+ catch { /* tool errors may be plain text */ }
32
+ }
33
+ if (name === 'read_file') {
34
+ let text = safe;
35
+ try {
36
+ const result = JSON.parse(safe);
37
+ if (typeof result.content === 'string')
38
+ text = result.content;
39
+ }
40
+ catch { /* small files are plain text */ }
41
+ if (!isError)
42
+ return { summary: `${text.length ? text.split('\n').length : 0} lines · ${Buffer.byteLength(text)} bytes`, lines: excerpt(text) };
43
+ }
44
+ if (name === 'read_files') {
45
+ try {
46
+ const files = JSON.parse(safe);
47
+ if (Array.isArray(files))
48
+ return {
49
+ summary: `${files.filter((file) => !file.error).length}/${files.length} files read`,
50
+ lines: files.slice(0, MAX_EXPANDED_LINES).map((file) => `${file.path ?? 'file'} · ${file.error ?? `${Buffer.byteLength(file.content ?? '')} bytes`}`),
51
+ };
52
+ }
53
+ catch { /* fall through */ }
54
+ }
55
+ if (name === 'grep' || name === 'find_files' || name === 'list_dir') {
56
+ const lines = excerpt(safe);
57
+ const count = safe.split('\n').filter((line) => line && !line.startsWith('…') && !line.startsWith('(no matches') && !line.startsWith('(empty')).length;
58
+ return { summary: `${count} ${name === 'grep' ? 'matches' : 'entries'}${safe.includes('partial') ? ' · partial' : ''}`, lines };
59
+ }
60
+ const lines = excerpt(safe);
61
+ return { summary: (lines[0] ?? (isError ? 'failed' : 'completed')).slice(0, MAX_LINE), lines };
62
+ }