@tangle-network/ui 11.16.4 → 11.16.6
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 +12 -0
- package/dist/openui/schema-compiled.js +108 -209
- package/dist/openui/schema-data.js +0 -1
- package/dist/openui-schema.js +4 -0
- package/dist/primitives/status-pill.d.ts +2 -2
- package/dist/primitives/status-pill.js +5 -11
- package/dist/tool-previews/command-preview.d.ts +3 -1
- package/dist/tool-previews/command-preview.js +58 -13
- package/package.json +2 -2
- package/src/openui/schema-compiled.ts +1 -1
- package/src/openui/schema-data.ts +5 -1
- package/src/openui/schema.test.tsx +45 -0
- package/src/openui/schema.ts +5 -0
- package/src/primitives/status-pill.tsx +6 -7
- package/src/tool-previews/command-preview.test.tsx +73 -0
- package/src/tool-previews/command-preview.tsx +88 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @tangle-network/ui
|
|
2
2
|
|
|
3
|
+
## 11.16.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 74fbea5: A closed terminal command is a quiet bordered row on the surface it sits on, and turns into the dark terminal only when opened, so a list of commands no longer reads as a stack of black bars. Red is kept for evidence the command failed: a nonzero exit, a timeout or a signal. A tool that reported an error with nothing recorded about the command shows a neutral "tool error" badge. A command wraps between its tokens, so `--short` is no longer split at its hyphen; a token wider than the line still breaks, and the copied text is unchanged. The status pill marks a failed state with a cross instead of a slashed disc, which read as "disabled".
|
|
8
|
+
|
|
9
|
+
## 11.16.5
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 44ce397: Let model tool-schema converters accept the OpenUI node schema: container `children` no longer declares a nonempty minimum, which formed a required recursive loop that opencode rejected for `render_ui`. The persistence gate still rejects an empty stack, grid, or card children list.
|
|
14
|
+
|
|
3
15
|
## 11.16.4
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -1592,7 +1592,6 @@ const schema33 = {
|
|
|
1592
1592
|
"wrap": { "type": "boolean" },
|
|
1593
1593
|
"children": {
|
|
1594
1594
|
"type": "array",
|
|
1595
|
-
"minItems": 1,
|
|
1596
1595
|
"items": { "$ref": "#/$defs/node" }
|
|
1597
1596
|
}
|
|
1598
1597
|
},
|
|
@@ -1807,7 +1806,6 @@ const schema46 = {
|
|
|
1807
1806
|
] },
|
|
1808
1807
|
"children": {
|
|
1809
1808
|
"type": "array",
|
|
1810
|
-
"minItems": 1,
|
|
1811
1809
|
"items": { "$ref": "#/$defs/node" }
|
|
1812
1810
|
}
|
|
1813
1811
|
},
|
|
@@ -1909,30 +1907,19 @@ function validate27(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
1909
1907
|
const _errs7 = errors;
|
|
1910
1908
|
if (errors === _errs7) {
|
|
1911
1909
|
if (Array.isArray(data4)) {
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
for (let i0 = 0; i0 < len0; i0++) {
|
|
1924
|
-
const _errs9 = errors;
|
|
1925
|
-
if (!wrapper1.validate(data4[i0], {
|
|
1926
|
-
instancePath: instancePath + "/children/" + i0,
|
|
1927
|
-
parentData: data4,
|
|
1928
|
-
parentDataProperty: i0,
|
|
1929
|
-
rootData
|
|
1930
|
-
})) {
|
|
1931
|
-
vErrors = vErrors === null ? wrapper1.validate.errors : vErrors.concat(wrapper1.validate.errors);
|
|
1932
|
-
errors = vErrors.length;
|
|
1933
|
-
}
|
|
1934
|
-
if (!(_errs9 === errors)) break;
|
|
1910
|
+
const len0 = data4.length;
|
|
1911
|
+
for (let i0 = 0; i0 < len0; i0++) {
|
|
1912
|
+
const _errs9 = errors;
|
|
1913
|
+
if (!wrapper1.validate(data4[i0], {
|
|
1914
|
+
instancePath: instancePath + "/children/" + i0,
|
|
1915
|
+
parentData: data4,
|
|
1916
|
+
parentDataProperty: i0,
|
|
1917
|
+
rootData
|
|
1918
|
+
})) {
|
|
1919
|
+
vErrors = vErrors === null ? wrapper1.validate.errors : vErrors.concat(wrapper1.validate.errors);
|
|
1920
|
+
errors = vErrors.length;
|
|
1935
1921
|
}
|
|
1922
|
+
if (!(_errs9 === errors)) break;
|
|
1936
1923
|
}
|
|
1937
1924
|
} else {
|
|
1938
1925
|
validate27.errors = [{
|
|
@@ -2319,30 +2306,19 @@ function validate29(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
2319
2306
|
const _errs34 = errors;
|
|
2320
2307
|
if (errors === _errs34) {
|
|
2321
2308
|
if (Array.isArray(data16)) {
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
for (let i1 = 0; i1 < len1; i1++) {
|
|
2334
|
-
const _errs36 = errors;
|
|
2335
|
-
if (!wrapper1.validate(data16[i1], {
|
|
2336
|
-
instancePath: instancePath + "/children/" + i1,
|
|
2337
|
-
parentData: data16,
|
|
2338
|
-
parentDataProperty: i1,
|
|
2339
|
-
rootData
|
|
2340
|
-
})) {
|
|
2341
|
-
vErrors = vErrors === null ? wrapper1.validate.errors : vErrors.concat(wrapper1.validate.errors);
|
|
2342
|
-
errors = vErrors.length;
|
|
2343
|
-
}
|
|
2344
|
-
if (!(_errs36 === errors)) break;
|
|
2309
|
+
const len1 = data16.length;
|
|
2310
|
+
for (let i1 = 0; i1 < len1; i1++) {
|
|
2311
|
+
const _errs36 = errors;
|
|
2312
|
+
if (!wrapper1.validate(data16[i1], {
|
|
2313
|
+
instancePath: instancePath + "/children/" + i1,
|
|
2314
|
+
parentData: data16,
|
|
2315
|
+
parentDataProperty: i1,
|
|
2316
|
+
rootData
|
|
2317
|
+
})) {
|
|
2318
|
+
vErrors = vErrors === null ? wrapper1.validate.errors : vErrors.concat(wrapper1.validate.errors);
|
|
2319
|
+
errors = vErrors.length;
|
|
2345
2320
|
}
|
|
2321
|
+
if (!(_errs36 === errors)) break;
|
|
2346
2322
|
}
|
|
2347
2323
|
} else {
|
|
2348
2324
|
validate29.errors = [{
|
|
@@ -4139,30 +4115,19 @@ function validate23(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
4139
4115
|
const _errs10 = errors;
|
|
4140
4116
|
if (errors === _errs10) {
|
|
4141
4117
|
if (Array.isArray(data6)) {
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
for (let i0 = 0; i0 < len0; i0++) {
|
|
4154
|
-
const _errs12 = errors;
|
|
4155
|
-
if (!validate24(data6[i0], {
|
|
4156
|
-
instancePath: instancePath + "/children/" + i0,
|
|
4157
|
-
parentData: data6,
|
|
4158
|
-
parentDataProperty: i0,
|
|
4159
|
-
rootData
|
|
4160
|
-
})) {
|
|
4161
|
-
vErrors = vErrors === null ? validate24.errors : vErrors.concat(validate24.errors);
|
|
4162
|
-
errors = vErrors.length;
|
|
4163
|
-
}
|
|
4164
|
-
if (!(_errs12 === errors)) break;
|
|
4118
|
+
const len0 = data6.length;
|
|
4119
|
+
for (let i0 = 0; i0 < len0; i0++) {
|
|
4120
|
+
const _errs12 = errors;
|
|
4121
|
+
if (!validate24(data6[i0], {
|
|
4122
|
+
instancePath: instancePath + "/children/" + i0,
|
|
4123
|
+
parentData: data6,
|
|
4124
|
+
parentDataProperty: i0,
|
|
4125
|
+
rootData
|
|
4126
|
+
})) {
|
|
4127
|
+
vErrors = vErrors === null ? validate24.errors : vErrors.concat(validate24.errors);
|
|
4128
|
+
errors = vErrors.length;
|
|
4165
4129
|
}
|
|
4130
|
+
if (!(_errs12 === errors)) break;
|
|
4166
4131
|
}
|
|
4167
4132
|
} else {
|
|
4168
4133
|
validate23.errors = [{
|
|
@@ -4532,30 +4497,19 @@ function validate38(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
4532
4497
|
const _errs10 = errors;
|
|
4533
4498
|
if (errors === _errs10) {
|
|
4534
4499
|
if (Array.isArray(data6)) {
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
for (let i0 = 0; i0 < len0; i0++) {
|
|
4547
|
-
const _errs12 = errors;
|
|
4548
|
-
if (!wrapper3.validate(data6[i0], {
|
|
4549
|
-
instancePath: instancePath + "/children/" + i0,
|
|
4550
|
-
parentData: data6,
|
|
4551
|
-
parentDataProperty: i0,
|
|
4552
|
-
rootData
|
|
4553
|
-
})) {
|
|
4554
|
-
vErrors = vErrors === null ? wrapper3.validate.errors : vErrors.concat(wrapper3.validate.errors);
|
|
4555
|
-
errors = vErrors.length;
|
|
4556
|
-
}
|
|
4557
|
-
if (!(_errs12 === errors)) break;
|
|
4500
|
+
const len0 = data6.length;
|
|
4501
|
+
for (let i0 = 0; i0 < len0; i0++) {
|
|
4502
|
+
const _errs12 = errors;
|
|
4503
|
+
if (!wrapper3.validate(data6[i0], {
|
|
4504
|
+
instancePath: instancePath + "/children/" + i0,
|
|
4505
|
+
parentData: data6,
|
|
4506
|
+
parentDataProperty: i0,
|
|
4507
|
+
rootData
|
|
4508
|
+
})) {
|
|
4509
|
+
vErrors = vErrors === null ? wrapper3.validate.errors : vErrors.concat(wrapper3.validate.errors);
|
|
4510
|
+
errors = vErrors.length;
|
|
4558
4511
|
}
|
|
4512
|
+
if (!(_errs12 === errors)) break;
|
|
4559
4513
|
}
|
|
4560
4514
|
} else {
|
|
4561
4515
|
validate38.errors = [{
|
|
@@ -4944,30 +4898,19 @@ function validate40(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
4944
4898
|
const _errs34 = errors;
|
|
4945
4899
|
if (errors === _errs34) {
|
|
4946
4900
|
if (Array.isArray(data16)) {
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
for (let i1 = 0; i1 < len1; i1++) {
|
|
4959
|
-
const _errs36 = errors;
|
|
4960
|
-
if (!wrapper3.validate(data16[i1], {
|
|
4961
|
-
instancePath: instancePath + "/children/" + i1,
|
|
4962
|
-
parentData: data16,
|
|
4963
|
-
parentDataProperty: i1,
|
|
4964
|
-
rootData
|
|
4965
|
-
})) {
|
|
4966
|
-
vErrors = vErrors === null ? wrapper3.validate.errors : vErrors.concat(wrapper3.validate.errors);
|
|
4967
|
-
errors = vErrors.length;
|
|
4968
|
-
}
|
|
4969
|
-
if (!(_errs36 === errors)) break;
|
|
4901
|
+
const len1 = data16.length;
|
|
4902
|
+
for (let i1 = 0; i1 < len1; i1++) {
|
|
4903
|
+
const _errs36 = errors;
|
|
4904
|
+
if (!wrapper3.validate(data16[i1], {
|
|
4905
|
+
instancePath: instancePath + "/children/" + i1,
|
|
4906
|
+
parentData: data16,
|
|
4907
|
+
parentDataProperty: i1,
|
|
4908
|
+
rootData
|
|
4909
|
+
})) {
|
|
4910
|
+
vErrors = vErrors === null ? wrapper3.validate.errors : vErrors.concat(wrapper3.validate.errors);
|
|
4911
|
+
errors = vErrors.length;
|
|
4970
4912
|
}
|
|
4913
|
+
if (!(_errs36 === errors)) break;
|
|
4971
4914
|
}
|
|
4972
4915
|
} else {
|
|
4973
4916
|
validate40.errors = [{
|
|
@@ -6733,30 +6676,19 @@ function validate34(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
6733
6676
|
const _errs7 = errors;
|
|
6734
6677
|
if (errors === _errs7) {
|
|
6735
6678
|
if (Array.isArray(data4)) {
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
for (let i0 = 0; i0 < len0; i0++) {
|
|
6748
|
-
const _errs9 = errors;
|
|
6749
|
-
if (!validate35(data4[i0], {
|
|
6750
|
-
instancePath: instancePath + "/children/" + i0,
|
|
6751
|
-
parentData: data4,
|
|
6752
|
-
parentDataProperty: i0,
|
|
6753
|
-
rootData
|
|
6754
|
-
})) {
|
|
6755
|
-
vErrors = vErrors === null ? validate35.errors : vErrors.concat(validate35.errors);
|
|
6756
|
-
errors = vErrors.length;
|
|
6757
|
-
}
|
|
6758
|
-
if (!(_errs9 === errors)) break;
|
|
6679
|
+
const len0 = data4.length;
|
|
6680
|
+
for (let i0 = 0; i0 < len0; i0++) {
|
|
6681
|
+
const _errs9 = errors;
|
|
6682
|
+
if (!validate35(data4[i0], {
|
|
6683
|
+
instancePath: instancePath + "/children/" + i0,
|
|
6684
|
+
parentData: data4,
|
|
6685
|
+
parentDataProperty: i0,
|
|
6686
|
+
rootData
|
|
6687
|
+
})) {
|
|
6688
|
+
vErrors = vErrors === null ? validate35.errors : vErrors.concat(validate35.errors);
|
|
6689
|
+
errors = vErrors.length;
|
|
6759
6690
|
}
|
|
6691
|
+
if (!(_errs9 === errors)) break;
|
|
6760
6692
|
}
|
|
6761
6693
|
} else {
|
|
6762
6694
|
validate34.errors = [{
|
|
@@ -7124,30 +7056,19 @@ function validate49(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
7124
7056
|
const _errs10 = errors;
|
|
7125
7057
|
if (errors === _errs10) {
|
|
7126
7058
|
if (Array.isArray(data6)) {
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7138
|
-
for (let i0 = 0; i0 < len0; i0++) {
|
|
7139
|
-
const _errs12 = errors;
|
|
7140
|
-
if (!wrapper6.validate(data6[i0], {
|
|
7141
|
-
instancePath: instancePath + "/children/" + i0,
|
|
7142
|
-
parentData: data6,
|
|
7143
|
-
parentDataProperty: i0,
|
|
7144
|
-
rootData
|
|
7145
|
-
})) {
|
|
7146
|
-
vErrors = vErrors === null ? wrapper6.validate.errors : vErrors.concat(wrapper6.validate.errors);
|
|
7147
|
-
errors = vErrors.length;
|
|
7148
|
-
}
|
|
7149
|
-
if (!(_errs12 === errors)) break;
|
|
7059
|
+
const len0 = data6.length;
|
|
7060
|
+
for (let i0 = 0; i0 < len0; i0++) {
|
|
7061
|
+
const _errs12 = errors;
|
|
7062
|
+
if (!wrapper6.validate(data6[i0], {
|
|
7063
|
+
instancePath: instancePath + "/children/" + i0,
|
|
7064
|
+
parentData: data6,
|
|
7065
|
+
parentDataProperty: i0,
|
|
7066
|
+
rootData
|
|
7067
|
+
})) {
|
|
7068
|
+
vErrors = vErrors === null ? wrapper6.validate.errors : vErrors.concat(wrapper6.validate.errors);
|
|
7069
|
+
errors = vErrors.length;
|
|
7150
7070
|
}
|
|
7071
|
+
if (!(_errs12 === errors)) break;
|
|
7151
7072
|
}
|
|
7152
7073
|
} else {
|
|
7153
7074
|
validate49.errors = [{
|
|
@@ -7279,30 +7200,19 @@ function validate51(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
7279
7200
|
const _errs7 = errors;
|
|
7280
7201
|
if (errors === _errs7) {
|
|
7281
7202
|
if (Array.isArray(data4)) {
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
for (let i0 = 0; i0 < len0; i0++) {
|
|
7294
|
-
const _errs9 = errors;
|
|
7295
|
-
if (!wrapper6.validate(data4[i0], {
|
|
7296
|
-
instancePath: instancePath + "/children/" + i0,
|
|
7297
|
-
parentData: data4,
|
|
7298
|
-
parentDataProperty: i0,
|
|
7299
|
-
rootData
|
|
7300
|
-
})) {
|
|
7301
|
-
vErrors = vErrors === null ? wrapper6.validate.errors : vErrors.concat(wrapper6.validate.errors);
|
|
7302
|
-
errors = vErrors.length;
|
|
7303
|
-
}
|
|
7304
|
-
if (!(_errs9 === errors)) break;
|
|
7203
|
+
const len0 = data4.length;
|
|
7204
|
+
for (let i0 = 0; i0 < len0; i0++) {
|
|
7205
|
+
const _errs9 = errors;
|
|
7206
|
+
if (!wrapper6.validate(data4[i0], {
|
|
7207
|
+
instancePath: instancePath + "/children/" + i0,
|
|
7208
|
+
parentData: data4,
|
|
7209
|
+
parentDataProperty: i0,
|
|
7210
|
+
rootData
|
|
7211
|
+
})) {
|
|
7212
|
+
vErrors = vErrors === null ? wrapper6.validate.errors : vErrors.concat(wrapper6.validate.errors);
|
|
7213
|
+
errors = vErrors.length;
|
|
7305
7214
|
}
|
|
7215
|
+
if (!(_errs9 === errors)) break;
|
|
7306
7216
|
}
|
|
7307
7217
|
} else {
|
|
7308
7218
|
validate51.errors = [{
|
|
@@ -9322,30 +9232,19 @@ function validate45(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
9322
9232
|
const _errs34 = errors;
|
|
9323
9233
|
if (errors === _errs34) {
|
|
9324
9234
|
if (Array.isArray(data16)) {
|
|
9325
|
-
|
|
9326
|
-
|
|
9327
|
-
|
|
9328
|
-
|
|
9329
|
-
|
|
9330
|
-
|
|
9331
|
-
|
|
9332
|
-
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
|
|
9336
|
-
for (let i1 = 0; i1 < len1; i1++) {
|
|
9337
|
-
const _errs36 = errors;
|
|
9338
|
-
if (!validate46(data16[i1], {
|
|
9339
|
-
instancePath: instancePath + "/children/" + i1,
|
|
9340
|
-
parentData: data16,
|
|
9341
|
-
parentDataProperty: i1,
|
|
9342
|
-
rootData
|
|
9343
|
-
})) {
|
|
9344
|
-
vErrors = vErrors === null ? validate46.errors : vErrors.concat(validate46.errors);
|
|
9345
|
-
errors = vErrors.length;
|
|
9346
|
-
}
|
|
9347
|
-
if (!(_errs36 === errors)) break;
|
|
9235
|
+
const len1 = data16.length;
|
|
9236
|
+
for (let i1 = 0; i1 < len1; i1++) {
|
|
9237
|
+
const _errs36 = errors;
|
|
9238
|
+
if (!validate46(data16[i1], {
|
|
9239
|
+
instancePath: instancePath + "/children/" + i1,
|
|
9240
|
+
parentData: data16,
|
|
9241
|
+
parentDataProperty: i1,
|
|
9242
|
+
rootData
|
|
9243
|
+
})) {
|
|
9244
|
+
vErrors = vErrors === null ? validate46.errors : vErrors.concat(validate46.errors);
|
|
9245
|
+
errors = vErrors.length;
|
|
9348
9246
|
}
|
|
9247
|
+
if (!(_errs36 === errors)) break;
|
|
9349
9248
|
}
|
|
9350
9249
|
} else {
|
|
9351
9250
|
validate45.errors = [{
|
package/dist/openui-schema.js
CHANGED
|
@@ -26,6 +26,10 @@ function findUnsupportedOpenUINode(value) {
|
|
|
26
26
|
message: `Unsupported OpenUI node type: ${String(record.type)}.`
|
|
27
27
|
};
|
|
28
28
|
if (record.type === "stack" || record.type === "grid" || record.type === "card") {
|
|
29
|
+
if (Array.isArray(record.children) && record.children.length === 0) return {
|
|
30
|
+
path: `${path}.children`,
|
|
31
|
+
message: "OpenUI containers need at least one child."
|
|
32
|
+
};
|
|
29
33
|
if (Array.isArray(record.children)) for (const [index, child] of record.children.entries()) {
|
|
30
34
|
const issue = visit(child, `${path}.children[${index}]`, depth + 1);
|
|
31
35
|
if (issue) return issue;
|
|
@@ -10,8 +10,8 @@ import * as React from "react";
|
|
|
10
10
|
* the tone's COLOUR, and the state's own LABEL as text.
|
|
11
11
|
*
|
|
12
12
|
* The glyphs are chosen to survive at 8px and to differ in outline rather than
|
|
13
|
-
* in fill: a ring reads as "still open", a solid disc as "settled", a
|
|
14
|
-
*
|
|
13
|
+
* in fill: a ring reads as "still open", a solid disc as "settled", a cross as
|
|
14
|
+
* "failed". Two states never share one silhouette.
|
|
15
15
|
*
|
|
16
16
|
* Each tone draws its fill, border and text from ONE matched token triple.
|
|
17
17
|
* That pairing is the whole point: a status colour is solved against its own
|
|
@@ -45,22 +45,16 @@ function ToneGlyph({ tone }) {
|
|
|
45
45
|
r: "3.25"
|
|
46
46
|
})
|
|
47
47
|
});
|
|
48
|
-
case "danger": return /* @__PURE__ */
|
|
48
|
+
case "danger": return /* @__PURE__ */ jsx("svg", {
|
|
49
49
|
...common,
|
|
50
50
|
"aria-hidden": "true",
|
|
51
51
|
fill: "none",
|
|
52
52
|
stroke: "currentColor",
|
|
53
|
-
strokeWidth: "1.
|
|
54
|
-
children:
|
|
55
|
-
|
|
56
|
-
cy: "4",
|
|
57
|
-
r: "3.1",
|
|
58
|
-
fill: "currentColor",
|
|
59
|
-
opacity: "0.35"
|
|
60
|
-
}), /* @__PURE__ */ jsx("path", {
|
|
61
|
-
d: "M1.9 6.1 6.1 1.9",
|
|
53
|
+
strokeWidth: "1.75",
|
|
54
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
55
|
+
d: "M1.5 1.5 6.5 6.5M6.5 1.5 1.5 6.5",
|
|
62
56
|
strokeLinecap: "round"
|
|
63
|
-
})
|
|
57
|
+
})
|
|
64
58
|
});
|
|
65
59
|
case "warning": return /* @__PURE__ */ jsx("svg", {
|
|
66
60
|
...common,
|
|
@@ -14,7 +14,9 @@ export interface CommandPreviewProps {
|
|
|
14
14
|
* One shell command as a terminal block: a `$ command` prompt line with its
|
|
15
15
|
* exit status, and stdout and stderr in separate regions below it.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
17
|
+
* Closed, a command is a quiet row on the surface it sits on: a list of
|
|
18
|
+
* commands should read as a list, not a stack of black bars. Opened, it is a
|
|
19
|
+
* dark terminal. It scopes the dark token set onto itself with
|
|
18
20
|
* `data-theme="dark"`, so stderr, the badges and the muted prompt keep the
|
|
19
21
|
* contrast they were designed with on a dark ground, in a light console too.
|
|
20
22
|
*/
|
|
@@ -61,10 +61,14 @@ function extractCommandOutput(output) {
|
|
|
61
61
|
}
|
|
62
62
|
function fromObject(obj) {
|
|
63
63
|
const text = (value) => value === void 0 || value === null ? "" : String(value);
|
|
64
|
+
const timedOut = obj.timedOut ?? obj.timed_out;
|
|
65
|
+
const signal = obj.signal;
|
|
64
66
|
return {
|
|
65
67
|
stdout: text(obj.stdout ?? obj.output),
|
|
66
68
|
stderr: text(obj.stderr),
|
|
67
|
-
exitCode: finiteNumber(obj.exitCode ?? obj.exit_code ?? obj.code)
|
|
69
|
+
exitCode: finiteNumber(obj.exitCode ?? obj.exit_code ?? obj.code),
|
|
70
|
+
...timedOut === true ? { timedOut: true } : {},
|
|
71
|
+
...typeof signal === "string" && signal.length > 0 ? { signal } : {}
|
|
68
72
|
};
|
|
69
73
|
}
|
|
70
74
|
/** The keys a serialized command result carries, and nothing else. */
|
|
@@ -96,9 +100,12 @@ function parseStructured(text) {
|
|
|
96
100
|
return;
|
|
97
101
|
}
|
|
98
102
|
}
|
|
99
|
-
/** Exit status as a badge
|
|
100
|
-
*
|
|
101
|
-
|
|
103
|
+
/** Exit status as a badge. Red only where the command itself is known to have
|
|
104
|
+
* failed: a nonzero exit, a timeout, or a signal. A tool that reported an
|
|
105
|
+
* error with nothing recorded about the command (no exit code, or exit 0
|
|
106
|
+
* from a runner that failed afterwards) gets a neutral badge; its error text
|
|
107
|
+
* prints below. A clean run stays quiet green. */
|
|
108
|
+
function ExitBadge({ output, status }) {
|
|
102
109
|
if (status === "running" || status === "pending") return /* @__PURE__ */ jsxs("span", {
|
|
103
110
|
className: "inline-flex shrink-0 items-center gap-1 text-[11px] text-muted-foreground",
|
|
104
111
|
children: [/* @__PURE__ */ jsx(Loader2, {
|
|
@@ -106,19 +113,53 @@ function ExitBadge({ exitCode, status }) {
|
|
|
106
113
|
"aria-hidden": "true"
|
|
107
114
|
}), "running"]
|
|
108
115
|
});
|
|
109
|
-
const
|
|
110
|
-
|
|
116
|
+
const { exitCode, timedOut, signal } = output;
|
|
117
|
+
let label;
|
|
118
|
+
let tone;
|
|
119
|
+
if (timedOut) {
|
|
120
|
+
label = "timed out";
|
|
121
|
+
tone = "danger";
|
|
122
|
+
} else if (signal) {
|
|
123
|
+
label = signal;
|
|
124
|
+
tone = "danger";
|
|
125
|
+
} else if (exitCode !== void 0 && exitCode !== 0) {
|
|
126
|
+
label = `exit ${exitCode}`;
|
|
127
|
+
tone = "danger";
|
|
128
|
+
} else if (status === "error") {
|
|
129
|
+
label = exitCode === 0 ? "exit 0 · tool error" : "tool error";
|
|
130
|
+
tone = "neutral";
|
|
131
|
+
} else {
|
|
132
|
+
label = exitCode === 0 ? "exit 0" : null;
|
|
133
|
+
tone = "success";
|
|
134
|
+
}
|
|
111
135
|
if (label === null) return null;
|
|
112
136
|
return /* @__PURE__ */ jsx("span", {
|
|
113
|
-
className: cn("inline-flex shrink-0 items-center rounded-full px-1.5 py-px text-[11px] font-medium tabular-nums",
|
|
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 === "neutral" && "border-[var(--surface-neutral-border)] bg-[var(--surface-neutral-bg)] text-[var(--surface-neutral-text)]"),
|
|
114
138
|
children: label
|
|
115
139
|
});
|
|
116
140
|
}
|
|
117
141
|
/**
|
|
142
|
+
* A command split at its whitespace, each token in an inline box. Browsers
|
|
143
|
+
* break after a hyphen, which split `--short` into `--` and `short` on a
|
|
144
|
+
* phone. A box moves to the next line whole, and breaks inside only when it
|
|
145
|
+
* is wider than the line (a full SHA). The text is unchanged, so a copy still
|
|
146
|
+
* pastes the exact command.
|
|
147
|
+
*/
|
|
148
|
+
function CommandText({ command, all }) {
|
|
149
|
+
const tokens = command.split(/(\s+)/);
|
|
150
|
+
const limit = all ? tokens.length : 128;
|
|
151
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [tokens.slice(0, limit).map((token, i) => token.length > 0 && !/\s/.test(token) ? /* @__PURE__ */ jsx("span", {
|
|
152
|
+
className: "inline-block max-w-full [overflow-wrap:anywhere]",
|
|
153
|
+
children: token
|
|
154
|
+
}, i) : token), limit < tokens.length ? tokens.slice(limit).join("") : null] });
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
118
157
|
* One shell command as a terminal block: a `$ command` prompt line with its
|
|
119
158
|
* exit status, and stdout and stderr in separate regions below it.
|
|
120
159
|
*
|
|
121
|
-
*
|
|
160
|
+
* Closed, a command is a quiet row on the surface it sits on: a list of
|
|
161
|
+
* commands should read as a list, not a stack of black bars. Opened, it is a
|
|
162
|
+
* dark terminal. It scopes the dark token set onto itself with
|
|
122
163
|
* `data-theme="dark"`, so stderr, the badges and the muted prompt keep the
|
|
123
164
|
* contrast they were designed with on a dark ground, in a light console too.
|
|
124
165
|
*/
|
|
@@ -139,23 +180,27 @@ const CommandPreview = memo(({ part, defaultExpanded = false, className }) => {
|
|
|
139
180
|
}),
|
|
140
181
|
/* @__PURE__ */ jsx("code", {
|
|
141
182
|
className: cn("min-w-0 flex-1 whitespace-pre-wrap [overflow-wrap:anywhere]", expanded ? "" : "line-clamp-2"),
|
|
142
|
-
children:
|
|
183
|
+
children: /* @__PURE__ */ jsx(CommandText, {
|
|
184
|
+
command,
|
|
185
|
+
all: expanded
|
|
186
|
+
})
|
|
143
187
|
}),
|
|
144
188
|
/* @__PURE__ */ jsx(ExitBadge, {
|
|
145
|
-
|
|
189
|
+
output,
|
|
146
190
|
status
|
|
147
191
|
})
|
|
148
192
|
] });
|
|
149
193
|
return /* @__PURE__ */ jsxs("div", {
|
|
150
|
-
"data-theme": "dark",
|
|
194
|
+
"data-theme": expanded ? "dark" : void 0,
|
|
151
195
|
"data-testid": "command-preview",
|
|
152
|
-
|
|
196
|
+
"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-border bg-transparent", className),
|
|
153
198
|
children: [hasBody ? /* @__PURE__ */ jsxs("button", {
|
|
154
199
|
type: "button",
|
|
155
200
|
onClick: () => setExpanded((value) => !value),
|
|
156
201
|
"aria-expanded": expanded,
|
|
157
202
|
"aria-controls": bodyId,
|
|
158
|
-
className: cn("flex w-full items-start gap-2 px-3 py-2 text-left transition-colors hover:bg-white/5", focusRing),
|
|
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),
|
|
159
204
|
children: [promptLine, expanded ? /* @__PURE__ */ jsx(ChevronDown, {
|
|
160
205
|
className: "mt-px h-3.5 w-3.5 shrink-0 text-muted-foreground",
|
|
161
206
|
"aria-hidden": "true"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/ui",
|
|
3
|
-
"version": "11.16.
|
|
3
|
+
"version": "11.16.6",
|
|
4
4
|
"description": "Generic React UI components for Tangle products — primitives, chat, run, files, editor, markdown.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
"peerDependencies": {
|
|
143
143
|
"@hocuspocus/provider": ">=2.15.0 <5.0.0",
|
|
144
144
|
"@nanostores/react": ">=0.8.4 <3.0.0",
|
|
145
|
-
"@tangle-network/brand": "^1.10.
|
|
145
|
+
"@tangle-network/brand": "^1.10.2",
|
|
146
146
|
"@tiptap/core": ">=3.20.4 <4.0.0",
|
|
147
147
|
"@tiptap/extension-collaboration": ">=3.20.4 <4.0.0",
|
|
148
148
|
"@tiptap/extension-collaboration-caret": ">=3.7.0 <4.0.0",
|