@tangle-network/ui 11.16.0 → 11.16.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.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @tangle-network/ui
|
|
2
2
|
|
|
3
|
+
## 11.16.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c59ed11: `CommandPreview` prints a failed command's text once when the producer persisted it as both the output and the error.
|
|
8
|
+
|
|
9
|
+
It also reads a JSON string as a `{ stdout, stderr, exitCode }` envelope only when every key is an envelope key, so a command whose own output is JSON with a `stdout` field is shown as printed, and an `error` status turns the exit badge red even when the retained exit code is 0.
|
|
10
|
+
|
|
3
11
|
## 11.16.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
|
@@ -67,6 +67,20 @@ function fromObject(obj) {
|
|
|
67
67
|
exitCode: finiteNumber(obj.exitCode ?? obj.exit_code ?? obj.code)
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
|
+
/** The keys a serialized command result carries, and nothing else. */
|
|
71
|
+
const ENVELOPE_KEYS = /* @__PURE__ */ new Set([
|
|
72
|
+
"stdout",
|
|
73
|
+
"stderr",
|
|
74
|
+
"output",
|
|
75
|
+
"exitCode",
|
|
76
|
+
"exit_code",
|
|
77
|
+
"code",
|
|
78
|
+
"signal",
|
|
79
|
+
"durationMs",
|
|
80
|
+
"duration_ms",
|
|
81
|
+
"timedOut",
|
|
82
|
+
"timed_out"
|
|
83
|
+
]);
|
|
70
84
|
/** A string that is a serialized `{ stdout, stderr, exitCode }` record. */
|
|
71
85
|
function parseStructured(text) {
|
|
72
86
|
const trimmed = text.trimStart();
|
|
@@ -76,6 +90,7 @@ function parseStructured(text) {
|
|
|
76
90
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return;
|
|
77
91
|
const obj = parsed;
|
|
78
92
|
if (!("stdout" in obj) && !("stderr" in obj)) return void 0;
|
|
93
|
+
if (!Object.keys(obj).every((key) => ENVELOPE_KEYS.has(key))) return;
|
|
79
94
|
return fromObject(obj);
|
|
80
95
|
} catch {
|
|
81
96
|
return;
|
|
@@ -91,7 +106,7 @@ function ExitBadge({ exitCode, status }) {
|
|
|
91
106
|
"aria-hidden": "true"
|
|
92
107
|
}), "running"]
|
|
93
108
|
});
|
|
94
|
-
const failed = exitCode !== void 0
|
|
109
|
+
const failed = status === "error" || exitCode !== void 0 && exitCode !== 0;
|
|
95
110
|
const label = exitCode !== void 0 ? `exit ${exitCode}` : failed ? "error" : null;
|
|
96
111
|
if (label === null) return null;
|
|
97
112
|
return /* @__PURE__ */ jsx("span", {
|
|
@@ -113,7 +128,8 @@ const CommandPreview = memo(({ part, defaultExpanded = false, className }) => {
|
|
|
113
128
|
const command = commandOf(part.state.input);
|
|
114
129
|
const { status } = part.state;
|
|
115
130
|
const output = extractCommandOutput(part.state.output);
|
|
116
|
-
const
|
|
131
|
+
const normalize = (text) => text.replace(/\s+/g, " ").trim();
|
|
132
|
+
const errorText = part.state.error !== void 0 && output.stdout.length > 0 && normalize(part.state.error) === normalize(output.stdout) ? void 0 : part.state.error;
|
|
117
133
|
const hasBody = output.stdout.length > 0 || output.stderr.length > 0 || errorText !== void 0 && errorText.length > 0;
|
|
118
134
|
const promptLine = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
119
135
|
/* @__PURE__ */ jsx("span", {
|
package/package.json
CHANGED
|
@@ -79,6 +79,21 @@ function fromObject(obj: Record<string, unknown>): CommandOutput {
|
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
/** The keys a serialized command result carries, and nothing else. */
|
|
83
|
+
const ENVELOPE_KEYS = new Set([
|
|
84
|
+
"stdout",
|
|
85
|
+
"stderr",
|
|
86
|
+
"output",
|
|
87
|
+
"exitCode",
|
|
88
|
+
"exit_code",
|
|
89
|
+
"code",
|
|
90
|
+
"signal",
|
|
91
|
+
"durationMs",
|
|
92
|
+
"duration_ms",
|
|
93
|
+
"timedOut",
|
|
94
|
+
"timed_out",
|
|
95
|
+
]);
|
|
96
|
+
|
|
82
97
|
/** A string that is a serialized `{ stdout, stderr, exitCode }` record. */
|
|
83
98
|
function parseStructured(text: string): CommandOutput | undefined {
|
|
84
99
|
const trimmed = text.trimStart();
|
|
@@ -89,7 +104,13 @@ function parseStructured(text: string): CommandOutput | undefined {
|
|
|
89
104
|
return undefined;
|
|
90
105
|
}
|
|
91
106
|
const obj = parsed as Record<string, unknown>;
|
|
107
|
+
// Only an unambiguous envelope: a stream key, and nothing but envelope keys.
|
|
108
|
+
// A command whose own stdout is JSON that happens to have a `stdout` field
|
|
109
|
+
// (`{"stdout":"v","result":"ok"}`) is shown as the text it printed.
|
|
92
110
|
if (!("stdout" in obj) && !("stderr" in obj)) return undefined;
|
|
111
|
+
if (!Object.keys(obj).every((key) => ENVELOPE_KEYS.has(key))) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
93
114
|
return fromObject(obj);
|
|
94
115
|
} catch {
|
|
95
116
|
return undefined;
|
|
@@ -113,7 +134,9 @@ function ExitBadge({
|
|
|
113
134
|
</span>
|
|
114
135
|
);
|
|
115
136
|
}
|
|
116
|
-
|
|
137
|
+
// The tool's own error status wins: a runner can fail after the shell exited
|
|
138
|
+
// 0, and a green "exit 0" beside that error would contradict it.
|
|
139
|
+
const failed = status === "error" || (exitCode !== undefined && exitCode !== 0);
|
|
117
140
|
const label =
|
|
118
141
|
exitCode !== undefined ? `exit ${exitCode}` : failed ? "error" : null;
|
|
119
142
|
if (label === null) return null;
|
|
@@ -146,7 +169,16 @@ export const CommandPreview = memo(
|
|
|
146
169
|
const command = commandOf(part.state.input);
|
|
147
170
|
const { status } = part.state;
|
|
148
171
|
const output = extractCommandOutput(part.state.output);
|
|
149
|
-
|
|
172
|
+
// A failed call often persists the same text twice — as its output and as
|
|
173
|
+
// its error. Print it once. Only an exact repeat (ignoring whitespace) is
|
|
174
|
+
// folded: an error that merely CONTAINS the output, or the reverse, is a
|
|
175
|
+
// distinct message and keeps its own region.
|
|
176
|
+
const normalize = (text: string) => text.replace(/\s+/g, " ").trim();
|
|
177
|
+
const errorRepeats =
|
|
178
|
+
part.state.error !== undefined &&
|
|
179
|
+
output.stdout.length > 0 &&
|
|
180
|
+
normalize(part.state.error) === normalize(output.stdout);
|
|
181
|
+
const errorText = errorRepeats ? undefined : part.state.error;
|
|
150
182
|
const hasBody =
|
|
151
183
|
output.stdout.length > 0 ||
|
|
152
184
|
output.stderr.length > 0 ||
|