@tangle-network/ui 11.16.6 → 11.16.8
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.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @tangle-network/ui
|
|
2
2
|
|
|
3
|
+
## 11.16.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c8ab512: A terminal command whose tool reported an error with nothing recorded about the command shows its "tool reported error" badge in the warning tone and sans type, so it reads as a status rather than metadata. Red stays reserved for a nonzero exit, a timeout or a signal.
|
|
8
|
+
|
|
9
|
+
## 11.16.7
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 083c632: A closed terminal command has no border, so it reads as the same kind of row as the other tool calls beside it. On a phone its exit badge takes its own line under the command, so the command keeps the row's width. A tool error with nothing recorded about the command reads "tool reported error", which states what is known.
|
|
14
|
+
|
|
3
15
|
## 11.16.6
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -103,7 +103,7 @@ function parseStructured(text) {
|
|
|
103
103
|
/** Exit status as a badge. Red only where the command itself is known to have
|
|
104
104
|
* failed: a nonzero exit, a timeout, or a signal. A tool that reported an
|
|
105
105
|
* error with nothing recorded about the command (no exit code, or exit 0
|
|
106
|
-
* from a runner that failed afterwards) gets
|
|
106
|
+
* from a runner that failed afterwards) gets an amber badge; its error text
|
|
107
107
|
* prints below. A clean run stays quiet green. */
|
|
108
108
|
function ExitBadge({ output, status }) {
|
|
109
109
|
if (status === "running" || status === "pending") return /* @__PURE__ */ jsxs("span", {
|
|
@@ -126,15 +126,15 @@ function ExitBadge({ output, status }) {
|
|
|
126
126
|
label = `exit ${exitCode}`;
|
|
127
127
|
tone = "danger";
|
|
128
128
|
} else if (status === "error") {
|
|
129
|
-
label = exitCode === 0 ? "exit 0 · tool error" : "tool error";
|
|
130
|
-
tone = "
|
|
129
|
+
label = exitCode === 0 ? "exit 0 · tool reported error" : "tool reported error";
|
|
130
|
+
tone = "warning";
|
|
131
131
|
} else {
|
|
132
132
|
label = exitCode === 0 ? "exit 0" : null;
|
|
133
133
|
tone = "success";
|
|
134
134
|
}
|
|
135
135
|
if (label === null) return null;
|
|
136
136
|
return /* @__PURE__ */ jsx("span", {
|
|
137
|
-
className: cn("inline-flex shrink-0 items-center rounded-full border px-1.5 py-px text-[11px] font-medium tabular-nums", tone === "danger" && "border-transparent bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]", tone === "success" && "border-transparent bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]", tone === "
|
|
137
|
+
className: cn("inline-flex shrink-0 items-center rounded-full border px-1.5 py-px font-sans text-[11px] font-medium tabular-nums", tone === "danger" && "border-transparent bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]", tone === "success" && "border-transparent bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]", tone === "warning" && "border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]"),
|
|
138
138
|
children: label
|
|
139
139
|
});
|
|
140
140
|
}
|
|
@@ -185,22 +185,25 @@ const CommandPreview = memo(({ part, defaultExpanded = false, className }) => {
|
|
|
185
185
|
all: expanded
|
|
186
186
|
})
|
|
187
187
|
}),
|
|
188
|
-
/* @__PURE__ */ jsx(
|
|
189
|
-
|
|
190
|
-
|
|
188
|
+
/* @__PURE__ */ jsx("span", {
|
|
189
|
+
className: "flex shrink-0 max-sm:order-last max-sm:basis-full max-sm:pl-4",
|
|
190
|
+
children: /* @__PURE__ */ jsx(ExitBadge, {
|
|
191
|
+
output,
|
|
192
|
+
status
|
|
193
|
+
})
|
|
191
194
|
})
|
|
192
195
|
] });
|
|
193
196
|
return /* @__PURE__ */ jsxs("div", {
|
|
194
197
|
"data-theme": expanded ? "dark" : void 0,
|
|
195
198
|
"data-testid": "command-preview",
|
|
196
199
|
"data-expanded": expanded,
|
|
197
|
-
className: cn("overflow-hidden rounded-[var(--radius-md)] border font-mono text-xs text-foreground", expanded ? "border-[var(--md3-surface-container-lowest)] bg-[var(--md3-surface-container-lowest)]" : "border-
|
|
200
|
+
className: cn("overflow-hidden rounded-[var(--radius-md)] border font-mono text-xs text-foreground", expanded ? "border-[var(--md3-surface-container-lowest)] bg-[var(--md3-surface-container-lowest)]" : "border-transparent bg-transparent", className),
|
|
198
201
|
children: [hasBody ? /* @__PURE__ */ jsxs("button", {
|
|
199
202
|
type: "button",
|
|
200
203
|
onClick: () => setExpanded((value) => !value),
|
|
201
204
|
"aria-expanded": expanded,
|
|
202
205
|
"aria-controls": bodyId,
|
|
203
|
-
className: cn("flex w-full items-start gap-2 px-3 py-2 text-left transition-colors", expanded ? "hover:bg-white/5" : "hover:bg-muted", focusRing),
|
|
206
|
+
className: cn("flex w-full flex-wrap items-start gap-x-2 gap-y-1 px-3 py-2 text-left transition-colors sm:flex-nowrap", expanded ? "hover:bg-white/5" : "hover:bg-muted", focusRing),
|
|
204
207
|
children: [promptLine, expanded ? /* @__PURE__ */ jsx(ChevronDown, {
|
|
205
208
|
className: "mt-px h-3.5 w-3.5 shrink-0 text-muted-foreground",
|
|
206
209
|
"aria-hidden": "true"
|
|
@@ -209,7 +212,7 @@ const CommandPreview = memo(({ part, defaultExpanded = false, className }) => {
|
|
|
209
212
|
"aria-hidden": "true"
|
|
210
213
|
})]
|
|
211
214
|
}) : /* @__PURE__ */ jsx("div", {
|
|
212
|
-
className: "flex w-full items-start gap-2 px-3 py-2",
|
|
215
|
+
className: "flex w-full flex-wrap items-start gap-x-2 gap-y-1 px-3 py-2 sm:flex-nowrap",
|
|
213
216
|
children: promptLine
|
|
214
217
|
}), expanded && hasBody ? /* @__PURE__ */ jsxs("div", {
|
|
215
218
|
id: bodyId,
|
package/package.json
CHANGED
|
@@ -13,10 +13,10 @@ function part(state: Partial<ToolPart["state"]>): ToolPart {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
describe("CommandPreview", () => {
|
|
16
|
-
it("shows
|
|
16
|
+
it("shows an amber badge, not a red exit, when a tool errored without an exit code", () => {
|
|
17
17
|
render(<CommandPreview part={part({ status: "error", output: "warning: x" })} />);
|
|
18
|
-
const badge = screen.getByText("tool error");
|
|
19
|
-
expect(badge.className).toContain("surface-
|
|
18
|
+
const badge = screen.getByText("tool reported error");
|
|
19
|
+
expect(badge.className).toContain("surface-warning");
|
|
20
20
|
expect(badge.className).not.toContain("surface-danger");
|
|
21
21
|
expect(screen.queryByText("error")).toBeNull();
|
|
22
22
|
});
|
|
@@ -52,13 +52,13 @@ describe("CommandPreview", () => {
|
|
|
52
52
|
expect(screen.getByText("timed out").className).toContain("surface-danger");
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
it("keeps a runner error after a clean exit
|
|
55
|
+
it("keeps a runner error after a clean exit amber, not red", () => {
|
|
56
56
|
render(
|
|
57
57
|
<CommandPreview
|
|
58
58
|
part={part({ status: "error", output: { stdout: "ok", stderr: "", exitCode: 0 } })}
|
|
59
59
|
/>,
|
|
60
60
|
);
|
|
61
|
-
expect(screen.getByText("exit 0 · tool error").className).toContain("surface-
|
|
61
|
+
expect(screen.getByText("exit 0 · tool reported error").className).toContain("surface-warning");
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
it("is a quiet row until opened, then a dark terminal", () => {
|
|
@@ -128,7 +128,7 @@ function parseStructured(text: string): CommandOutput | undefined {
|
|
|
128
128
|
/** Exit status as a badge. Red only where the command itself is known to have
|
|
129
129
|
* failed: a nonzero exit, a timeout, or a signal. A tool that reported an
|
|
130
130
|
* error with nothing recorded about the command (no exit code, or exit 0
|
|
131
|
-
* from a runner that failed afterwards) gets
|
|
131
|
+
* from a runner that failed afterwards) gets an amber badge; its error text
|
|
132
132
|
* prints below. A clean run stays quiet green. */
|
|
133
133
|
function ExitBadge({
|
|
134
134
|
output,
|
|
@@ -147,7 +147,7 @@ function ExitBadge({
|
|
|
147
147
|
}
|
|
148
148
|
const { exitCode, timedOut, signal } = output;
|
|
149
149
|
let label: string | null;
|
|
150
|
-
let tone: "danger" | "success" | "
|
|
150
|
+
let tone: "danger" | "success" | "warning";
|
|
151
151
|
if (timedOut) {
|
|
152
152
|
label = "timed out";
|
|
153
153
|
tone = "danger";
|
|
@@ -158,8 +158,10 @@ function ExitBadge({
|
|
|
158
158
|
label = `exit ${exitCode}`;
|
|
159
159
|
tone = "danger";
|
|
160
160
|
} else if (status === "error") {
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
// Say what is known: the tool reported an error. Nothing recorded says
|
|
162
|
+
// the command itself failed.
|
|
163
|
+
label = exitCode === 0 ? "exit 0 · tool reported error" : "tool reported error";
|
|
164
|
+
tone = "warning";
|
|
163
165
|
} else {
|
|
164
166
|
label = exitCode === 0 ? "exit 0" : null;
|
|
165
167
|
tone = "success";
|
|
@@ -169,13 +171,15 @@ function ExitBadge({
|
|
|
169
171
|
<span
|
|
170
172
|
className={cn(
|
|
171
173
|
// Every badge has a border, so mixed rows keep one height.
|
|
172
|
-
"inline-flex shrink-0 items-center rounded-full border px-1.5 py-px text-[11px] font-medium tabular-nums",
|
|
174
|
+
"inline-flex shrink-0 items-center rounded-full border px-1.5 py-px font-sans text-[11px] font-medium tabular-nums",
|
|
173
175
|
tone === "danger" &&
|
|
174
176
|
"border-transparent bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]",
|
|
175
177
|
tone === "success" &&
|
|
176
178
|
"border-transparent bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]",
|
|
177
|
-
|
|
178
|
-
|
|
179
|
+
// A reported error with nothing recorded about the command deserves
|
|
180
|
+
// attention, but it is not a failed command: amber, not red.
|
|
181
|
+
tone === "warning" &&
|
|
182
|
+
"border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]",
|
|
179
183
|
)}
|
|
180
184
|
>
|
|
181
185
|
{label}
|
|
@@ -259,7 +263,11 @@ export const CommandPreview = memo(
|
|
|
259
263
|
>
|
|
260
264
|
<CommandText command={command} all={expanded} />
|
|
261
265
|
</code>
|
|
262
|
-
|
|
266
|
+
{/* On a phone the badge takes its own line under the command, so the
|
|
267
|
+
command keeps the row's width. */}
|
|
268
|
+
<span className="flex shrink-0 max-sm:order-last max-sm:basis-full max-sm:pl-4">
|
|
269
|
+
<ExitBadge output={output} status={status} />
|
|
270
|
+
</span>
|
|
263
271
|
</>
|
|
264
272
|
);
|
|
265
273
|
|
|
@@ -274,7 +282,7 @@ export const CommandPreview = memo(
|
|
|
274
282
|
"overflow-hidden rounded-[var(--radius-md)] border font-mono text-xs text-foreground",
|
|
275
283
|
expanded
|
|
276
284
|
? "border-[var(--md3-surface-container-lowest)] bg-[var(--md3-surface-container-lowest)]"
|
|
277
|
-
: "border-
|
|
285
|
+
: "border-transparent bg-transparent",
|
|
278
286
|
className,
|
|
279
287
|
)}
|
|
280
288
|
>
|
|
@@ -285,7 +293,7 @@ export const CommandPreview = memo(
|
|
|
285
293
|
aria-expanded={expanded}
|
|
286
294
|
aria-controls={bodyId}
|
|
287
295
|
className={cn(
|
|
288
|
-
"flex w-full items-start gap-2 px-3 py-2 text-left transition-colors",
|
|
296
|
+
"flex w-full flex-wrap items-start gap-x-2 gap-y-1 px-3 py-2 text-left transition-colors sm:flex-nowrap",
|
|
289
297
|
expanded ? "hover:bg-white/5" : "hover:bg-muted",
|
|
290
298
|
focusRing,
|
|
291
299
|
)}
|
|
@@ -298,7 +306,9 @@ export const CommandPreview = memo(
|
|
|
298
306
|
)}
|
|
299
307
|
</button>
|
|
300
308
|
) : (
|
|
301
|
-
<div className="flex w-full items-start gap-2 px-3 py-2">
|
|
309
|
+
<div className="flex w-full flex-wrap items-start gap-x-2 gap-y-1 px-3 py-2 sm:flex-nowrap">
|
|
310
|
+
{promptLine}
|
|
311
|
+
</div>
|
|
302
312
|
)}
|
|
303
313
|
|
|
304
314
|
{expanded && hasBody ? (
|