@tangle-network/ui 11.6.0 → 11.8.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 (59) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +43 -0
  3. package/dist/chat.d.ts +18 -8
  4. package/dist/chat.js +9 -7
  5. package/dist/chunk-4CLN43XT.js +45 -0
  6. package/dist/{chunk-AZWDI2JG.js → chunk-565EATZZ.js} +1 -1
  7. package/dist/{chunk-XROQW5J7.js → chunk-BWOUSEHM.js} +1 -1
  8. package/dist/{chunk-J2G7KCYH.js → chunk-KNYSKNZX.js} +113 -69
  9. package/dist/chunk-L57WRIND.js +59 -0
  10. package/dist/{chunk-ULDNFLIM.js → chunk-ND3ZFXQK.js} +11 -58
  11. package/dist/{chunk-AAUNOHVL.js → chunk-NWECTSOH.js} +1 -1
  12. package/dist/{chunk-R5GVQDL3.js → chunk-OXZRCXJK.js} +9 -7
  13. package/dist/{chunk-XPYPZMYT.js → chunk-Q7ZR6LSD.js} +1 -1
  14. package/dist/{chunk-RKC3GXHE.js → chunk-X53RZSX6.js} +99 -104
  15. package/dist/{chunk-PLWRAS5Z.js → chunk-XGOWUDDW.js} +270 -106
  16. package/dist/{chunk-ZRVH3WCA.js → chunk-XU3HB5QL.js} +21 -1
  17. package/dist/chunk-YTO5V6QS.js +19 -0
  18. package/dist/files.d.ts +41 -12
  19. package/dist/files.js +13 -5
  20. package/dist/hooks.js +9 -7
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +37 -24
  23. package/dist/primitives.d.ts +15 -1
  24. package/dist/primitives.js +5 -1
  25. package/dist/run.d.ts +22 -17
  26. package/dist/run.js +11 -8
  27. package/dist/sdk-hooks.js +9 -7
  28. package/dist/tool-previews.js +2 -2
  29. package/dist/utils.d.ts +6 -0
  30. package/dist/utils.js +6 -4
  31. package/package.json +1 -1
  32. package/src/chat/agent-timeline.stories.tsx +163 -10
  33. package/src/chat/agent-timeline.test.tsx +114 -7
  34. package/src/chat/agent-timeline.tsx +120 -158
  35. package/src/chat/chat-container.test.tsx +59 -0
  36. package/src/chat/user-message.test.tsx +33 -0
  37. package/src/chat/user-message.tsx +13 -8
  38. package/src/files/file-artifact-pane.stories.tsx +149 -0
  39. package/src/files/file-artifact-pane.test.tsx +192 -0
  40. package/src/files/file-artifact-pane.tsx +6 -1
  41. package/src/files/file-format.ts +42 -4
  42. package/src/files/file-preview-kind.test.ts +109 -0
  43. package/src/files/file-preview.tsx +315 -132
  44. package/src/files/index.ts +8 -1
  45. package/src/primitives/index.ts +3 -0
  46. package/src/primitives/text-shimmer.test.tsx +34 -0
  47. package/src/primitives/text-shimmer.tsx +82 -0
  48. package/src/run/inline-thinking-item.stories.tsx +2 -2
  49. package/src/run/inline-thinking-item.tsx +2 -2
  50. package/src/run/inline-tool-item.test.tsx +76 -0
  51. package/src/run/inline-tool-item.tsx +9 -7
  52. package/src/run/run-group.tsx +4 -3
  53. package/src/run/run-row-shell.test.tsx +74 -4
  54. package/src/run/run-row-shell.tsx +81 -53
  55. package/src/run/tool-call-step.tsx +9 -7
  56. package/src/utils/tool-display.test.ts +53 -0
  57. package/src/utils/tool-display.ts +16 -15
  58. package/dist/chunk-LQS34IGP.js +0 -0
  59. /package/dist/{chunk-EJ5NBW7V.js → chunk-LDLOJKPC.js} +0 -0
@@ -0,0 +1,53 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import type { ToolPart } from "../types/parts";
3
+ import { getToolDisplayMetadata } from "./tool-display";
4
+
5
+ function part(tool: string, input: unknown): ToolPart {
6
+ return {
7
+ type: "tool",
8
+ id: `id-${tool}`,
9
+ tool,
10
+ state: { status: "completed", input },
11
+ };
12
+ }
13
+
14
+ describe("getToolDisplayMetadata", () => {
15
+ it.each([
16
+ ["read", { file_path: "/home/u/project/src/app.ts" }, "Read", "/home/u/project/src/app.ts"],
17
+ ["edit", { path: "src/app.ts" }, "Edit", "src/app.ts"],
18
+ ["write", { file: "src/new.ts" }, "Write", "src/new.ts"],
19
+ ["bash", { command: "pnpm test --run" }, "Shell", "pnpm test --run"],
20
+ ["grep", { pattern: "useCallback" }, "Search", "useCallback"],
21
+ ["glob", { pattern: "src/**/*.ts" }, "Find", "src/**/*.ts"],
22
+ ["web_search", { query: "vitest mocking" }, "Web search", "vitest mocking"],
23
+ ["web_fetch", { url: "https://vitest.dev" }, "Fetch", "https://vitest.dev"],
24
+ ["task", { description: "audit routes" }, "Task", "audit routes"],
25
+ ])("%s → bare verb title, subject in the description only", (tool, input, title, description) => {
26
+ const meta = getToolDisplayMetadata(part(tool, input));
27
+ expect(meta.title).toBe(title);
28
+ expect(meta.description).toBe(description);
29
+ expect(meta.title).not.toContain(description);
30
+ });
31
+
32
+ it("keeps the untruncated path and command for consumers that need them", () => {
33
+ const edit = getToolDisplayMetadata(part("edit", { file_path: "/a/b/c/d/e.ts" }));
34
+ expect(edit.targetPath).toBe("/a/b/c/d/e.ts");
35
+ expect(edit.diffFilePath).toBe("/a/b/c/d/e.ts");
36
+
37
+ const long = "x".repeat(80);
38
+ const shell = getToolDisplayMetadata(part("bash", { command: long }));
39
+ expect(shell.commandSnippet).toBe(long);
40
+ expect(shell.description).toHaveLength(60);
41
+ });
42
+
43
+ it("falls back to the verb alone when the input carries no subject", () => {
44
+ expect(getToolDisplayMetadata(part("read", {})).title).toBe("Read");
45
+ expect(getToolDisplayMetadata(part("read", {})).description).toBeUndefined();
46
+ });
47
+
48
+ it("names unknown tools by their tool name", () => {
49
+ const meta = getToolDisplayMetadata(part("custom_probe", { pattern: "p" }));
50
+ expect(meta.title).toBe("custom_probe");
51
+ expect(meta.description).toBe("p");
52
+ });
53
+ });
@@ -43,11 +43,6 @@ function extractFilePath(input: unknown): string | undefined {
43
43
  );
44
44
  }
45
45
 
46
- function cleanPath(path: string): string {
47
- const parts = path.split("/");
48
- return parts.length > 3 ? ".../" + parts.slice(-2).join("/") : path;
49
- }
50
-
51
46
  // ---------------------------------------------------------------------------
52
47
  // Category icons (emoji shorthand used by compact views)
53
48
  // ---------------------------------------------------------------------------
@@ -116,6 +111,12 @@ export function getToolCategory(toolName: string): ToolCategory {
116
111
  // Main metadata resolver
117
112
  // ---------------------------------------------------------------------------
118
113
 
114
+ /**
115
+ * Title is the bare verb ("Read", "Edit", "Shell"); the path, command, pattern
116
+ * or query lives in `description` only, so a row prints its subject once.
117
+ * `targetPath` / `commandSnippet` carry the untruncated value for consumers
118
+ * that need it (diff headers, expanded detail).
119
+ */
119
120
  export function getToolDisplayMetadata(part: ToolPart): ToolDisplayMetadata {
120
121
  const name = normalizeToolName(part.tool);
121
122
  const input = part.state.status !== "pending" ? part.state.input : undefined;
@@ -128,7 +129,7 @@ export function getToolDisplayMetadata(part: ToolPart): ToolDisplayMetadata {
128
129
  case "command":
129
130
  case "execute":
130
131
  return {
131
- title: "Run command",
132
+ title: "Shell",
132
133
  description: command ? truncateCommand(command) : undefined,
133
134
  displayVariant: "command",
134
135
  commandSnippet: command,
@@ -138,7 +139,7 @@ export function getToolDisplayMetadata(part: ToolPart): ToolDisplayMetadata {
138
139
  case "write_file":
139
140
  case "create_file":
140
141
  return {
141
- title: filePath ? `Write ${cleanPath(filePath)}` : "Write file",
142
+ title: "Write",
142
143
  description: filePath,
143
144
  displayVariant: "write-file",
144
145
  targetPath: filePath,
@@ -147,7 +148,7 @@ export function getToolDisplayMetadata(part: ToolPart): ToolDisplayMetadata {
147
148
  case "edit":
148
149
  case "patch":
149
150
  return {
150
- title: filePath ? `Edit ${cleanPath(filePath)}` : "Edit file",
151
+ title: "Edit",
151
152
  description: filePath,
152
153
  hasDiffOutput: true,
153
154
  diffFilePath: filePath,
@@ -159,7 +160,7 @@ export function getToolDisplayMetadata(part: ToolPart): ToolDisplayMetadata {
159
160
  case "read_file":
160
161
  case "cat":
161
162
  return {
162
- title: filePath ? `Read ${cleanPath(filePath)}` : "Read file",
163
+ title: "Read",
163
164
  description: filePath,
164
165
  displayVariant: "read-file",
165
166
  targetPath: filePath,
@@ -170,7 +171,7 @@ export function getToolDisplayMetadata(part: ToolPart): ToolDisplayMetadata {
170
171
  case "rg": {
171
172
  const pattern = extractString(input, "pattern");
172
173
  return {
173
- title: pattern ? `Search: ${pattern}` : "Search",
174
+ title: "Search",
174
175
  description: pattern,
175
176
  displayVariant: "grep",
176
177
  };
@@ -181,7 +182,7 @@ export function getToolDisplayMetadata(part: ToolPart): ToolDisplayMetadata {
181
182
  case "ls": {
182
183
  const pattern = extractString(input, "pattern");
183
184
  return {
184
- title: pattern ? `Find: ${pattern}` : "Find files",
185
+ title: "Find",
185
186
  description: pattern,
186
187
  displayVariant: "glob",
187
188
  };
@@ -193,8 +194,8 @@ export function getToolDisplayMetadata(part: ToolPart): ToolDisplayMetadata {
193
194
  const query =
194
195
  extractString(input, "query") ?? extractString(input, "url");
195
196
  return {
196
- title: query ? `Web: ${truncateCommand(query)}` : "Web search",
197
- description: query,
197
+ title: name === "web_search" ? "Web search" : "Fetch",
198
+ description: query ? truncateCommand(query) : undefined,
198
199
  displayVariant: "web-search",
199
200
  };
200
201
  }
@@ -206,8 +207,8 @@ export function getToolDisplayMetadata(part: ToolPart): ToolDisplayMetadata {
206
207
  extractString(input, "description") ??
207
208
  extractString(input, "prompt");
208
209
  return {
209
- title: desc ? `Task: ${truncateCommand(desc)}` : "Agent task",
210
- description: desc,
210
+ title: "Task",
211
+ description: desc ? truncateCommand(desc) : undefined,
211
212
  };
212
213
  }
213
214
 
File without changes
File without changes