@spexcode/transcript-ui 0.7.0-next.8 → 0.7.0-next.9

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 (2) hide show
  1. package/dist/vocabulary.js +15 -3
  2. package/package.json +2 -2
@@ -3,6 +3,7 @@ export const defaultVocabulary = {
3
3
  Read: 'Read', NotebookRead: 'Read',
4
4
  Grep: 'Searched', Glob: 'Searched', WebSearch: 'Searched the web',
5
5
  Bash: 'Ran', BashOutput: 'Read output',
6
+ exec: 'Ran', shell: 'Ran', wait: 'Waited',
6
7
  Edit: 'Edited', MultiEdit: 'Edited', NotebookEdit: 'Edited',
7
8
  Write: 'Wrote',
8
9
  WebFetch: 'Fetched',
@@ -10,7 +11,7 @@ export const defaultVocabulary = {
10
11
  TodoWrite: 'Updated the plan',
11
12
  },
12
13
  quiet: new Set(['Read', 'NotebookRead', 'Grep', 'Glob', 'WebFetch', 'WebSearch']),
13
- targetKeys: ['file_path', 'filePath', 'path', 'notebook_path', 'pattern', 'query', 'command', 'cmd', 'url', 'description'],
14
+ targetKeys: ['file_path', 'filePath', 'path', 'notebook_path', 'pattern', 'query', 'command', 'cmd', 'url', 'cell_id', 'description'],
14
15
  };
15
16
  export function extendVocabulary(base, extra) {
16
17
  return {
@@ -47,6 +48,14 @@ export function prettyInput(input) {
47
48
  }
48
49
  }
49
50
  export const isQuietTool = (name, vocabulary = defaultVocabulary) => vocabulary.quiet.has(name);
51
+ // A command's or a script's head: its first non-empty line, clamped. A one-liner is itself; a multi-line
52
+ // script shows the line that names it, and the CSS ellipsis takes the rest.
53
+ function firstLine(text) {
54
+ const line = text.split(/\r?\n/).map((l) => l.trim()).find(Boolean);
55
+ if (!line)
56
+ return null;
57
+ return line.length <= 160 ? line : line.slice(0, 160);
58
+ }
50
59
  // The target, from the call's own arguments. `input` is the raw JSON of the arguments (or a bare string), so
51
60
  // this reads the field the tool actually names and shows NOTHING when it cannot — a wrong target is worse
52
61
  // than no target, and a truncated blob of JSON is not a target at all.
@@ -54,14 +63,17 @@ export function toolTarget(input, vocabulary = defaultVocabulary) {
54
63
  if (typeof input !== 'string' || !input)
55
64
  return null;
56
65
  let parsed = null;
66
+ // A tool whose input is a bare string is a command or a script (a codex `exec` cell, a shell one-liner). Its
67
+ // FIRST non-empty line names it — a wall of script has a head worth reading, and nothing is worse than a row
68
+ // that says only "exec". JSON is parsed for its named target below; a bare string is its own head.
57
69
  try {
58
70
  parsed = JSON.parse(input);
59
71
  }
60
72
  catch {
61
- return input.length <= 80 ? input : null;
73
+ return firstLine(input);
62
74
  }
63
75
  if (!parsed || typeof parsed !== 'object')
64
- return typeof parsed === 'string' ? parsed : null;
76
+ return typeof parsed === 'string' ? firstLine(parsed) : null;
65
77
  for (const key of vocabulary.targetKeys) {
66
78
  const value = parsed[key];
67
79
  if (typeof value === 'string' && value.trim())
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spexcode/transcript-ui",
3
- "version": "0.7.0-next.8",
3
+ "version": "0.7.0-next.9",
4
4
  "type": "module",
5
5
  "description": "React components that draw a normalized agent transcript — the person quoted, the agent as the page, a tool call as a sentence, the work folded behind its answer — with the fold, the prose renderer, the tool vocabulary, the labels and the design tokens all tunable.",
6
6
  "files": [
@@ -24,7 +24,7 @@
24
24
  "test": "npm run build && tsx --test src/*.test.tsx"
25
25
  },
26
26
  "dependencies": {
27
- "@spexcode/transcript": "0.7.0-next.8"
27
+ "@spexcode/transcript": "0.7.0-next.9"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "react": "^18.2.0 || ^19.0.0"