@huanlin/dsh-plugin-merge-tool-calls 0.2.2 → 0.4.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.
- package/README.md +97 -94
- package/lib/client.js +2051 -1637
- package/lib/client.js.map +1 -1
- package/lib/types/client/card-model.d.ts +77 -77
- package/lib/types/client/dictionaries.d.ts +22 -15
- package/lib/types/client/index.d.ts +29 -29
- package/lib/types/client/locales.d.ts +103 -57
- package/lib/types/client/merge-run.d.ts +49 -46
- package/lib/types/client/rows.d.ts +77 -73
- package/package.json +15 -22
- package/lib/invariant.js +0 -11
- package/lib/types/invariant.d.ts +0 -12
package/lib/client.js
CHANGED
|
@@ -1,1638 +1,2052 @@
|
|
|
1
|
-
window.__ModuleLoader__.load({ id: "@huanlin/dsh-plugin-merge-tool-calls", factory: (require) => {
|
|
2
|
-
var module = { exports: {} }; var exports = module.exports;
|
|
3
|
-
//#region rolldown:runtime
|
|
4
|
-
var __create = Object.create;
|
|
5
|
-
var __defProp = Object.defineProperty;
|
|
6
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
-
key = keys[i];
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
14
|
-
get: ((k) => from[k]).bind(null, key),
|
|
15
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
21
|
-
value: mod,
|
|
22
|
-
enumerable: true
|
|
23
|
-
}) : target, mod));
|
|
24
|
-
|
|
25
|
-
//#endregion
|
|
26
|
-
let react = require("react");
|
|
27
|
-
react = __toESM(react);
|
|
28
|
-
let __deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
29
|
-
__deepseek_ai_dsh_client_ui_primitives = __toESM(__deepseek_ai_dsh_client_ui_primitives);
|
|
30
|
-
let
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
"terminal.
|
|
62
|
-
"terminal.
|
|
63
|
-
"terminal.
|
|
64
|
-
"terminal.
|
|
65
|
-
"terminal.
|
|
66
|
-
"terminal.
|
|
67
|
-
"terminal.
|
|
68
|
-
"terminal.
|
|
69
|
-
"terminal.
|
|
70
|
-
"terminal.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
"terminal.
|
|
89
|
-
"terminal.
|
|
90
|
-
"terminal.
|
|
91
|
-
"terminal.
|
|
92
|
-
"terminal.
|
|
93
|
-
"terminal.
|
|
94
|
-
"terminal.
|
|
95
|
-
"terminal.
|
|
96
|
-
"terminal.
|
|
97
|
-
"terminal.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
"terminal.
|
|
116
|
-
"terminal.
|
|
117
|
-
"terminal.
|
|
118
|
-
"terminal.
|
|
119
|
-
"terminal.
|
|
120
|
-
"terminal.
|
|
121
|
-
"terminal.
|
|
122
|
-
"terminal.
|
|
123
|
-
"terminal.
|
|
124
|
-
"terminal.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
"terminal.
|
|
143
|
-
"terminal.
|
|
144
|
-
"terminal.
|
|
145
|
-
"terminal.
|
|
146
|
-
"terminal.
|
|
147
|
-
"terminal.
|
|
148
|
-
"terminal.
|
|
149
|
-
"terminal.
|
|
150
|
-
"terminal.
|
|
151
|
-
"terminal.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
"terminal.
|
|
170
|
-
"terminal.
|
|
171
|
-
"terminal.
|
|
172
|
-
"terminal.
|
|
173
|
-
"terminal.
|
|
174
|
-
"terminal.
|
|
175
|
-
"terminal.
|
|
176
|
-
"terminal.
|
|
177
|
-
"terminal.
|
|
178
|
-
"terminal.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
"terminal.
|
|
197
|
-
"terminal.
|
|
198
|
-
"terminal.
|
|
199
|
-
"terminal.
|
|
200
|
-
"terminal.
|
|
201
|
-
"terminal.
|
|
202
|
-
"terminal.
|
|
203
|
-
"terminal.
|
|
204
|
-
"terminal.
|
|
205
|
-
"terminal.
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
"terminal.
|
|
224
|
-
"terminal.
|
|
225
|
-
"terminal.
|
|
226
|
-
"terminal.
|
|
227
|
-
"terminal.
|
|
228
|
-
"terminal.
|
|
229
|
-
"terminal.
|
|
230
|
-
"terminal.
|
|
231
|
-
"terminal.
|
|
232
|
-
"terminal.
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
"terminal.
|
|
251
|
-
"terminal.
|
|
252
|
-
"terminal.
|
|
253
|
-
"terminal.
|
|
254
|
-
"terminal.
|
|
255
|
-
"terminal.
|
|
256
|
-
"terminal.
|
|
257
|
-
"terminal.
|
|
258
|
-
"terminal.
|
|
259
|
-
"terminal.
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
"terminal.
|
|
278
|
-
"terminal.
|
|
279
|
-
"terminal.
|
|
280
|
-
"terminal.
|
|
281
|
-
"terminal.
|
|
282
|
-
"terminal.
|
|
283
|
-
"terminal.
|
|
284
|
-
"terminal.
|
|
285
|
-
"terminal.
|
|
286
|
-
"terminal.
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
"terminal.
|
|
305
|
-
"terminal.
|
|
306
|
-
"terminal.
|
|
307
|
-
"terminal.
|
|
308
|
-
"terminal.
|
|
309
|
-
"terminal.
|
|
310
|
-
"terminal.
|
|
311
|
-
"terminal.
|
|
312
|
-
"terminal.
|
|
313
|
-
"terminal.
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
"terminal.
|
|
332
|
-
"terminal.
|
|
333
|
-
"terminal.
|
|
334
|
-
"terminal.
|
|
335
|
-
"terminal.
|
|
336
|
-
"terminal.
|
|
337
|
-
"terminal.
|
|
338
|
-
"terminal.
|
|
339
|
-
"terminal.
|
|
340
|
-
"terminal.
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
"terminal.
|
|
359
|
-
"terminal.
|
|
360
|
-
"terminal.
|
|
361
|
-
"terminal.
|
|
362
|
-
"terminal.
|
|
363
|
-
"terminal.
|
|
364
|
-
"terminal.
|
|
365
|
-
"terminal.
|
|
366
|
-
"terminal.
|
|
367
|
-
"terminal.
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
"terminal.
|
|
386
|
-
"terminal.
|
|
387
|
-
"terminal.
|
|
388
|
-
"terminal.
|
|
389
|
-
"terminal.
|
|
390
|
-
"terminal.
|
|
391
|
-
"terminal.
|
|
392
|
-
"terminal.
|
|
393
|
-
"terminal.
|
|
394
|
-
"terminal.
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
"terminal.
|
|
413
|
-
"terminal.
|
|
414
|
-
"terminal.
|
|
415
|
-
"terminal.
|
|
416
|
-
"terminal.
|
|
417
|
-
"terminal.
|
|
418
|
-
"terminal.
|
|
419
|
-
"terminal.
|
|
420
|
-
"terminal.
|
|
421
|
-
"terminal.
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
"terminal.
|
|
440
|
-
"terminal.
|
|
441
|
-
"terminal.
|
|
442
|
-
"terminal.
|
|
443
|
-
"terminal.
|
|
444
|
-
"terminal.
|
|
445
|
-
"terminal.
|
|
446
|
-
"terminal.
|
|
447
|
-
"terminal.
|
|
448
|
-
"terminal.
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
"terminal.
|
|
467
|
-
"terminal.
|
|
468
|
-
"terminal.
|
|
469
|
-
"terminal.
|
|
470
|
-
"terminal.
|
|
471
|
-
"terminal.
|
|
472
|
-
"terminal.
|
|
473
|
-
"terminal.
|
|
474
|
-
"terminal.
|
|
475
|
-
"terminal.
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
"terminal.
|
|
494
|
-
"terminal.
|
|
495
|
-
"terminal.
|
|
496
|
-
"terminal.
|
|
497
|
-
"terminal.
|
|
498
|
-
"terminal.
|
|
499
|
-
"terminal.
|
|
500
|
-
"terminal.
|
|
501
|
-
"terminal.
|
|
502
|
-
"terminal.
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
"terminal.
|
|
521
|
-
"terminal.
|
|
522
|
-
"terminal.
|
|
523
|
-
"terminal.
|
|
524
|
-
"terminal.
|
|
525
|
-
"terminal.
|
|
526
|
-
"terminal.
|
|
527
|
-
"terminal.
|
|
528
|
-
"terminal.
|
|
529
|
-
"terminal.
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
"terminal.
|
|
548
|
-
"terminal.
|
|
549
|
-
"terminal.
|
|
550
|
-
"terminal.
|
|
551
|
-
"terminal.
|
|
552
|
-
"terminal.
|
|
553
|
-
"terminal.
|
|
554
|
-
"terminal.
|
|
555
|
-
"terminal.
|
|
556
|
-
"terminal.
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
"terminal.signal": "信号 {signal}",
|
|
580
|
-
"terminal.exitCode": "退出码 {code}",
|
|
581
|
-
"terminal.running": "运行中",
|
|
582
|
-
"terminal.failed": "失败",
|
|
583
|
-
"terminal.done": "已完成",
|
|
584
|
-
"terminal.copy": "复制",
|
|
585
|
-
"terminal.copied": "已复制",
|
|
586
|
-
"terminal.noOutput": "无输出",
|
|
587
|
-
"terminal.collapseAria": "收起输出",
|
|
588
|
-
"terminal.collapse": "折叠",
|
|
589
|
-
"terminal.expandAria": "展开其余 {n} 行输出",
|
|
590
|
-
"terminal.expandRest": "… 其余 {n} 行"
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
"
|
|
607
|
-
"
|
|
608
|
-
"
|
|
609
|
-
"
|
|
610
|
-
"
|
|
611
|
-
"
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
"read",
|
|
644
|
-
"
|
|
645
|
-
"
|
|
646
|
-
"
|
|
647
|
-
"
|
|
648
|
-
"
|
|
649
|
-
"
|
|
650
|
-
"
|
|
651
|
-
"
|
|
652
|
-
"
|
|
653
|
-
"
|
|
654
|
-
"
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
*
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
const
|
|
769
|
-
"
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
if (
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
return
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
if (
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
const
|
|
911
|
-
const
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
};
|
|
941
|
-
|
|
942
|
-
if (
|
|
943
|
-
return
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
function
|
|
957
|
-
if (
|
|
958
|
-
const
|
|
959
|
-
if (
|
|
960
|
-
if (
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
function
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
const
|
|
1038
|
-
const
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
if (
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
const
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
const
|
|
1057
|
-
if (
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
const
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
return {
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
if (
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
const
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
*
|
|
1203
|
-
*
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
*
|
|
1352
|
-
*
|
|
1353
|
-
* a chat tool-call node.
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
const
|
|
1364
|
-
const
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
const
|
|
1369
|
-
if (
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
/**
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
*
|
|
1431
|
-
*
|
|
1432
|
-
*
|
|
1433
|
-
*
|
|
1434
|
-
*/
|
|
1435
|
-
const
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
.
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
.
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
.
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
.
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
.
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
.
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
.
|
|
1551
|
-
.
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
.
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
const
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1
|
+
window.__ModuleLoader__.load({ id: "@huanlin/dsh-plugin-merge-tool-calls", factory: (require) => {
|
|
2
|
+
var module = { exports: {} }; var exports = module.exports;
|
|
3
|
+
//#region rolldown:runtime
|
|
4
|
+
var __create = Object.create;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
+
key = keys[i];
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
21
|
+
value: mod,
|
|
22
|
+
enumerable: true
|
|
23
|
+
}) : target, mod));
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
let react = require("react");
|
|
27
|
+
react = __toESM(react);
|
|
28
|
+
let __deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
29
|
+
__deepseek_ai_dsh_client_ui_primitives = __toESM(__deepseek_ai_dsh_client_ui_primitives);
|
|
30
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
31
|
+
react_jsx_runtime = __toESM(react_jsx_runtime);
|
|
32
|
+
|
|
33
|
+
//#region src/types.ts
|
|
34
|
+
/** Runtime defaults applied when a half receives no config (defensive only). */
|
|
35
|
+
const DEFAULT_MERGE_CONFIG = {
|
|
36
|
+
tools: [],
|
|
37
|
+
groupBy: "adjacent",
|
|
38
|
+
maxGroupSize: 8
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/client/dictionaries.ts
|
|
43
|
+
/** All override-language dictionaries for the `NS` namespace. */
|
|
44
|
+
const dicts = {
|
|
45
|
+
ja: {
|
|
46
|
+
running: "実行中",
|
|
47
|
+
failed: "失敗",
|
|
48
|
+
stopped: "中断",
|
|
49
|
+
expand: "展開",
|
|
50
|
+
collapse: "折りたたむ",
|
|
51
|
+
more: "+{n}",
|
|
52
|
+
showLess: "残りを閉じる",
|
|
53
|
+
mergedCount: "{n} 回の呼び出しを統合",
|
|
54
|
+
countFiles: "{n} 個のファイル",
|
|
55
|
+
countQueries: "{n} 回の検索",
|
|
56
|
+
countCommands: "{n} 個のコマンド",
|
|
57
|
+
countPrograms: "{n} 個のプログラム",
|
|
58
|
+
countCalls: "{n} 回の呼び出し",
|
|
59
|
+
"terminal.signal": "シグナル {signal}",
|
|
60
|
+
"terminal.exitCode": "終了コード {code}",
|
|
61
|
+
"terminal.running": "実行中",
|
|
62
|
+
"terminal.failed": "失敗",
|
|
63
|
+
"terminal.done": "完了",
|
|
64
|
+
"terminal.copy": "コピー",
|
|
65
|
+
"terminal.copied": "コピーしました",
|
|
66
|
+
"terminal.noOutput": "出力なし",
|
|
67
|
+
"terminal.collapseAria": "出力を折りたたむ",
|
|
68
|
+
"terminal.collapse": "折りたたむ",
|
|
69
|
+
"terminal.expandAria": "残り {n} 行の出力を展開",
|
|
70
|
+
"terminal.expandRest": "… 残り {n} 行"
|
|
71
|
+
},
|
|
72
|
+
de: {
|
|
73
|
+
running: "Läuft",
|
|
74
|
+
failed: "Fehlgeschlagen",
|
|
75
|
+
stopped: "Unterbrochen",
|
|
76
|
+
expand: "Erweitern",
|
|
77
|
+
collapse: "Einklappen",
|
|
78
|
+
more: "+{n}",
|
|
79
|
+
showLess: "Weniger anzeigen",
|
|
80
|
+
mergedCount: "{n} Aufrufe zusammengeführt",
|
|
81
|
+
countFiles: "{n} Dateien",
|
|
82
|
+
countQueries: "{n} Suchanfragen",
|
|
83
|
+
countCommands: "{n} Befehle",
|
|
84
|
+
countPrograms: "{n} Programme",
|
|
85
|
+
countCalls: "{n} Aufrufe",
|
|
86
|
+
"terminal.signal": "Signal {signal}",
|
|
87
|
+
"terminal.exitCode": "Exit-Code {code}",
|
|
88
|
+
"terminal.running": "Läuft",
|
|
89
|
+
"terminal.failed": "Fehlgeschlagen",
|
|
90
|
+
"terminal.done": "Abgeschlossen",
|
|
91
|
+
"terminal.copy": "Kopieren",
|
|
92
|
+
"terminal.copied": "Kopiert",
|
|
93
|
+
"terminal.noOutput": "Keine Ausgabe",
|
|
94
|
+
"terminal.collapseAria": "Ausgabe einklappen",
|
|
95
|
+
"terminal.collapse": "Einklappen",
|
|
96
|
+
"terminal.expandAria": "Die restlichen {n} Ausgabezeilen ausklappen",
|
|
97
|
+
"terminal.expandRest": "… {n} weitere Zeilen"
|
|
98
|
+
},
|
|
99
|
+
fr: {
|
|
100
|
+
running: "En cours",
|
|
101
|
+
failed: "Échec",
|
|
102
|
+
stopped: "Interrompu",
|
|
103
|
+
expand: "Développer",
|
|
104
|
+
collapse: "Réduire",
|
|
105
|
+
more: "+{n}",
|
|
106
|
+
showLess: "Afficher moins",
|
|
107
|
+
mergedCount: "{n} appels fusionnés",
|
|
108
|
+
countFiles: "{n} fichiers",
|
|
109
|
+
countQueries: "{n} recherches",
|
|
110
|
+
countCommands: "{n} commandes",
|
|
111
|
+
countPrograms: "{n} programmes",
|
|
112
|
+
countCalls: "{n} appels",
|
|
113
|
+
"terminal.signal": "Signal {signal}",
|
|
114
|
+
"terminal.exitCode": "Code de sortie {code}",
|
|
115
|
+
"terminal.running": "En cours",
|
|
116
|
+
"terminal.failed": "Échec",
|
|
117
|
+
"terminal.done": "Terminé",
|
|
118
|
+
"terminal.copy": "Copier",
|
|
119
|
+
"terminal.copied": "Copié",
|
|
120
|
+
"terminal.noOutput": "Aucune sortie",
|
|
121
|
+
"terminal.collapseAria": "Réduire la sortie",
|
|
122
|
+
"terminal.collapse": "Réduire",
|
|
123
|
+
"terminal.expandAria": "Déployer les {n} lignes de sortie restantes",
|
|
124
|
+
"terminal.expandRest": "… {n} lignes restantes"
|
|
125
|
+
},
|
|
126
|
+
pt: {
|
|
127
|
+
running: "Executando",
|
|
128
|
+
failed: "Falhou",
|
|
129
|
+
stopped: "Interrompido",
|
|
130
|
+
expand: "Expandir",
|
|
131
|
+
collapse: "Recolher",
|
|
132
|
+
more: "+{n}",
|
|
133
|
+
showLess: "Mostrar menos",
|
|
134
|
+
mergedCount: "{n} chamadas mescladas",
|
|
135
|
+
countFiles: "{n} arquivos",
|
|
136
|
+
countQueries: "{n} pesquisas",
|
|
137
|
+
countCommands: "{n} comandos",
|
|
138
|
+
countPrograms: "{n} programas",
|
|
139
|
+
countCalls: "{n} chamadas",
|
|
140
|
+
"terminal.signal": "sinal {signal}",
|
|
141
|
+
"terminal.exitCode": "código de saída {code}",
|
|
142
|
+
"terminal.running": "Executando",
|
|
143
|
+
"terminal.failed": "Falhou",
|
|
144
|
+
"terminal.done": "Concluído",
|
|
145
|
+
"terminal.copy": "Copiar",
|
|
146
|
+
"terminal.copied": "Copiado",
|
|
147
|
+
"terminal.noOutput": "Sem saída",
|
|
148
|
+
"terminal.collapseAria": "Recolher saída",
|
|
149
|
+
"terminal.collapse": "Recolher",
|
|
150
|
+
"terminal.expandAria": "Expandir as {n} linhas de saída restantes",
|
|
151
|
+
"terminal.expandRest": "… mais {n} linhas"
|
|
152
|
+
},
|
|
153
|
+
ko: {
|
|
154
|
+
running: "실행 중",
|
|
155
|
+
failed: "실패",
|
|
156
|
+
stopped: "중단됨",
|
|
157
|
+
expand: "펼치기",
|
|
158
|
+
collapse: "접기",
|
|
159
|
+
more: "+{n}",
|
|
160
|
+
showLess: "더 적게 표시",
|
|
161
|
+
mergedCount: "{n}번 호출 병합됨",
|
|
162
|
+
countFiles: "파일 {n}개",
|
|
163
|
+
countQueries: "검색 {n}회",
|
|
164
|
+
countCommands: "명령 {n}개",
|
|
165
|
+
countPrograms: "프로그램 {n}개",
|
|
166
|
+
countCalls: "호출 {n}회",
|
|
167
|
+
"terminal.signal": "신호 {signal}",
|
|
168
|
+
"terminal.exitCode": "종료 코드 {code}",
|
|
169
|
+
"terminal.running": "실행 중",
|
|
170
|
+
"terminal.failed": "실패",
|
|
171
|
+
"terminal.done": "완료",
|
|
172
|
+
"terminal.copy": "복사",
|
|
173
|
+
"terminal.copied": "복사됨",
|
|
174
|
+
"terminal.noOutput": "출력 없음",
|
|
175
|
+
"terminal.collapseAria": "출력 접기",
|
|
176
|
+
"terminal.collapse": "접기",
|
|
177
|
+
"terminal.expandAria": "나머지 {n}줄 출력 펼치기",
|
|
178
|
+
"terminal.expandRest": "… 나머지 {n}줄"
|
|
179
|
+
},
|
|
180
|
+
ar: {
|
|
181
|
+
running: "قيد التشغيل",
|
|
182
|
+
failed: "فشل",
|
|
183
|
+
stopped: "متوقف",
|
|
184
|
+
expand: "توسيع",
|
|
185
|
+
collapse: "طي",
|
|
186
|
+
more: "+{n}",
|
|
187
|
+
showLess: "إظهار أقل",
|
|
188
|
+
mergedCount: "تم دمج {n} استدعاء",
|
|
189
|
+
countFiles: "{n} ملف",
|
|
190
|
+
countQueries: "{n} بحث",
|
|
191
|
+
countCommands: "{n} أمر",
|
|
192
|
+
countPrograms: "{n} برنامج",
|
|
193
|
+
countCalls: "{n} استدعاء",
|
|
194
|
+
"terminal.signal": "إشارة {signal}",
|
|
195
|
+
"terminal.exitCode": "رمز الخروج {code}",
|
|
196
|
+
"terminal.running": "قيد التشغيل",
|
|
197
|
+
"terminal.failed": "فشل",
|
|
198
|
+
"terminal.done": "اكتمل",
|
|
199
|
+
"terminal.copy": "نسخ",
|
|
200
|
+
"terminal.copied": "تم النسخ",
|
|
201
|
+
"terminal.noOutput": "لا يوجد إخراج",
|
|
202
|
+
"terminal.collapseAria": "طي الإخراج",
|
|
203
|
+
"terminal.collapse": "طي",
|
|
204
|
+
"terminal.expandAria": "توسيع {n} أسطر إخراج المتبقية",
|
|
205
|
+
"terminal.expandRest": "… و{n} أسطر أخرى"
|
|
206
|
+
},
|
|
207
|
+
hi: {
|
|
208
|
+
running: "चल रहा",
|
|
209
|
+
failed: "विफल",
|
|
210
|
+
stopped: "रोका गया",
|
|
211
|
+
expand: "विस्तार करें",
|
|
212
|
+
collapse: "संक्षिप्त करें",
|
|
213
|
+
more: "+{n}",
|
|
214
|
+
showLess: "कम दिखाएं",
|
|
215
|
+
mergedCount: "{n} कॉल मर्ज किए गए",
|
|
216
|
+
countFiles: "{n} फ़ाइलें",
|
|
217
|
+
countQueries: "{n} खोज",
|
|
218
|
+
countCommands: "{n} कमांड",
|
|
219
|
+
countPrograms: "{n} प्रोग्राम",
|
|
220
|
+
countCalls: "{n} कॉल",
|
|
221
|
+
"terminal.signal": "सिग्नल {signal}",
|
|
222
|
+
"terminal.exitCode": "एग्ज़िट कोड {code}",
|
|
223
|
+
"terminal.running": "चल रहा",
|
|
224
|
+
"terminal.failed": "विफल",
|
|
225
|
+
"terminal.done": "पूर्ण",
|
|
226
|
+
"terminal.copy": "कॉपी",
|
|
227
|
+
"terminal.copied": "कॉपी हो गया",
|
|
228
|
+
"terminal.noOutput": "कोई आउटपुट नहीं",
|
|
229
|
+
"terminal.collapseAria": "आउटपुट संक्षिप्त करें",
|
|
230
|
+
"terminal.collapse": "संक्षिप्त करें",
|
|
231
|
+
"terminal.expandAria": "शेष {n} आउटपुट पंक्तियाँ विस्तृत करें",
|
|
232
|
+
"terminal.expandRest": "… {n} और पंक्तियाँ"
|
|
233
|
+
},
|
|
234
|
+
id: {
|
|
235
|
+
running: "Berjalan",
|
|
236
|
+
failed: "Gagal",
|
|
237
|
+
stopped: "Dihentikan",
|
|
238
|
+
expand: "Bentangkan",
|
|
239
|
+
collapse: "Lipat",
|
|
240
|
+
more: "+{n}",
|
|
241
|
+
showLess: "Tampilkan lebih sedikit",
|
|
242
|
+
mergedCount: "{n} panggilan digabungkan",
|
|
243
|
+
countFiles: "{n} file",
|
|
244
|
+
countQueries: "{n} pencarian",
|
|
245
|
+
countCommands: "{n} perintah",
|
|
246
|
+
countPrograms: "{n} program",
|
|
247
|
+
countCalls: "{n} panggilan",
|
|
248
|
+
"terminal.signal": "sinyal {signal}",
|
|
249
|
+
"terminal.exitCode": "kode keluar {code}",
|
|
250
|
+
"terminal.running": "Berjalan",
|
|
251
|
+
"terminal.failed": "Gagal",
|
|
252
|
+
"terminal.done": "Selesai",
|
|
253
|
+
"terminal.copy": "Salin",
|
|
254
|
+
"terminal.copied": "Tersalin",
|
|
255
|
+
"terminal.noOutput": "Tidak ada keluaran",
|
|
256
|
+
"terminal.collapseAria": "Lipat keluaran",
|
|
257
|
+
"terminal.collapse": "Lipat",
|
|
258
|
+
"terminal.expandAria": "Bentangkan {n} baris keluaran tersisa",
|
|
259
|
+
"terminal.expandRest": "… {n} baris lagi"
|
|
260
|
+
},
|
|
261
|
+
tr: {
|
|
262
|
+
running: "Çalışıyor",
|
|
263
|
+
failed: "Başarısız",
|
|
264
|
+
stopped: "Durduruldu",
|
|
265
|
+
expand: "Genişlet",
|
|
266
|
+
collapse: "Daralt",
|
|
267
|
+
more: "+{n}",
|
|
268
|
+
showLess: "Daha az göster",
|
|
269
|
+
mergedCount: "{n} çağrı birleştirildi",
|
|
270
|
+
countFiles: "{n} dosya",
|
|
271
|
+
countQueries: "{n} arama",
|
|
272
|
+
countCommands: "{n} komut",
|
|
273
|
+
countPrograms: "{n} program",
|
|
274
|
+
countCalls: "{n} çağrı",
|
|
275
|
+
"terminal.signal": "sinyal {signal}",
|
|
276
|
+
"terminal.exitCode": "çıkış kodu {code}",
|
|
277
|
+
"terminal.running": "Çalışıyor",
|
|
278
|
+
"terminal.failed": "Başarısız",
|
|
279
|
+
"terminal.done": "Tamamlandı",
|
|
280
|
+
"terminal.copy": "Kopyala",
|
|
281
|
+
"terminal.copied": "Kopyalandı",
|
|
282
|
+
"terminal.noOutput": "Çıkış yok",
|
|
283
|
+
"terminal.collapseAria": "Çıkışı daralt",
|
|
284
|
+
"terminal.collapse": "Daralt",
|
|
285
|
+
"terminal.expandAria": "Kalan {n} çıkış satırını genişlet",
|
|
286
|
+
"terminal.expandRest": "… {n} satır daha"
|
|
287
|
+
},
|
|
288
|
+
vi: {
|
|
289
|
+
running: "Đang chạy",
|
|
290
|
+
failed: "Thất bại",
|
|
291
|
+
stopped: "Đã dừng",
|
|
292
|
+
expand: "Mở rộng",
|
|
293
|
+
collapse: "Thu gọn",
|
|
294
|
+
more: "+{n}",
|
|
295
|
+
showLess: "Hiển thị ít hơn",
|
|
296
|
+
mergedCount: "Đã gộp {n} lệnh gọi",
|
|
297
|
+
countFiles: "{n} tệp",
|
|
298
|
+
countQueries: "{n} lượt tìm kiếm",
|
|
299
|
+
countCommands: "{n} lệnh",
|
|
300
|
+
countPrograms: "{n} chương trình",
|
|
301
|
+
countCalls: "{n} lượt gọi",
|
|
302
|
+
"terminal.signal": "tín hiệu {signal}",
|
|
303
|
+
"terminal.exitCode": "mã thoát {code}",
|
|
304
|
+
"terminal.running": "Đang chạy",
|
|
305
|
+
"terminal.failed": "Thất bại",
|
|
306
|
+
"terminal.done": "Đã xong",
|
|
307
|
+
"terminal.copy": "Sao chép",
|
|
308
|
+
"terminal.copied": "Đã sao chép",
|
|
309
|
+
"terminal.noOutput": "Không có đầu ra",
|
|
310
|
+
"terminal.collapseAria": "Thu gọn đầu ra",
|
|
311
|
+
"terminal.collapse": "Thu gọn",
|
|
312
|
+
"terminal.expandAria": "Mở rộng {n} dòng đầu ra còn lại",
|
|
313
|
+
"terminal.expandRest": "… còn {n} dòng"
|
|
314
|
+
},
|
|
315
|
+
th: {
|
|
316
|
+
running: "กำลังทำงาน",
|
|
317
|
+
failed: "ล้มเหลว",
|
|
318
|
+
stopped: "ถูกขัดจังหวะ",
|
|
319
|
+
expand: "ขยาย",
|
|
320
|
+
collapse: "ย่อ",
|
|
321
|
+
more: "+{n}",
|
|
322
|
+
showLess: "แสดงน้อยลง",
|
|
323
|
+
mergedCount: "รวม {n} การเรียก",
|
|
324
|
+
countFiles: "{n} ไฟล์",
|
|
325
|
+
countQueries: "{n} การค้นหา",
|
|
326
|
+
countCommands: "{n} คำสั่ง",
|
|
327
|
+
countPrograms: "{n} โปรแกรม",
|
|
328
|
+
countCalls: "{n} การเรียก",
|
|
329
|
+
"terminal.signal": "สัญญาณ {signal}",
|
|
330
|
+
"terminal.exitCode": "รหัสออก {code}",
|
|
331
|
+
"terminal.running": "กำลังทำงาน",
|
|
332
|
+
"terminal.failed": "ล้มเหลว",
|
|
333
|
+
"terminal.done": "เสร็จสิ้น",
|
|
334
|
+
"terminal.copy": "คัดลอก",
|
|
335
|
+
"terminal.copied": "คัดลอกแล้ว",
|
|
336
|
+
"terminal.noOutput": "ไม่มีเอาต์พุต",
|
|
337
|
+
"terminal.collapseAria": "ย่อเอาต์พุต",
|
|
338
|
+
"terminal.collapse": "ย่อ",
|
|
339
|
+
"terminal.expandAria": "ขยายเอาต์พุตอีก {n} บรรทัด",
|
|
340
|
+
"terminal.expandRest": "… อีก {n} บรรทัด"
|
|
341
|
+
},
|
|
342
|
+
ru: {
|
|
343
|
+
running: "Выполняется",
|
|
344
|
+
failed: "Сбой",
|
|
345
|
+
stopped: "Прервано",
|
|
346
|
+
expand: "Развернуть",
|
|
347
|
+
collapse: "Свернуть",
|
|
348
|
+
more: "+{n}",
|
|
349
|
+
showLess: "Показать меньше",
|
|
350
|
+
mergedCount: "Объединено вызовов: {n}",
|
|
351
|
+
countFiles: "{n} файлов",
|
|
352
|
+
countQueries: "{n} поисков",
|
|
353
|
+
countCommands: "{n} команд",
|
|
354
|
+
countPrograms: "{n} программ",
|
|
355
|
+
countCalls: "{n} вызовов",
|
|
356
|
+
"terminal.signal": "сигнал {signal}",
|
|
357
|
+
"terminal.exitCode": "код выхода {code}",
|
|
358
|
+
"terminal.running": "Выполняется",
|
|
359
|
+
"terminal.failed": "Сбой",
|
|
360
|
+
"terminal.done": "Завершено",
|
|
361
|
+
"terminal.copy": "Копировать",
|
|
362
|
+
"terminal.copied": "Скопировано",
|
|
363
|
+
"terminal.noOutput": "Нет вывода",
|
|
364
|
+
"terminal.collapseAria": "Свернуть вывод",
|
|
365
|
+
"terminal.collapse": "Свернуть",
|
|
366
|
+
"terminal.expandAria": "Показать оставшиеся {n} строк вывода",
|
|
367
|
+
"terminal.expandRest": "… ещё {n} строк"
|
|
368
|
+
},
|
|
369
|
+
it: {
|
|
370
|
+
running: "In esecuzione",
|
|
371
|
+
failed: "Non riuscito",
|
|
372
|
+
stopped: "Interrotto",
|
|
373
|
+
expand: "Espandi",
|
|
374
|
+
collapse: "Comprimi",
|
|
375
|
+
more: "+{n}",
|
|
376
|
+
showLess: "Mostra meno",
|
|
377
|
+
mergedCount: "{n} chiamate unite",
|
|
378
|
+
countFiles: "{n} file",
|
|
379
|
+
countQueries: "{n} ricerche",
|
|
380
|
+
countCommands: "{n} comandi",
|
|
381
|
+
countPrograms: "{n} programmi",
|
|
382
|
+
countCalls: "{n} chiamate",
|
|
383
|
+
"terminal.signal": "segnale {signal}",
|
|
384
|
+
"terminal.exitCode": "codice di uscita {code}",
|
|
385
|
+
"terminal.running": "In esecuzione",
|
|
386
|
+
"terminal.failed": "Non riuscito",
|
|
387
|
+
"terminal.done": "Completato",
|
|
388
|
+
"terminal.copy": "Copia",
|
|
389
|
+
"terminal.copied": "Copiato",
|
|
390
|
+
"terminal.noOutput": "Nessun output",
|
|
391
|
+
"terminal.collapseAria": "Comprimi output",
|
|
392
|
+
"terminal.collapse": "Comprimi",
|
|
393
|
+
"terminal.expandAria": "Espandi le restanti {n} righe di output",
|
|
394
|
+
"terminal.expandRest": "… altre {n} righe"
|
|
395
|
+
},
|
|
396
|
+
nl: {
|
|
397
|
+
running: "Actief",
|
|
398
|
+
failed: "Mislukt",
|
|
399
|
+
stopped: "Onderbroken",
|
|
400
|
+
expand: "Uitklappen",
|
|
401
|
+
collapse: "Inklappen",
|
|
402
|
+
more: "+{n}",
|
|
403
|
+
showLess: "Minder tonen",
|
|
404
|
+
mergedCount: "{n} aanroepen samengevoegd",
|
|
405
|
+
countFiles: "{n} bestanden",
|
|
406
|
+
countQueries: "{n} zoekopdrachten",
|
|
407
|
+
countCommands: "{n} opdrachten",
|
|
408
|
+
countPrograms: "{n} programma's",
|
|
409
|
+
countCalls: "{n} aanroepen",
|
|
410
|
+
"terminal.signal": "signaal {signal}",
|
|
411
|
+
"terminal.exitCode": "exit-code {code}",
|
|
412
|
+
"terminal.running": "Actief",
|
|
413
|
+
"terminal.failed": "Mislukt",
|
|
414
|
+
"terminal.done": "Voltooid",
|
|
415
|
+
"terminal.copy": "Kopiëren",
|
|
416
|
+
"terminal.copied": "Gekopieerd",
|
|
417
|
+
"terminal.noOutput": "Geen uitvoer",
|
|
418
|
+
"terminal.collapseAria": "Uitvoer inklappen",
|
|
419
|
+
"terminal.collapse": "Inklappen",
|
|
420
|
+
"terminal.expandAria": "De overige {n} uitvoerregels uitklappen",
|
|
421
|
+
"terminal.expandRest": "… nog {n} regels"
|
|
422
|
+
},
|
|
423
|
+
sv: {
|
|
424
|
+
running: "Kör",
|
|
425
|
+
failed: "Misslyckades",
|
|
426
|
+
stopped: "Avbruten",
|
|
427
|
+
expand: "Expandera",
|
|
428
|
+
collapse: "Komprimera",
|
|
429
|
+
more: "+{n}",
|
|
430
|
+
showLess: "Visa mindre",
|
|
431
|
+
mergedCount: "{n} anrop sammanslagna",
|
|
432
|
+
countFiles: "{n} filer",
|
|
433
|
+
countQueries: "{n} sökningar",
|
|
434
|
+
countCommands: "{n} kommandon",
|
|
435
|
+
countPrograms: "{n} program",
|
|
436
|
+
countCalls: "{n} anrop",
|
|
437
|
+
"terminal.signal": "signal {signal}",
|
|
438
|
+
"terminal.exitCode": "slutkod {code}",
|
|
439
|
+
"terminal.running": "Kör",
|
|
440
|
+
"terminal.failed": "Misslyckades",
|
|
441
|
+
"terminal.done": "Klar",
|
|
442
|
+
"terminal.copy": "Kopiera",
|
|
443
|
+
"terminal.copied": "Kopierades",
|
|
444
|
+
"terminal.noOutput": "Ingen utdata",
|
|
445
|
+
"terminal.collapseAria": "Komprimera utdata",
|
|
446
|
+
"terminal.collapse": "Komprimera",
|
|
447
|
+
"terminal.expandAria": "Expandera de återstående {n} utdataraderna",
|
|
448
|
+
"terminal.expandRest": "… {n} fler rader"
|
|
449
|
+
},
|
|
450
|
+
pl: {
|
|
451
|
+
running: "Działa",
|
|
452
|
+
failed: "Nie powiodło się",
|
|
453
|
+
stopped: "Przerwano",
|
|
454
|
+
expand: "Rozwiń",
|
|
455
|
+
collapse: "Zwiń",
|
|
456
|
+
more: "+{n}",
|
|
457
|
+
showLess: "Pokaż mniej",
|
|
458
|
+
mergedCount: "Połączono {n} wywołań",
|
|
459
|
+
countFiles: "{n} plików",
|
|
460
|
+
countQueries: "{n} wyszukań",
|
|
461
|
+
countCommands: "{n} poleceń",
|
|
462
|
+
countPrograms: "{n} programów",
|
|
463
|
+
countCalls: "{n} wywołań",
|
|
464
|
+
"terminal.signal": "sygnał {signal}",
|
|
465
|
+
"terminal.exitCode": "kod wyjścia {code}",
|
|
466
|
+
"terminal.running": "Działa",
|
|
467
|
+
"terminal.failed": "Nie powiodło się",
|
|
468
|
+
"terminal.done": "Ukończono",
|
|
469
|
+
"terminal.copy": "Kopiuj",
|
|
470
|
+
"terminal.copied": "Skopiowano",
|
|
471
|
+
"terminal.noOutput": "Brak wyjścia",
|
|
472
|
+
"terminal.collapseAria": "Zwiń wyjście",
|
|
473
|
+
"terminal.collapse": "Zwiń",
|
|
474
|
+
"terminal.expandAria": "Rozwiń pozostałe {n} wierszy wyjścia",
|
|
475
|
+
"terminal.expandRest": "…jeszcze {n} wierszy"
|
|
476
|
+
},
|
|
477
|
+
"zh-HK": {
|
|
478
|
+
running: "執行中",
|
|
479
|
+
failed: "失敗",
|
|
480
|
+
stopped: "已中斷",
|
|
481
|
+
expand: "展開",
|
|
482
|
+
collapse: "收起",
|
|
483
|
+
more: "+{n}",
|
|
484
|
+
showLess: "收起其餘",
|
|
485
|
+
mergedCount: "已合併 {n} 次呼叫",
|
|
486
|
+
countFiles: "{n} 個檔案",
|
|
487
|
+
countQueries: "{n} 次搜尋",
|
|
488
|
+
countCommands: "{n} 條命令",
|
|
489
|
+
countPrograms: "{n} 段程式碼",
|
|
490
|
+
countCalls: "{n} 次呼叫",
|
|
491
|
+
"terminal.signal": "訊號 {signal}",
|
|
492
|
+
"terminal.exitCode": "退出碼 {code}",
|
|
493
|
+
"terminal.running": "執行中",
|
|
494
|
+
"terminal.failed": "失敗",
|
|
495
|
+
"terminal.done": "已完成",
|
|
496
|
+
"terminal.copy": "複製",
|
|
497
|
+
"terminal.copied": "已複製",
|
|
498
|
+
"terminal.noOutput": "無輸出",
|
|
499
|
+
"terminal.collapseAria": "收起輸出",
|
|
500
|
+
"terminal.collapse": "收起",
|
|
501
|
+
"terminal.expandAria": "展開其餘 {n} 行輸出",
|
|
502
|
+
"terminal.expandRest": "… 其餘 {n} 行"
|
|
503
|
+
},
|
|
504
|
+
"zh-TW": {
|
|
505
|
+
running: "執行中",
|
|
506
|
+
failed: "失敗",
|
|
507
|
+
stopped: "已中斷",
|
|
508
|
+
expand: "展開",
|
|
509
|
+
collapse: "收起",
|
|
510
|
+
more: "+{n}",
|
|
511
|
+
showLess: "收起其餘",
|
|
512
|
+
mergedCount: "已合併 {n} 次呼叫",
|
|
513
|
+
countFiles: "{n} 個檔案",
|
|
514
|
+
countQueries: "{n} 次搜尋",
|
|
515
|
+
countCommands: "{n} 條命令",
|
|
516
|
+
countPrograms: "{n} 段程式碼",
|
|
517
|
+
countCalls: "{n} 次呼叫",
|
|
518
|
+
"terminal.signal": "訊號 {signal}",
|
|
519
|
+
"terminal.exitCode": "退出碼 {code}",
|
|
520
|
+
"terminal.running": "執行中",
|
|
521
|
+
"terminal.failed": "失敗",
|
|
522
|
+
"terminal.done": "已完成",
|
|
523
|
+
"terminal.copy": "複製",
|
|
524
|
+
"terminal.copied": "已複製",
|
|
525
|
+
"terminal.noOutput": "無輸出",
|
|
526
|
+
"terminal.collapseAria": "收起輸出",
|
|
527
|
+
"terminal.collapse": "收起",
|
|
528
|
+
"terminal.expandAria": "展開其餘 {n} 行輸出",
|
|
529
|
+
"terminal.expandRest": "… 其餘 {n} 行"
|
|
530
|
+
},
|
|
531
|
+
"zh-MO": {
|
|
532
|
+
running: "執行中",
|
|
533
|
+
failed: "失敗",
|
|
534
|
+
stopped: "已中斷",
|
|
535
|
+
expand: "展開",
|
|
536
|
+
collapse: "收起",
|
|
537
|
+
more: "+{n}",
|
|
538
|
+
showLess: "收起其餘",
|
|
539
|
+
mergedCount: "已合併 {n} 次呼叫",
|
|
540
|
+
countFiles: "{n} 個檔案",
|
|
541
|
+
countQueries: "{n} 次搜尋",
|
|
542
|
+
countCommands: "{n} 條命令",
|
|
543
|
+
countPrograms: "{n} 段程式碼",
|
|
544
|
+
countCalls: "{n} 次呼叫",
|
|
545
|
+
"terminal.signal": "訊號 {signal}",
|
|
546
|
+
"terminal.exitCode": "退出碼 {code}",
|
|
547
|
+
"terminal.running": "執行中",
|
|
548
|
+
"terminal.failed": "失敗",
|
|
549
|
+
"terminal.done": "已完成",
|
|
550
|
+
"terminal.copy": "複製",
|
|
551
|
+
"terminal.copied": "已複製",
|
|
552
|
+
"terminal.noOutput": "無輸出",
|
|
553
|
+
"terminal.collapseAria": "收起輸出",
|
|
554
|
+
"terminal.collapse": "收起",
|
|
555
|
+
"terminal.expandAria": "展開其餘 {n} 行輸出",
|
|
556
|
+
"terminal.expandRest": "… 其餘 {n} 行"
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
//#endregion
|
|
561
|
+
//#region src/client/locales.ts
|
|
562
|
+
/** Product copy for the merged tool-call rows. */
|
|
563
|
+
const zh = {
|
|
564
|
+
running: "进行中",
|
|
565
|
+
failed: "失败",
|
|
566
|
+
stopped: "已中断",
|
|
567
|
+
expand: "展开",
|
|
568
|
+
collapse: "折叠",
|
|
569
|
+
more: "+{n}",
|
|
570
|
+
showLess: "收起其余",
|
|
571
|
+
mergedCount: "已合并 {n} 次调用",
|
|
572
|
+
countFiles: "{n} 个文件",
|
|
573
|
+
countQueries: "{n} 次搜索",
|
|
574
|
+
countCommands: "{n} 条命令",
|
|
575
|
+
countPrograms: "{n} 段代码",
|
|
576
|
+
countCalls: "{n} 次调用",
|
|
577
|
+
copy: "复制",
|
|
578
|
+
copied: "已复制",
|
|
579
|
+
"terminal.signal": "信号 {signal}",
|
|
580
|
+
"terminal.exitCode": "退出码 {code}",
|
|
581
|
+
"terminal.running": "运行中",
|
|
582
|
+
"terminal.failed": "失败",
|
|
583
|
+
"terminal.done": "已完成",
|
|
584
|
+
"terminal.copy": "复制",
|
|
585
|
+
"terminal.copied": "已复制",
|
|
586
|
+
"terminal.noOutput": "无输出",
|
|
587
|
+
"terminal.collapseAria": "收起输出",
|
|
588
|
+
"terminal.collapse": "折叠",
|
|
589
|
+
"terminal.expandAria": "展开其余 {n} 行输出",
|
|
590
|
+
"terminal.expandRest": "… 其余 {n} 行",
|
|
591
|
+
"read.window": "显示 {shown} / {total} 行",
|
|
592
|
+
"read.collapseAria": "收起内容",
|
|
593
|
+
"read.expandAria": "展开其余 {count} 行",
|
|
594
|
+
"read.expandRest": "… 其余 {count} 行",
|
|
595
|
+
"search.paths": "{shown} 个路径",
|
|
596
|
+
"search.paths.truncated": "显示 {shown} / 共 {total} 个路径",
|
|
597
|
+
"search.matches": "{shown} 处匹配 · {files} 个文件",
|
|
598
|
+
"search.matches.truncated": "显示 {shown} / 共 {total} 处匹配 · {files} 个文件",
|
|
599
|
+
"search.noResults": "无结果",
|
|
600
|
+
"search.collapseAria": "收起结果",
|
|
601
|
+
"search.expandAria": "展开其余 {count} 行结果",
|
|
602
|
+
"search.expandRest": "… 其余 {count} 行",
|
|
603
|
+
"diff.collapseAria": "收起差异",
|
|
604
|
+
"diff.expandAria": "展开其余 {count} 行差异",
|
|
605
|
+
"diff.expandRest": "… 其余 {count} 行",
|
|
606
|
+
"diff.files": "{count} 个文件",
|
|
607
|
+
"web.noResults": "未找到结果",
|
|
608
|
+
"web.sourcesTruncated": "来源列表已截断",
|
|
609
|
+
"web.http": "HTTP",
|
|
610
|
+
"web.contentTruncated": "内容已截断",
|
|
611
|
+
"markdown.footnotes": "脚注"
|
|
612
|
+
};
|
|
613
|
+
const en = {
|
|
614
|
+
running: "Running",
|
|
615
|
+
failed: "Failed",
|
|
616
|
+
stopped: "Interrupted",
|
|
617
|
+
expand: "Expand",
|
|
618
|
+
collapse: "Collapse",
|
|
619
|
+
more: "+{n}",
|
|
620
|
+
showLess: "Show fewer",
|
|
621
|
+
mergedCount: "{n} calls merged",
|
|
622
|
+
countFiles: "{n} Files",
|
|
623
|
+
countQueries: "{n} Queries",
|
|
624
|
+
countCommands: "{n} Commands",
|
|
625
|
+
countPrograms: "{n} Programs",
|
|
626
|
+
countCalls: "{n} Calls",
|
|
627
|
+
copy: "Copy",
|
|
628
|
+
copied: "Copied",
|
|
629
|
+
"terminal.signal": "signal {signal}",
|
|
630
|
+
"terminal.exitCode": "exit code {code}",
|
|
631
|
+
"terminal.running": "Running",
|
|
632
|
+
"terminal.failed": "Failed",
|
|
633
|
+
"terminal.done": "Done",
|
|
634
|
+
"terminal.copy": "Copy",
|
|
635
|
+
"terminal.copied": "Copied",
|
|
636
|
+
"terminal.noOutput": "No output",
|
|
637
|
+
"terminal.collapseAria": "Collapse output",
|
|
638
|
+
"terminal.collapse": "Collapse",
|
|
639
|
+
"terminal.expandAria": "Expand the remaining {n} output lines",
|
|
640
|
+
"terminal.expandRest": "… {n} more lines",
|
|
641
|
+
"read.window": "Showing {shown} of {total} lines",
|
|
642
|
+
"read.collapseAria": "Collapse content",
|
|
643
|
+
"read.expandAria": "Expand {count} more lines",
|
|
644
|
+
"read.expandRest": "… {count} more lines",
|
|
645
|
+
"search.paths": "{shown} paths",
|
|
646
|
+
"search.paths.truncated": "Showing {shown} of {total} paths",
|
|
647
|
+
"search.matches": "{shown} matches · {files} files",
|
|
648
|
+
"search.matches.truncated": "Showing {shown} of {total} matches · {files} files",
|
|
649
|
+
"search.noResults": "No results",
|
|
650
|
+
"search.collapseAria": "Collapse results",
|
|
651
|
+
"search.expandAria": "Expand {count} more result lines",
|
|
652
|
+
"search.expandRest": "… {count} more lines",
|
|
653
|
+
"diff.collapseAria": "Collapse diff",
|
|
654
|
+
"diff.expandAria": "Expand {count} more diff lines",
|
|
655
|
+
"diff.expandRest": "… {count} more lines",
|
|
656
|
+
"diff.files": "{count} files",
|
|
657
|
+
"web.noResults": "No results found",
|
|
658
|
+
"web.sourcesTruncated": "Source list truncated",
|
|
659
|
+
"web.http": "HTTP",
|
|
660
|
+
"web.contentTruncated": "Content truncated",
|
|
661
|
+
"markdown.footnotes": "Footnotes"
|
|
662
|
+
};
|
|
663
|
+
const NS = "merge-tool-calls";
|
|
664
|
+
|
|
665
|
+
//#endregion
|
|
666
|
+
//#region src/client/tool-names.ts
|
|
667
|
+
/**
|
|
668
|
+
* The built-in tool universe this plugin shadows by default, plus the
|
|
669
|
+
* variant-classification vocabulary mirroring ui-tool's tool-call model.
|
|
670
|
+
*
|
|
671
|
+
* The keyed `tool.call.toolview` slot dispatches on the exact wire tool name,
|
|
672
|
+
* so a shadowed registration is needed per name (there is no wildcard). This
|
|
673
|
+
* list names every shipped tool whose row belongs to the generic ToolRow
|
|
674
|
+
* family — a variant title/icon plus read/search/diff/terminal/web card or
|
|
675
|
+
* IN/OUT text — which the merged row reproduces faithfully.
|
|
676
|
+
*
|
|
677
|
+
* Deliberately excluded: tools with custom row cards this plugin does not
|
|
678
|
+
* replicate (`skill`, `cordis_define`, and the live `cordis_run` /
|
|
679
|
+
* `cordis_stop` / `cordis_undefine` rows), and `todo_write` /
|
|
680
|
+
* `ask_user_question` whose summary formatting is tool-specific. They keep
|
|
681
|
+
* their built-in rows unless the user names them in the `tools` config
|
|
682
|
+
* explicitly.
|
|
683
|
+
* @module
|
|
684
|
+
*/
|
|
685
|
+
/** Wire tool names merged by default (empty `tools` config = this list). */
|
|
686
|
+
const ALL_TOOL_NAMES = [
|
|
687
|
+
"read",
|
|
688
|
+
"grep",
|
|
689
|
+
"glob",
|
|
690
|
+
"edit",
|
|
691
|
+
"write",
|
|
692
|
+
"bash",
|
|
693
|
+
"pwsh",
|
|
694
|
+
"web_search",
|
|
695
|
+
"web_fetch",
|
|
696
|
+
"run_code",
|
|
697
|
+
"cordis_package_inspect",
|
|
698
|
+
"cordis_runtime_inspect"
|
|
699
|
+
];
|
|
700
|
+
/** Figma row titles per variant (design literals, not translatable copy). */
|
|
701
|
+
const VARIANT_TITLES = {
|
|
702
|
+
search: "Search",
|
|
703
|
+
read: "Read",
|
|
704
|
+
bash: "Bash",
|
|
705
|
+
write: "Write",
|
|
706
|
+
edit: "Edit",
|
|
707
|
+
code: "Code",
|
|
708
|
+
others: "Tool call"
|
|
709
|
+
};
|
|
710
|
+
/**
|
|
711
|
+
* Known tool name -> row variant (mirrors ui-tool's classification table,
|
|
712
|
+
* minus the run-control verbs: their rows are custom and not shadowed).
|
|
713
|
+
*/
|
|
714
|
+
const TOOL_VARIANTS = {
|
|
715
|
+
bash: "bash",
|
|
716
|
+
pwsh: "bash",
|
|
717
|
+
read: "read",
|
|
718
|
+
web_fetch: "read",
|
|
719
|
+
web_search: "search",
|
|
720
|
+
grep: "search",
|
|
721
|
+
glob: "search",
|
|
722
|
+
write: "write",
|
|
723
|
+
edit: "edit",
|
|
724
|
+
run_code: "code",
|
|
725
|
+
cordis_package_inspect: "read",
|
|
726
|
+
cordis_runtime_inspect: "read"
|
|
727
|
+
};
|
|
728
|
+
/** Tool-owned titles refining a generic row variant (mirrors ui-tool). */
|
|
729
|
+
const TOOL_TITLES = {
|
|
730
|
+
cordis_package_inspect: "Inspect",
|
|
731
|
+
cordis_runtime_inspect: "Inspect",
|
|
732
|
+
pwsh: "Pwsh"
|
|
733
|
+
};
|
|
734
|
+
/** Classify a tool name into its row variant (mirrors ui-tool). */
|
|
735
|
+
function classifyTool(toolName) {
|
|
736
|
+
return TOOL_VARIANTS[toolName] ?? "others";
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
//#endregion
|
|
740
|
+
//#region src/client/card-model.ts
|
|
741
|
+
/**
|
|
742
|
+
* Parse the call head paired with one immutable Tool block.
|
|
743
|
+
* @param block - running or settled Tool block.
|
|
744
|
+
* @returns the Tool name and object arguments, or null when unavailable.
|
|
745
|
+
*/
|
|
746
|
+
function parsedArgsOf(block) {
|
|
747
|
+
const call = "kind" in block ? block.call : block;
|
|
748
|
+
if (call === null) return null;
|
|
749
|
+
let value;
|
|
750
|
+
try {
|
|
751
|
+
value = JSON.parse(call.argsRaw);
|
|
752
|
+
} catch {
|
|
753
|
+
return null;
|
|
754
|
+
}
|
|
755
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
|
|
756
|
+
return {
|
|
757
|
+
name: call.name,
|
|
758
|
+
args: value
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Read the exact single text block consumed by first-party card derivations.
|
|
763
|
+
* @param block - settled Tool result.
|
|
764
|
+
* @returns its text, or undefined for any other content layout.
|
|
765
|
+
*/
|
|
766
|
+
function singleResultText(block) {
|
|
767
|
+
if (block.content.length !== 1) return void 0;
|
|
768
|
+
const only = block.content[0];
|
|
769
|
+
return only?.type === "text" ? only.text : void 0;
|
|
770
|
+
}
|
|
771
|
+
/** True when a settled terminal card reports a failing exit (mirrors ui-tool). */
|
|
772
|
+
function terminalFailed(model) {
|
|
773
|
+
const { exitCode, signal, running } = model.card;
|
|
774
|
+
return running !== true && (exitCode !== void 0 && exitCode !== 0 || signal !== void 0);
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* Flatten a settled result's content blocks to display text.
|
|
778
|
+
* @param node - settled result node.
|
|
779
|
+
* @returns joined text (may be empty).
|
|
780
|
+
*/
|
|
781
|
+
function resultText(node) {
|
|
782
|
+
const parts = [];
|
|
783
|
+
for (const block of node.content) if (block.type === "text") parts.push(block.text);
|
|
784
|
+
else parts.push(JSON.stringify(block, null, 2));
|
|
785
|
+
if (parts.length === 0 && node.error !== void 0) parts.push(`${node.error.name}: ${node.error.code}`);
|
|
786
|
+
return parts.join("\n");
|
|
787
|
+
}
|
|
788
|
+
function firstLine(text) {
|
|
789
|
+
const nl = text.indexOf("\n");
|
|
790
|
+
return nl === -1 ? text : text.slice(0, nl);
|
|
791
|
+
}
|
|
792
|
+
/** Strip the workspace root from a workspace-rooted absolute path (display only). */
|
|
793
|
+
function relativizeToCwd(text, cwd) {
|
|
794
|
+
if (cwd === void 0 || cwd === "") return text;
|
|
795
|
+
const root = cwd.replace(/[/\\]+$/, "");
|
|
796
|
+
if (text.startsWith(`${root}/`) || text.startsWith(`${root}\\`)) return text.slice(root.length + 1);
|
|
797
|
+
return text;
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Resolve a Workspace-relative path into the Host-facing spelling (local
|
|
801
|
+
* mirror of `@deepseek-ai/dsh-util-workspace-path`'s `resolveWorkspacePath`:
|
|
802
|
+
* that static utility package is not a dynamic client bundle row, so the
|
|
803
|
+
* browser half carries this one-function copy).
|
|
804
|
+
* @param cwd - Session Workspace root, when known.
|
|
805
|
+
* @param path - Absolute or Workspace-relative path.
|
|
806
|
+
* @returns an absolute path when a Workspace root is available, otherwise the original path.
|
|
807
|
+
*/
|
|
808
|
+
function resolveWorkspacePath(cwd, path) {
|
|
809
|
+
if (path.startsWith("/") || /^[A-Za-z]:[/\\]/.test(path) || path.startsWith("\\\\")) return path;
|
|
810
|
+
if (cwd === void 0 || cwd === "") return path;
|
|
811
|
+
return `${cwd.replace(/[/\\]+$/, "")}/${path.replace(/^[/\\]+/, "")}`;
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Abbreviate a POSIX home directory for display (local mirror of
|
|
815
|
+
* `@deepseek-ai/dsh-util-workspace-path`'s `abbreviateHomePath`).
|
|
816
|
+
* @param path - Absolute or already-short display path.
|
|
817
|
+
* @param home - Host account home; absent skips abbreviation.
|
|
818
|
+
* @returns `~` or `~/…` for the POSIX home and its descendants, otherwise `path`.
|
|
819
|
+
*/
|
|
820
|
+
function abbreviateHomePath(path, home) {
|
|
821
|
+
if (home === void 0 || home === "") return path;
|
|
822
|
+
if (/^[A-Za-z]:[/\\]/.test(path) || path.startsWith("\\\\") || /^[A-Za-z]:[/\\]/.test(home) || home.startsWith("\\\\")) return path;
|
|
823
|
+
const root = home.replace(/\/+$/, "");
|
|
824
|
+
if (root === "" || root === "/") return path;
|
|
825
|
+
if (path.replace(/\/+$/, "") === root) return "~";
|
|
826
|
+
if (path.startsWith(`${root}/`)) return `~${path.slice(root.length)}`;
|
|
827
|
+
return path;
|
|
828
|
+
}
|
|
829
|
+
function parseArgs(argsRaw) {
|
|
830
|
+
try {
|
|
831
|
+
const parsed = JSON.parse(argsRaw);
|
|
832
|
+
return typeof parsed === "object" && parsed !== null ? parsed : void 0;
|
|
833
|
+
} catch {
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
function pickString(args, keys) {
|
|
838
|
+
for (const key of keys) {
|
|
839
|
+
const value = args[key];
|
|
840
|
+
if (typeof value === "string" && value !== "") return value;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
/** Summary key preference per row variant (args-derived, mirrors ui-tool). */
|
|
844
|
+
const SUMMARY_KEYS = {
|
|
845
|
+
bash: ["description", "command"],
|
|
846
|
+
read: [
|
|
847
|
+
"path",
|
|
848
|
+
"file_path",
|
|
849
|
+
"url"
|
|
850
|
+
],
|
|
851
|
+
search: [
|
|
852
|
+
"query",
|
|
853
|
+
"pattern",
|
|
854
|
+
"url"
|
|
855
|
+
],
|
|
856
|
+
write: ["path", "file_path"],
|
|
857
|
+
edit: ["path", "file_path"],
|
|
858
|
+
code: ["description"],
|
|
859
|
+
others: []
|
|
860
|
+
};
|
|
861
|
+
function deriveSummary(variant, argsRaw) {
|
|
862
|
+
const parsed = parseArgs(argsRaw);
|
|
863
|
+
if (parsed === void 0) return firstLine(argsRaw);
|
|
864
|
+
if (variant === "search" && Array.isArray(parsed.queries)) {
|
|
865
|
+
const queries = parsed.queries.filter((query) => typeof query === "string" && query !== "");
|
|
866
|
+
if (queries.length > 0) return queries.map(firstLine).join(", ");
|
|
867
|
+
}
|
|
868
|
+
const picked = pickString(parsed, SUMMARY_KEYS[variant]);
|
|
869
|
+
if (picked !== void 0) return firstLine(picked);
|
|
870
|
+
for (const value of Object.values(parsed)) if (typeof value === "string" && value !== "") return firstLine(value);
|
|
871
|
+
return firstLine(argsRaw);
|
|
872
|
+
}
|
|
873
|
+
/** Path keys only — never `url` (web_fetch lands on the read variant). */
|
|
874
|
+
const FILE_PATH_KEYS = ["path", "file_path"];
|
|
875
|
+
/** File-tool variants whose summary may be an openable workspace path. */
|
|
876
|
+
const FILE_PATH_VARIANTS = new Set([
|
|
877
|
+
"read",
|
|
878
|
+
"write",
|
|
879
|
+
"edit"
|
|
880
|
+
]);
|
|
881
|
+
function deriveFilePath(variant, argsRaw) {
|
|
882
|
+
if (!FILE_PATH_VARIANTS.has(variant)) return void 0;
|
|
883
|
+
const parsed = parseArgs(argsRaw);
|
|
884
|
+
if (parsed === void 0) return void 0;
|
|
885
|
+
return pickString(parsed, FILE_PATH_KEYS)?.split("\n")[0];
|
|
886
|
+
}
|
|
887
|
+
function deriveBody(variant, argsRaw) {
|
|
888
|
+
if (argsRaw === "") return null;
|
|
889
|
+
const parsed = parseArgs(argsRaw);
|
|
890
|
+
if (parsed === void 0) return argsRaw;
|
|
891
|
+
if (variant === "code") {
|
|
892
|
+
const code = parsed.code;
|
|
893
|
+
if (typeof code === "string" && code !== "") return code;
|
|
894
|
+
}
|
|
895
|
+
return JSON.stringify(parsed, null, 2);
|
|
896
|
+
}
|
|
897
|
+
/** Derive the row model for one call of a grouped tool. */
|
|
898
|
+
function callRowModel(toolName, block, cwd, home) {
|
|
899
|
+
const done = "kind" in block;
|
|
900
|
+
const argsRaw = (done ? block.call?.argsRaw : block.argsRaw) ?? "";
|
|
901
|
+
const state = !done ? "running" : block.error?.code === "interrupted" ? "stopped" : block.isError ? "error" : "ok";
|
|
902
|
+
const variant = classifyTool(toolName);
|
|
903
|
+
const terminal = terminalCardOf(block, cwd);
|
|
904
|
+
const read = readCardOf(block, cwd, home);
|
|
905
|
+
const diff = diffCardOf(block);
|
|
906
|
+
const search = searchCardOf(block);
|
|
907
|
+
const web = webCardOf(block);
|
|
908
|
+
const base = argsRaw === "" ? block.callId : abbreviateHomePath(relativizeToCwd(deriveSummary(variant, argsRaw), cwd), home);
|
|
909
|
+
const toolTitle = TOOL_TITLES[toolName];
|
|
910
|
+
const argsSummary = variant === "others" && toolName !== "" && toolTitle === void 0 ? `${toolName} · ${base}` : base;
|
|
911
|
+
const filePath = deriveFilePath(variant, argsRaw);
|
|
912
|
+
const output = done ? resultText(block) || null : null;
|
|
913
|
+
const errorSummary = state === "error" && output !== null ? firstLine(output) : null;
|
|
914
|
+
const summary = terminal?.description ?? argsSummary;
|
|
915
|
+
const body = filePath !== void 0 ? null : deriveBody(variant, argsRaw);
|
|
916
|
+
const finalState = state === "ok" && terminal !== null && terminalFailed(terminal) ? "error" : state;
|
|
917
|
+
const expandable = terminal !== null || diff !== null || read !== null || search !== null || web !== null || body !== null || output !== null;
|
|
918
|
+
return {
|
|
919
|
+
state: finalState,
|
|
920
|
+
variant,
|
|
921
|
+
title: toolTitle ?? VARIANT_TITLES[variant],
|
|
922
|
+
summary,
|
|
923
|
+
body,
|
|
924
|
+
output,
|
|
925
|
+
errorSummary,
|
|
926
|
+
filePath,
|
|
927
|
+
expandable,
|
|
928
|
+
terminal,
|
|
929
|
+
diff,
|
|
930
|
+
read,
|
|
931
|
+
search,
|
|
932
|
+
web
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
/** Read-card derivation, or null when this call is not a read card (mirrors ui-tool). */
|
|
936
|
+
function readCardOf(block, cwd, home) {
|
|
937
|
+
if (block.parentCallId !== void 0 || !("kind" in block) || block.isError) return null;
|
|
938
|
+
const parsed = parsedArgsOf(block);
|
|
939
|
+
if (parsed?.name !== "read") return null;
|
|
940
|
+
const { file_path: path, offset, limit } = parsed.args;
|
|
941
|
+
if (typeof path !== "string" || path.trim() === "") return null;
|
|
942
|
+
if (offset !== void 0 && (typeof offset !== "number" || !Number.isInteger(offset) || offset < 1)) return null;
|
|
943
|
+
if (limit !== void 0 && (typeof limit !== "number" || !Number.isInteger(limit) || limit < 1)) return null;
|
|
944
|
+
const meta = readMeta(block.meta);
|
|
945
|
+
if (meta === null) return null;
|
|
946
|
+
const text = singleResultText(block);
|
|
947
|
+
if (text === void 0) return null;
|
|
948
|
+
if (/^<path>[^\n]*<\/path>\n<type>file<\/type>\n<content>\n([\s\S]*)\n<\/content>$/u.exec(text)?.[1] === void 0) return null;
|
|
949
|
+
return {
|
|
950
|
+
label: abbreviateHomePath(relativizeToCwd(meta.path, cwd), home),
|
|
951
|
+
lines: meta.lines,
|
|
952
|
+
totalLines: meta.totalLines,
|
|
953
|
+
lang: meta.lang
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
function readMeta(meta) {
|
|
957
|
+
if (typeof meta !== "object" || meta === null || Array.isArray(meta)) return null;
|
|
958
|
+
const { path, offset, lines, totalLines, lang } = meta;
|
|
959
|
+
if (typeof path !== "string" || typeof offset !== "number" || !Number.isInteger(offset) || offset < 1) return null;
|
|
960
|
+
if (typeof totalLines !== "number" || !Number.isInteger(totalLines) || totalLines < 0 || !Array.isArray(lines)) return null;
|
|
961
|
+
if (lang !== void 0 && typeof lang !== "string") return null;
|
|
962
|
+
const narrowed = [];
|
|
963
|
+
let previous = offset - 1;
|
|
964
|
+
for (const line of lines) {
|
|
965
|
+
if (typeof line !== "object" || line === null || Array.isArray(line)) return null;
|
|
966
|
+
const { number, text } = line;
|
|
967
|
+
if (typeof number !== "number" || !Number.isInteger(number) || number < 1 || number <= previous) return null;
|
|
968
|
+
if (number > totalLines || typeof text !== "string") return null;
|
|
969
|
+
previous = number;
|
|
970
|
+
narrowed.push({
|
|
971
|
+
number,
|
|
972
|
+
text
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
return {
|
|
976
|
+
path,
|
|
977
|
+
lines: narrowed,
|
|
978
|
+
totalLines,
|
|
979
|
+
...lang === void 0 ? {} : { lang }
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
function isValidFiles(files) {
|
|
983
|
+
return Array.isArray(files) && files.every((file) => typeof file === "object" && file !== null && typeof file.path === "string" && Array.isArray(file.matches) && file.matches.every((match) => typeof match === "object" && match !== null && typeof match.lineNumber === "number" && typeof match.line === "string"));
|
|
984
|
+
}
|
|
985
|
+
function flattenContent(content) {
|
|
986
|
+
const text = content.filter((block) => block.type === "text" && typeof block.text === "string").map((block) => block.text).join("\n");
|
|
987
|
+
return text === "" ? void 0 : text;
|
|
988
|
+
}
|
|
989
|
+
/** Search-card derivation, or null when this call is not a search card (mirrors ui-tool). */
|
|
990
|
+
function searchCardOf(block) {
|
|
991
|
+
if (block.parentCallId !== void 0 || !("kind" in block) || block.isError) return null;
|
|
992
|
+
const parsed = parsedArgsOf(block);
|
|
993
|
+
if (parsed === null || parsed.name !== "grep" && parsed.name !== "glob") return null;
|
|
994
|
+
const { pattern, path } = parsed.args;
|
|
995
|
+
if (typeof pattern !== "string") return null;
|
|
996
|
+
if (parsed.name === "grep" && pattern === "") return null;
|
|
997
|
+
if (parsed.name === "glob" && pattern.trim() === "") return null;
|
|
998
|
+
if (path !== void 0 && (typeof path !== "string" || path.trim() === "")) return null;
|
|
999
|
+
if (parsed.name === "grep") {
|
|
1000
|
+
const include = parsed.args.include;
|
|
1001
|
+
if (include !== void 0 && typeof include !== "string") return null;
|
|
1002
|
+
}
|
|
1003
|
+
if (typeof block.meta !== "object" || block.meta === null || Array.isArray(block.meta)) return null;
|
|
1004
|
+
const meta = block.meta;
|
|
1005
|
+
if (typeof meta.truncated !== "boolean") return null;
|
|
1006
|
+
if (typeof meta.total !== "number" || !Number.isInteger(meta.total) || meta.total < 0) return null;
|
|
1007
|
+
const common = {
|
|
1008
|
+
truncated: meta.truncated,
|
|
1009
|
+
total: meta.total
|
|
1010
|
+
};
|
|
1011
|
+
const recovery = meta.truncated ? flattenContent(block.content) : void 0;
|
|
1012
|
+
if (meta.shape === "matches") {
|
|
1013
|
+
if (!isValidFiles(meta.files)) return null;
|
|
1014
|
+
return {
|
|
1015
|
+
recovery,
|
|
1016
|
+
card: {
|
|
1017
|
+
kind: "matches",
|
|
1018
|
+
files: meta.files,
|
|
1019
|
+
...common
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
if (meta.shape !== "paths") return null;
|
|
1024
|
+
if (!Array.isArray(meta.paths) || !meta.paths.every((path$1) => typeof path$1 === "string")) return null;
|
|
1025
|
+
return {
|
|
1026
|
+
recovery,
|
|
1027
|
+
card: {
|
|
1028
|
+
kind: "paths",
|
|
1029
|
+
paths: meta.paths,
|
|
1030
|
+
...common
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
/** Narrow a result metadata `diffs` to well-formed hunks (mirrors ui-tool). */
|
|
1035
|
+
function narrowDiffs(diffs) {
|
|
1036
|
+
if (!Array.isArray(diffs) || diffs.length === 0) return null;
|
|
1037
|
+
const out = [];
|
|
1038
|
+
for (const hunk of diffs) {
|
|
1039
|
+
if (typeof hunk !== "object" || hunk === null) return null;
|
|
1040
|
+
const { path, oldText, newText } = hunk;
|
|
1041
|
+
if (typeof path !== "string") return null;
|
|
1042
|
+
if (oldText !== null && typeof oldText !== "string") return null;
|
|
1043
|
+
if (typeof newText !== "string") return null;
|
|
1044
|
+
out.push({
|
|
1045
|
+
path,
|
|
1046
|
+
oldText,
|
|
1047
|
+
newText
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
return out;
|
|
1051
|
+
}
|
|
1052
|
+
function intendedDiff(block) {
|
|
1053
|
+
const parsed = parsedArgsOf(block);
|
|
1054
|
+
if (parsed === null) return null;
|
|
1055
|
+
if (parsed.name === "str_replace_editor") {
|
|
1056
|
+
const { command, path: path$1, file_text: fileText, old_str: oldText$1, new_str: newText$1 } = parsed.args;
|
|
1057
|
+
if (typeof path$1 !== "string" || path$1.trim() === "") return null;
|
|
1058
|
+
if (command === "create") {
|
|
1059
|
+
if (fileText !== void 0 && typeof fileText !== "string") return null;
|
|
1060
|
+
return {
|
|
1061
|
+
tool: "str_replace_editor",
|
|
1062
|
+
diff: {
|
|
1063
|
+
path: path$1,
|
|
1064
|
+
oldText: null,
|
|
1065
|
+
newText: fileText ?? ""
|
|
1066
|
+
}
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
if (command === "str_replace") {
|
|
1070
|
+
if (oldText$1 !== void 0 && typeof oldText$1 !== "string") return null;
|
|
1071
|
+
if (newText$1 !== void 0 && typeof newText$1 !== "string") return null;
|
|
1072
|
+
return {
|
|
1073
|
+
tool: "str_replace_editor",
|
|
1074
|
+
diff: {
|
|
1075
|
+
path: path$1,
|
|
1076
|
+
oldText: oldText$1 ?? null,
|
|
1077
|
+
newText: newText$1 ?? ""
|
|
1078
|
+
}
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
return null;
|
|
1082
|
+
}
|
|
1083
|
+
const { file_path: path } = parsed.args;
|
|
1084
|
+
if (typeof path !== "string" || path.trim() === "") return null;
|
|
1085
|
+
if (parsed.name === "write") {
|
|
1086
|
+
const { content } = parsed.args;
|
|
1087
|
+
return typeof content === "string" ? {
|
|
1088
|
+
tool: "write",
|
|
1089
|
+
diff: {
|
|
1090
|
+
path,
|
|
1091
|
+
oldText: null,
|
|
1092
|
+
newText: content
|
|
1093
|
+
}
|
|
1094
|
+
} : null;
|
|
1095
|
+
}
|
|
1096
|
+
if (parsed.name !== "edit") return null;
|
|
1097
|
+
const { old_string: oldText, new_string: newText, replace_all: replaceAll } = parsed.args;
|
|
1098
|
+
if (typeof oldText !== "string" || typeof newText !== "string") return null;
|
|
1099
|
+
if (replaceAll !== void 0 && typeof replaceAll !== "boolean") return null;
|
|
1100
|
+
return {
|
|
1101
|
+
tool: "edit",
|
|
1102
|
+
diff: {
|
|
1103
|
+
path,
|
|
1104
|
+
oldText: oldText || null,
|
|
1105
|
+
newText
|
|
1106
|
+
}
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
function appliedDiffs(meta) {
|
|
1110
|
+
if (typeof meta !== "object" || meta === null || Array.isArray(meta)) return null;
|
|
1111
|
+
const diffs = meta.diffs;
|
|
1112
|
+
if (!Array.isArray(diffs)) return null;
|
|
1113
|
+
if (diffs.length === 0) return "empty";
|
|
1114
|
+
return narrowDiffs(diffs);
|
|
1115
|
+
}
|
|
1116
|
+
/** Diff-card derivation, or null when this call is not a diff card (mirrors ui-tool). */
|
|
1117
|
+
function diffCardOf(block) {
|
|
1118
|
+
if (block.parentCallId !== void 0) return null;
|
|
1119
|
+
const intended = intendedDiff(block);
|
|
1120
|
+
if (intended === null) return null;
|
|
1121
|
+
if (!("kind" in block)) return { card: { diffs: [intended.diff] } };
|
|
1122
|
+
if (intended.tool === "str_replace_editor") return null;
|
|
1123
|
+
if (block.isError) return null;
|
|
1124
|
+
const applied = appliedDiffs(block.meta);
|
|
1125
|
+
if (applied === null || applied === "empty") return intended.tool === "write" ? { card: { diffs: [intended.diff] } } : null;
|
|
1126
|
+
return { card: { diffs: applied } };
|
|
1127
|
+
}
|
|
1128
|
+
function shellCallOf(name, args) {
|
|
1129
|
+
if (name !== "bash" && name !== "pwsh") return null;
|
|
1130
|
+
const { command, description, timeoutMs, workdir, run_in_background: background } = args;
|
|
1131
|
+
if (typeof command !== "string" || command.trim() === "") return null;
|
|
1132
|
+
if (timeoutMs !== void 0 && (typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs) || timeoutMs <= 0)) return null;
|
|
1133
|
+
if (workdir !== void 0 && typeof workdir !== "string") return null;
|
|
1134
|
+
if (background !== void 0 && typeof background !== "boolean") return null;
|
|
1135
|
+
if (description === void 0) return {
|
|
1136
|
+
command,
|
|
1137
|
+
description: void 0,
|
|
1138
|
+
workdir: void 0,
|
|
1139
|
+
persistent: true,
|
|
1140
|
+
background: false
|
|
1141
|
+
};
|
|
1142
|
+
if (typeof description !== "string" || description.trim() === "") return null;
|
|
1143
|
+
return {
|
|
1144
|
+
command,
|
|
1145
|
+
description,
|
|
1146
|
+
workdir,
|
|
1147
|
+
persistent: false,
|
|
1148
|
+
background: background === true
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Parse the result text's trailing exit-status marker (mirrors the shell
|
|
1153
|
+
* renderer's literal contract without importing that Host-only package).
|
|
1154
|
+
* @param text - rendered shell result text.
|
|
1155
|
+
* @returns output with a trailing exit-code or signal marker extracted.
|
|
1156
|
+
*/
|
|
1157
|
+
function parseExitStatus(text) {
|
|
1158
|
+
const signal = /\n\[killed by signal: ([^\]\n]+)\]$/.exec(text);
|
|
1159
|
+
if (signal?.[1] !== void 0) return {
|
|
1160
|
+
output: text.slice(0, signal.index),
|
|
1161
|
+
signal: signal[1]
|
|
1162
|
+
};
|
|
1163
|
+
const exit = /\n\[exit code: (\d+)\]$/.exec(text);
|
|
1164
|
+
if (exit?.[1] !== void 0) return {
|
|
1165
|
+
output: text.slice(0, exit.index),
|
|
1166
|
+
exitCode: Number(exit[1])
|
|
1167
|
+
};
|
|
1168
|
+
return {
|
|
1169
|
+
output: text,
|
|
1170
|
+
exitCode: 0
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
/**
|
|
1174
|
+
* Collapse `.` and `..` segments so the prompt label names the directory the
|
|
1175
|
+
* command actually ran in (local mirror of ui-tool's terminal normalization).
|
|
1176
|
+
* @param path - a joined or absolute path, possibly carrying `.`/`..` segments.
|
|
1177
|
+
* @returns the same path with those segments resolved.
|
|
1178
|
+
*/
|
|
1179
|
+
function normalizeSegments(path) {
|
|
1180
|
+
if (!/(?:^|[/\\])\.\.?(?:[/\\]|$)/.test(path)) return path;
|
|
1181
|
+
const separator = path.includes("\\") && !path.includes("/") ? "\\" : "/";
|
|
1182
|
+
const rooted = /^[/\\]/.test(path);
|
|
1183
|
+
const drive = /^[A-Za-z]:/.exec(path)?.[0] ?? "";
|
|
1184
|
+
const body = collapse(path.slice(drive.length), rooted || drive !== "", separator);
|
|
1185
|
+
const leading = rooted ? separator : "";
|
|
1186
|
+
return drive === "" ? `${leading}${body}` : `${drive}${rooted ? leading : separator}${body}`;
|
|
1187
|
+
}
|
|
1188
|
+
function collapse(body, rooted, separator = "/") {
|
|
1189
|
+
const kept = [];
|
|
1190
|
+
for (const segment of body.split(/[/\\]/)) {
|
|
1191
|
+
if (segment === "" || segment === ".") continue;
|
|
1192
|
+
if (segment === "..") {
|
|
1193
|
+
if (kept.length > 0 && kept[kept.length - 1] !== "..") kept.pop();
|
|
1194
|
+
else if (!rooted) kept.push(segment);
|
|
1195
|
+
continue;
|
|
1196
|
+
}
|
|
1197
|
+
kept.push(segment);
|
|
1198
|
+
}
|
|
1199
|
+
return kept.join(separator);
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Resolve a shell call's workdir for display: an absolute path is used as-is,
|
|
1203
|
+
* a relative one joins under the session workspace, and an omitted one IS the
|
|
1204
|
+
* session workspace.
|
|
1205
|
+
* @param workdir - the raw call's workdir, if any.
|
|
1206
|
+
* @param sessionCwd - the session workspace root, if the caller knows it.
|
|
1207
|
+
* @returns the working directory for the prompt label, or undefined.
|
|
1208
|
+
*/
|
|
1209
|
+
function resolveTerminalCwd(workdir, sessionCwd) {
|
|
1210
|
+
if (workdir === void 0 || workdir === "") return sessionCwd;
|
|
1211
|
+
if (sessionCwd === void 0 || sessionCwd === "") return normalizeSegments(workdir);
|
|
1212
|
+
return normalizeSegments(resolveWorkspacePath(sessionCwd, workdir));
|
|
1213
|
+
}
|
|
1214
|
+
/** Terminal-card derivation, or null when this call is not a terminal card (mirrors ui-tool). */
|
|
1215
|
+
function terminalCardOf(block, sessionCwd) {
|
|
1216
|
+
if (block.parentCallId !== void 0) return null;
|
|
1217
|
+
const parsed = parsedArgsOf(block);
|
|
1218
|
+
if (parsed === null) return null;
|
|
1219
|
+
if (parsed.name !== "bash" && parsed.name !== "pwsh") return null;
|
|
1220
|
+
const call = shellCallOf(parsed.name, parsed.args);
|
|
1221
|
+
if (call === null || call.background) return null;
|
|
1222
|
+
const cwd = resolveTerminalCwd(call.workdir, sessionCwd);
|
|
1223
|
+
if (!("kind" in block)) return {
|
|
1224
|
+
description: call.description,
|
|
1225
|
+
card: {
|
|
1226
|
+
command: call.command,
|
|
1227
|
+
cwd,
|
|
1228
|
+
output: void 0,
|
|
1229
|
+
exitCode: void 0,
|
|
1230
|
+
signal: void 0,
|
|
1231
|
+
running: true
|
|
1232
|
+
}
|
|
1233
|
+
};
|
|
1234
|
+
if (block.isError || call.persistent) return null;
|
|
1235
|
+
const output = singleResultText(block);
|
|
1236
|
+
if (output === void 0) return null;
|
|
1237
|
+
const status = parseExitStatus(output);
|
|
1238
|
+
return {
|
|
1239
|
+
description: call.description,
|
|
1240
|
+
card: {
|
|
1241
|
+
command: call.command,
|
|
1242
|
+
cwd,
|
|
1243
|
+
output: status.output,
|
|
1244
|
+
exitCode: status.exitCode,
|
|
1245
|
+
signal: status.signal,
|
|
1246
|
+
running: false
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
/** Web-card derivation, or null when this call is not a web card (mirrors ui-tool). */
|
|
1251
|
+
function webCardOf(block) {
|
|
1252
|
+
if (block.parentCallId !== void 0 || !("kind" in block) || block.isError) return null;
|
|
1253
|
+
const parsed = parsedArgsOf(block);
|
|
1254
|
+
if (parsed === null) return null;
|
|
1255
|
+
if (parsed.name === "web_search") {
|
|
1256
|
+
const { queries } = parsed.args;
|
|
1257
|
+
if (!Array.isArray(queries) || queries.length === 0) return null;
|
|
1258
|
+
if (!queries.every((query) => typeof query === "string" && query.trim() !== "")) return null;
|
|
1259
|
+
} else if (parsed.name === "web_fetch") {
|
|
1260
|
+
const { url } = parsed.args;
|
|
1261
|
+
if (typeof url !== "string" || url.trim() === "") return null;
|
|
1262
|
+
} else return null;
|
|
1263
|
+
if (typeof block.meta !== "object" || block.meta === null || Array.isArray(block.meta)) return null;
|
|
1264
|
+
const meta = block.meta;
|
|
1265
|
+
if (typeof meta.truncated !== "boolean") return null;
|
|
1266
|
+
if (parsed.name === "web_search") {
|
|
1267
|
+
const sources = webSources(meta.sources);
|
|
1268
|
+
if (sources === null || meta.answer !== void 0 && typeof meta.answer !== "string") return null;
|
|
1269
|
+
return {
|
|
1270
|
+
kind: "search",
|
|
1271
|
+
answer: meta.answer,
|
|
1272
|
+
sources,
|
|
1273
|
+
truncated: meta.truncated
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1276
|
+
if (typeof meta.url !== "string") return null;
|
|
1277
|
+
if (typeof meta.statusCode !== "number" || !Number.isInteger(meta.statusCode)) return null;
|
|
1278
|
+
return {
|
|
1279
|
+
kind: "fetch",
|
|
1280
|
+
url: meta.url,
|
|
1281
|
+
statusCode: meta.statusCode,
|
|
1282
|
+
truncated: meta.truncated
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
function webSources(value) {
|
|
1286
|
+
if (!Array.isArray(value)) return null;
|
|
1287
|
+
const sources = [];
|
|
1288
|
+
for (const source of value) {
|
|
1289
|
+
if (typeof source !== "object" || source === null) return null;
|
|
1290
|
+
const { url, title, snippet, publishedAt } = source;
|
|
1291
|
+
if (typeof url !== "string") return null;
|
|
1292
|
+
if (title !== void 0 && typeof title !== "string") return null;
|
|
1293
|
+
if (snippet !== void 0 && typeof snippet !== "string") return null;
|
|
1294
|
+
if (publishedAt !== void 0 && typeof publishedAt !== "string") return null;
|
|
1295
|
+
sources.push({
|
|
1296
|
+
url,
|
|
1297
|
+
...title === void 0 ? {} : { title },
|
|
1298
|
+
...snippet === void 0 ? {} : { snippet },
|
|
1299
|
+
...publishedAt === void 0 ? {} : { publishedAt }
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1302
|
+
return sources;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
//#endregion
|
|
1306
|
+
//#region src/client/merge-run.ts
|
|
1307
|
+
/** Tool-call node kind registered by ui-chat's built-in tool definition. */
|
|
1308
|
+
const TOOL_CALL_KIND = "tool-call";
|
|
1309
|
+
/** Extract a root call block from any chat node, when it is a tool-call node. */
|
|
1310
|
+
function toolRootOf(node) {
|
|
1311
|
+
if (node.kind !== TOOL_CALL_KIND) return null;
|
|
1312
|
+
const root = node.data.root;
|
|
1313
|
+
return typeof root === "object" && root !== null ? root : null;
|
|
1314
|
+
}
|
|
1315
|
+
/** The wire tool name of a call in either lifecycle form (mirrors ui-tool). */
|
|
1316
|
+
function callNameOf(block) {
|
|
1317
|
+
return "kind" in block ? block.call?.name ?? "" : block.name;
|
|
1318
|
+
}
|
|
1319
|
+
/** Whether the call's wire name is one of the grouped tools (empty = all). */
|
|
1320
|
+
function isGroupedTool(name, tools) {
|
|
1321
|
+
return tools.length === 0 || tools.includes(name);
|
|
1322
|
+
}
|
|
1323
|
+
/** Step identity of a node's location; undefined when the node is not step-bound. */
|
|
1324
|
+
function stepIdOf(node) {
|
|
1325
|
+
const location = node.location;
|
|
1326
|
+
return location.kind === "step" ? `${location.turn.turn}:${location.step.step}` : void 0;
|
|
1327
|
+
}
|
|
1328
|
+
/**
|
|
1329
|
+
* Compute the merged group this call belongs to.
|
|
1330
|
+
*
|
|
1331
|
+
* 1. Locates this call's node in the chat order; null when it is not a chat
|
|
1332
|
+
* tool-call node (e.g. a read dispatched as a subcall). The node key
|
|
1333
|
+
* format stays a ui-conversation internal, so the seat finds itself by
|
|
1334
|
+
* scanning the store for the tool-call node owning its call id instead of
|
|
1335
|
+
* recomputing the key.
|
|
1336
|
+
* 2. Walks backward/forward to the maximal consecutive run containing it. A
|
|
1337
|
+
* call continues the run when it is a grouped tool AND same-tool-same-run:
|
|
1338
|
+
* the identical wire name, or a sibling of the same known variant family
|
|
1339
|
+
* (grep+glob, bash+pwsh, read+web_fetch…). Unknown names (variant
|
|
1340
|
+
* `others`) only merge with themselves, so unrelated tools never share a
|
|
1341
|
+
* card (`adjacent`: any consecutive run; `step`: same agent step as this
|
|
1342
|
+
* call).
|
|
1343
|
+
* 3. Partitions the run into `maxGroupSize`-sized groups; this call is the
|
|
1344
|
+
* group's first only when it heads one of those partitions. Truncation
|
|
1345
|
+
* therefore never orphans a call: the excess starts its own group.
|
|
1346
|
+
*
|
|
1347
|
+
* @param order - chat node key order.
|
|
1348
|
+
* @param nodes - chat node store.
|
|
1349
|
+
* @param myCallId - the call id of the seat asking about itself.
|
|
1350
|
+
* @param tools - grouped wire tool names; empty means every tool.
|
|
1351
|
+
* @param groupBy - grouping mode.
|
|
1352
|
+
* @param maxGroupSize - per-group cap.
|
|
1353
|
+
* @returns the group partition, or null when the call is not a chat tool-call node.
|
|
1354
|
+
*/
|
|
1355
|
+
function readRun(order, nodes, myCallId, tools, groupBy, maxGroupSize) {
|
|
1356
|
+
const myIndex = myIndexOf(order, nodes, myCallId);
|
|
1357
|
+
if (myIndex < 0) return null;
|
|
1358
|
+
const myRoot = rootAtNode(order, nodes, myIndex);
|
|
1359
|
+
if (myRoot === null) return null;
|
|
1360
|
+
const myName = callNameOf(myRoot);
|
|
1361
|
+
const myVariant = classifyTool(myName);
|
|
1362
|
+
const size = Math.max(1, maxGroupSize);
|
|
1363
|
+
const rootAt = (index) => rootAtNode(order, nodes, index);
|
|
1364
|
+
const myStep = groupBy === "step" ? stepIdOfNodeAt(order, nodes, myIndex) : void 0;
|
|
1365
|
+
const inGroup = (index) => {
|
|
1366
|
+
const root = rootAt(index);
|
|
1367
|
+
if (root === null || !isGroupedTool(callNameOf(root), tools)) return false;
|
|
1368
|
+
const name = callNameOf(root);
|
|
1369
|
+
if (name !== myName) {
|
|
1370
|
+
if (myVariant === "others" || classifyTool(name) !== myVariant) return false;
|
|
1371
|
+
}
|
|
1372
|
+
if (groupBy !== "step") return true;
|
|
1373
|
+
return myStep !== void 0 && stepIdOfNodeAt(order, nodes, index) === myStep;
|
|
1374
|
+
};
|
|
1375
|
+
let start = myIndex;
|
|
1376
|
+
while (start > 0 && inGroup(start - 1)) start--;
|
|
1377
|
+
let end = myIndex;
|
|
1378
|
+
while (end < order.length - 1 && inGroup(end + 1)) end++;
|
|
1379
|
+
const groupStart = start + Math.floor((myIndex - start) / size) * size;
|
|
1380
|
+
const groupEnd = Math.min(groupStart + size, end + 1);
|
|
1381
|
+
const blocks = [];
|
|
1382
|
+
for (let index = groupStart; index < groupEnd; index++) {
|
|
1383
|
+
const root = rootAt(index);
|
|
1384
|
+
if (root !== null) blocks.push(root);
|
|
1385
|
+
}
|
|
1386
|
+
return {
|
|
1387
|
+
isFirst: myIndex === groupStart,
|
|
1388
|
+
blocks
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1391
|
+
/** Index in the chat order of the tool-call node owning `callId`; -1 when absent. */
|
|
1392
|
+
function myIndexOf(order, nodes, callId) {
|
|
1393
|
+
for (let index = 0; index < order.length; index++) {
|
|
1394
|
+
const key = order[index];
|
|
1395
|
+
if (key === void 0) continue;
|
|
1396
|
+
const node = nodes.get(key);
|
|
1397
|
+
if (node?.kind !== TOOL_CALL_KIND) continue;
|
|
1398
|
+
if (toolRootOf(node)?.callId === callId) return index;
|
|
1399
|
+
}
|
|
1400
|
+
return -1;
|
|
1401
|
+
}
|
|
1402
|
+
function rootAtNode(order, nodes, index) {
|
|
1403
|
+
const key = order[index];
|
|
1404
|
+
const node = key === void 0 ? void 0 : nodes.get(key);
|
|
1405
|
+
return node === void 0 ? null : toolRootOf(node);
|
|
1406
|
+
}
|
|
1407
|
+
function stepIdOfNodeAt(order, nodes, index) {
|
|
1408
|
+
const key = order[index];
|
|
1409
|
+
const node = key === void 0 ? void 0 : nodes.get(key);
|
|
1410
|
+
return node === void 0 ? void 0 : stepIdOf(node);
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
//#endregion
|
|
1414
|
+
//#region src/client/rows.tsx
|
|
1415
|
+
/** Chat rows show a capped card; the details panel stays the full-height surface. */
|
|
1416
|
+
const CHAT_READ_MAX_LINES = 8;
|
|
1417
|
+
const CHAT_SEARCH_MAX_LINES = 8;
|
|
1418
|
+
const CHAT_DIFF_MAX_LINES = 8;
|
|
1419
|
+
/** Variant leading icons (figma table); all glyphs render at 14 inside the 16px leading box. */
|
|
1420
|
+
const VARIANT_ICONS = {
|
|
1421
|
+
search: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16, { size: 14 }),
|
|
1422
|
+
read: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.IconBrowseOutline16, { size: 14 }),
|
|
1423
|
+
bash: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.IconApiOutline14, { size: 14 }),
|
|
1424
|
+
write: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, { size: 14 }),
|
|
1425
|
+
edit: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, { size: 14 }),
|
|
1426
|
+
code: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.IconCodeOutline16, { size: 14 }),
|
|
1427
|
+
others: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.IconSparkle16, { size: 14 })
|
|
1428
|
+
};
|
|
1429
|
+
/**
|
|
1430
|
+
* Per-variant locale key for the merged-count summary (`{n} Files`, `{n}
|
|
1431
|
+
* Commands`, …). Replaces the first call's file path on the main row when the
|
|
1432
|
+
* run merges more than one call, so the main row reads `Read · 5 Files` and
|
|
1433
|
+
* the file paths move to the collapsed child rows.
|
|
1434
|
+
*/
|
|
1435
|
+
const VARIANT_COUNT_KEY = {
|
|
1436
|
+
read: "countFiles",
|
|
1437
|
+
write: "countFiles",
|
|
1438
|
+
edit: "countFiles",
|
|
1439
|
+
search: "countQueries",
|
|
1440
|
+
bash: "countCommands",
|
|
1441
|
+
code: "countPrograms",
|
|
1442
|
+
others: "countCalls"
|
|
1443
|
+
};
|
|
1444
|
+
/** Leading-slot state substitution, mirroring the shipped row. */
|
|
1445
|
+
function leadingFor(state, icon) {
|
|
1446
|
+
switch (state) {
|
|
1447
|
+
case "error": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "error" });
|
|
1448
|
+
case "stopped": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "warning" });
|
|
1449
|
+
default: return icon;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
/** Visually hidden run-state label (the StateDot and sweep are colour-only). */
|
|
1453
|
+
function stateStatus(state, t) {
|
|
1454
|
+
switch (state) {
|
|
1455
|
+
case "running": return t("running");
|
|
1456
|
+
case "error": return t("failed");
|
|
1457
|
+
case "stopped": return t("stopped");
|
|
1458
|
+
default: return null;
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
/** TerminalBlock display copy from the plugin's own dictionary. */
|
|
1462
|
+
function terminalLabels(t) {
|
|
1463
|
+
return {
|
|
1464
|
+
signal: (signal) => t("terminal.signal", { signal }),
|
|
1465
|
+
exitCode: (code) => t("terminal.exitCode", { code }),
|
|
1466
|
+
running: t("terminal.running"),
|
|
1467
|
+
failed: t("terminal.failed"),
|
|
1468
|
+
done: t("terminal.done"),
|
|
1469
|
+
copy: t("terminal.copy"),
|
|
1470
|
+
copied: t("terminal.copied"),
|
|
1471
|
+
noOutput: t("terminal.noOutput"),
|
|
1472
|
+
collapseAria: t("terminal.collapseAria"),
|
|
1473
|
+
collapse: t("terminal.collapse"),
|
|
1474
|
+
expandAria: (hidden) => t("terminal.expandAria", { n: hidden }),
|
|
1475
|
+
expand: (hidden) => t("terminal.expandRest", { n: hidden })
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1478
|
+
/** ReadBlock display copy from the plugin's own dictionary. */
|
|
1479
|
+
function readLabels(t) {
|
|
1480
|
+
return {
|
|
1481
|
+
window: (shown, total) => t("read.window", {
|
|
1482
|
+
shown,
|
|
1483
|
+
total
|
|
1484
|
+
}),
|
|
1485
|
+
copy: t("copy"),
|
|
1486
|
+
copied: t("copied"),
|
|
1487
|
+
collapseAria: t("read.collapseAria"),
|
|
1488
|
+
expandAria: (count) => t("read.expandAria", { count }),
|
|
1489
|
+
collapse: t("collapse"),
|
|
1490
|
+
expand: (count) => t("read.expandRest", { count })
|
|
1491
|
+
};
|
|
1492
|
+
}
|
|
1493
|
+
/** SearchBlock display copy from the plugin's own dictionary. */
|
|
1494
|
+
function searchLabels(t) {
|
|
1495
|
+
return {
|
|
1496
|
+
pathsSummary: (shown, total, truncated) => t(truncated ? "search.paths.truncated" : "search.paths", {
|
|
1497
|
+
shown,
|
|
1498
|
+
total
|
|
1499
|
+
}),
|
|
1500
|
+
matchesSummary: (shown, total, files, truncated) => t(truncated ? "search.matches.truncated" : "search.matches", {
|
|
1501
|
+
shown,
|
|
1502
|
+
total,
|
|
1503
|
+
files
|
|
1504
|
+
}),
|
|
1505
|
+
copy: t("copy"),
|
|
1506
|
+
copied: t("copied"),
|
|
1507
|
+
noResults: t("search.noResults"),
|
|
1508
|
+
collapseAria: t("search.collapseAria"),
|
|
1509
|
+
expandAria: (count) => t("search.expandAria", { count }),
|
|
1510
|
+
collapse: t("collapse"),
|
|
1511
|
+
expand: (count) => t("search.expandRest", { count })
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
/** DiffBlock display copy from the plugin's own dictionary. */
|
|
1515
|
+
function diffLabels(t) {
|
|
1516
|
+
return {
|
|
1517
|
+
copy: t("copy"),
|
|
1518
|
+
copied: t("copied"),
|
|
1519
|
+
collapseAria: t("diff.collapseAria"),
|
|
1520
|
+
expandAria: (count) => t("diff.expandAria", { count }),
|
|
1521
|
+
collapse: t("collapse"),
|
|
1522
|
+
expand: (count) => t("diff.expandRest", { count }),
|
|
1523
|
+
files: (count) => t("diff.files", { count })
|
|
1524
|
+
};
|
|
1525
|
+
}
|
|
1526
|
+
/** WebBlock display copy from the plugin's own dictionary. */
|
|
1527
|
+
function webLabels(t) {
|
|
1528
|
+
return {
|
|
1529
|
+
noResults: t("web.noResults"),
|
|
1530
|
+
sourcesTruncated: t("web.sourcesTruncated"),
|
|
1531
|
+
http: t("web.http"),
|
|
1532
|
+
contentTruncated: t("web.contentTruncated"),
|
|
1533
|
+
markdown: {
|
|
1534
|
+
code: {
|
|
1535
|
+
copyLabel: t("copy"),
|
|
1536
|
+
copiedLabel: t("copied")
|
|
1537
|
+
},
|
|
1538
|
+
footnotes: t("markdown.footnotes")
|
|
1539
|
+
}
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1542
|
+
/** One call's expanded-body card, mirroring the built-in ToolRow body. */
|
|
1543
|
+
function CardBody({ model, home, t }) {
|
|
1544
|
+
if (model.terminal !== null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.TerminalBlock, {
|
|
1545
|
+
...model.terminal.card,
|
|
1546
|
+
home,
|
|
1547
|
+
maxLines: Infinity,
|
|
1548
|
+
labels: terminalLabels(t)
|
|
1549
|
+
});
|
|
1550
|
+
if (model.diff !== null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.DiffBlock, {
|
|
1551
|
+
...model.diff.card,
|
|
1552
|
+
labels: diffLabels(t),
|
|
1553
|
+
maxLines: CHAT_DIFF_MAX_LINES
|
|
1554
|
+
});
|
|
1555
|
+
if (model.read !== null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.ReadBlock, {
|
|
1556
|
+
...model.read,
|
|
1557
|
+
labels: readLabels(t),
|
|
1558
|
+
maxLines: CHAT_READ_MAX_LINES
|
|
1559
|
+
});
|
|
1560
|
+
if (model.search !== null) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.SearchBlock, {
|
|
1561
|
+
...model.search.card,
|
|
1562
|
+
labels: searchLabels(t),
|
|
1563
|
+
maxLines: CHAT_SEARCH_MAX_LINES
|
|
1564
|
+
}), model.search.recovery !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1565
|
+
className: "mtc-recovery",
|
|
1566
|
+
children: model.search.recovery
|
|
1567
|
+
})] });
|
|
1568
|
+
if (model.web !== null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.WebBlock, {
|
|
1569
|
+
...model.web,
|
|
1570
|
+
labels: webLabels(t)
|
|
1571
|
+
});
|
|
1572
|
+
const hasBody = model.body !== null;
|
|
1573
|
+
const hasOutput = model.output !== null;
|
|
1574
|
+
if (!hasBody && !hasOutput) return null;
|
|
1575
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1576
|
+
className: "mtc-io-card",
|
|
1577
|
+
children: [
|
|
1578
|
+
hasBody && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1579
|
+
className: "mtc-io-section",
|
|
1580
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1581
|
+
className: "mtc-io-label",
|
|
1582
|
+
children: "IN"
|
|
1583
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1584
|
+
className: "mtc-io-text",
|
|
1585
|
+
children: model.body
|
|
1586
|
+
})]
|
|
1587
|
+
}),
|
|
1588
|
+
hasBody && hasOutput && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1589
|
+
className: "mtc-io-divider",
|
|
1590
|
+
"aria-hidden": true
|
|
1591
|
+
}),
|
|
1592
|
+
hasOutput && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1593
|
+
className: "mtc-io-section",
|
|
1594
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1595
|
+
className: "mtc-io-label",
|
|
1596
|
+
children: "OUT"
|
|
1597
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1598
|
+
className: "mtc-io-text",
|
|
1599
|
+
"data-error": model.state === "error" || void 0,
|
|
1600
|
+
children: model.output
|
|
1601
|
+
})]
|
|
1602
|
+
})
|
|
1603
|
+
]
|
|
1604
|
+
});
|
|
1605
|
+
}
|
|
1606
|
+
/**
|
|
1607
|
+
* The run's main card: the first call's chrome (variant title/icon + state)
|
|
1608
|
+
* plus, for a single call, its expandable content card. For a merged run the
|
|
1609
|
+
* main row's collapsed summary is the count (`Read · 5 Files`) and the
|
|
1610
|
+
* expanded body is the child-rows block (passed in as `children`); the first
|
|
1611
|
+
* call is rendered as the first child row so every file path lands on a child
|
|
1612
|
+
* row, never on the main row.
|
|
1613
|
+
*/
|
|
1614
|
+
const RowCard = (0, react.memo)(function RowCard$1({ toolName, block, cwd, home, openFile, inspect, t, mergedCount, children }) {
|
|
1615
|
+
const model = callRowModel(toolName, block, cwd, home);
|
|
1616
|
+
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
1617
|
+
const hasChildren = mergedCount > 0;
|
|
1618
|
+
const expandable = model.expandable || hasChildren;
|
|
1619
|
+
const open = expanded && expandable;
|
|
1620
|
+
const status = stateStatus(model.state, t);
|
|
1621
|
+
const failureLine = model.state === "error" ? model.errorSummary ?? null : null;
|
|
1622
|
+
const summaryText = hasChildren && failureLine === null ? t(VARIANT_COUNT_KEY[model.variant], { n: String(mergedCount + 1) }) : failureLine ?? model.summary;
|
|
1623
|
+
const fileLink = !hasChildren && model.filePath !== void 0 && openFile !== void 0 && failureLine === null;
|
|
1624
|
+
const openFileClick = (event) => {
|
|
1625
|
+
event.stopPropagation();
|
|
1626
|
+
if (model.filePath !== void 0) openFile(model.filePath);
|
|
1627
|
+
};
|
|
1628
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1629
|
+
className: "mtc-row",
|
|
1630
|
+
"data-state": model.state,
|
|
1631
|
+
"data-variant": model.variant,
|
|
1632
|
+
"data-merged": hasChildren || void 0,
|
|
1633
|
+
children: [
|
|
1634
|
+
status !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1635
|
+
className: "mtc-visually-hidden",
|
|
1636
|
+
children: status
|
|
1637
|
+
}),
|
|
1638
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__deepseek_ai_dsh_client_ui_primitives.DisclosureRow, {
|
|
1639
|
+
rowClassName: "mtc-title-row",
|
|
1640
|
+
titleClassName: "mtc-title",
|
|
1641
|
+
leadingClassName: "mtc-leading",
|
|
1642
|
+
chevronClassName: "mtc-chevron",
|
|
1643
|
+
icon: leadingFor(model.state, VARIANT_ICONS[model.variant]),
|
|
1644
|
+
title: model.title,
|
|
1645
|
+
open,
|
|
1646
|
+
expandable,
|
|
1647
|
+
expandOnRowClick: true,
|
|
1648
|
+
keepContentWhenOpen: true,
|
|
1649
|
+
onToggle: () => {
|
|
1650
|
+
setExpanded((value) => !value);
|
|
1651
|
+
},
|
|
1652
|
+
collapsedContent: summaryText !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1653
|
+
className: "mtc-sep",
|
|
1654
|
+
"aria-hidden": true
|
|
1655
|
+
}), fileLink ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1656
|
+
type: "button",
|
|
1657
|
+
className: "mtc-summary-link",
|
|
1658
|
+
onClick: openFileClick,
|
|
1659
|
+
children: summaryText
|
|
1660
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1661
|
+
className: "mtc-summary",
|
|
1662
|
+
children: summaryText
|
|
1663
|
+
})] }),
|
|
1664
|
+
children: !hasChildren && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1665
|
+
className: "mtc-card-body",
|
|
1666
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardBody, {
|
|
1667
|
+
model,
|
|
1668
|
+
home,
|
|
1669
|
+
t
|
|
1670
|
+
}), inspect !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1671
|
+
type: "button",
|
|
1672
|
+
className: "mtc-inspect",
|
|
1673
|
+
onClick: inspect,
|
|
1674
|
+
children: "Inspect"
|
|
1675
|
+
})]
|
|
1676
|
+
})
|
|
1677
|
+
}),
|
|
1678
|
+
hasChildren && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1679
|
+
className: "mtc-children-collapse",
|
|
1680
|
+
"data-open": open || void 0,
|
|
1681
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1682
|
+
className: "mtc-children",
|
|
1683
|
+
children
|
|
1684
|
+
})
|
|
1685
|
+
}),
|
|
1686
|
+
hasChildren && open && inspect !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1687
|
+
type: "button",
|
|
1688
|
+
className: "mtc-inspect",
|
|
1689
|
+
onClick: inspect,
|
|
1690
|
+
children: "Inspect"
|
|
1691
|
+
})
|
|
1692
|
+
]
|
|
1693
|
+
});
|
|
1694
|
+
});
|
|
1695
|
+
/**
|
|
1696
|
+
* One compact continuation row: the main row's tail structure ([sep dot][path]).
|
|
1697
|
+
* An expandable call toggles the inline content card on click (mirroring the
|
|
1698
|
+
* main row's whole-row disclosure); a read/write/edit-family path additionally
|
|
1699
|
+
* renders as an open-file link (the sidebar preview) that stops propagation,
|
|
1700
|
+
* exactly like the main row's summary link.
|
|
1701
|
+
*/
|
|
1702
|
+
const ChildRow = (0, react.memo)(function ChildRow$1({ toolName, block, cwd, home, openFile, t }) {
|
|
1703
|
+
const model = callRowModel(toolName, block, cwd, home);
|
|
1704
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
1705
|
+
const stateLabel = stateStatus(model.state, t);
|
|
1706
|
+
const expandable = model.expandable;
|
|
1707
|
+
const toggle = () => {
|
|
1708
|
+
setOpen((value) => !value);
|
|
1709
|
+
};
|
|
1710
|
+
const openFileClick = (event) => {
|
|
1711
|
+
event.stopPropagation();
|
|
1712
|
+
if (model.filePath !== void 0) openFile(model.filePath);
|
|
1713
|
+
};
|
|
1714
|
+
const onRowKeyDown = (event) => {
|
|
1715
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
1716
|
+
event.preventDefault();
|
|
1717
|
+
toggle();
|
|
1718
|
+
}
|
|
1719
|
+
};
|
|
1720
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1721
|
+
className: "mtc-child",
|
|
1722
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1723
|
+
className: "mtc-child-row",
|
|
1724
|
+
"data-open": expandable && open || void 0,
|
|
1725
|
+
"data-static": expandable ? void 0 : true,
|
|
1726
|
+
role: expandable ? "button" : void 0,
|
|
1727
|
+
tabIndex: expandable ? 0 : void 0,
|
|
1728
|
+
"aria-expanded": expandable ? open : void 0,
|
|
1729
|
+
onClick: expandable ? toggle : void 0,
|
|
1730
|
+
onKeyDown: expandable ? onRowKeyDown : void 0,
|
|
1731
|
+
children: [
|
|
1732
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1733
|
+
className: "mtc-sep",
|
|
1734
|
+
"aria-hidden": true
|
|
1735
|
+
}),
|
|
1736
|
+
model.filePath !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1737
|
+
type: "button",
|
|
1738
|
+
className: "mtc-child-path-link",
|
|
1739
|
+
onClick: openFileClick,
|
|
1740
|
+
children: model.summary
|
|
1741
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1742
|
+
className: "mtc-child-path",
|
|
1743
|
+
children: model.summary
|
|
1744
|
+
}),
|
|
1745
|
+
stateLabel !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1746
|
+
className: "mtc-child-state",
|
|
1747
|
+
"data-error": model.state === "error" || void 0,
|
|
1748
|
+
children: stateLabel
|
|
1749
|
+
})
|
|
1750
|
+
]
|
|
1751
|
+
}), expandable && open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1752
|
+
className: "mtc-child-body",
|
|
1753
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardBody, {
|
|
1754
|
+
model,
|
|
1755
|
+
home,
|
|
1756
|
+
t
|
|
1757
|
+
})
|
|
1758
|
+
})]
|
|
1759
|
+
});
|
|
1760
|
+
});
|
|
1761
|
+
/**
|
|
1762
|
+
* The shadowed toolview: renders the merged run card for the run's first call,
|
|
1763
|
+
* nothing for continuation calls, and a plain single row when this call is not
|
|
1764
|
+
* a chat tool-call node.
|
|
1765
|
+
*
|
|
1766
|
+
* Child-row alignment is measured at runtime, not hardcoded: the main row's
|
|
1767
|
+
* separator dot sits after a variable-width title ("Read"/"Search"/"Bash"/…),
|
|
1768
|
+
* so its column depends on the rendered font. A layout effect measures the
|
|
1769
|
+
* dot's offset from the card root (once, plus on reflow via ResizeObserver)
|
|
1770
|
+
* and indents the children so their dots and paths land on the main row's
|
|
1771
|
+
* columns — no font/title constants to keep in sync.
|
|
1772
|
+
*/
|
|
1773
|
+
function MergedToolRow({ callId, toolName, block, cwd, home, openFile, inspect, t, cfg, useChat }) {
|
|
1774
|
+
const run = useChat((snapshot) => readRun(snapshot.order, snapshot.nodes, callId, cfg.tools, cfg.groupBy, cfg.maxGroupSize));
|
|
1775
|
+
const rootRef = (0, react.useRef)(null);
|
|
1776
|
+
/** Main separator dot's left offset from the card root; null before first measure. */
|
|
1777
|
+
const [sepLeft, setSepLeft] = (0, react.useState)(null);
|
|
1778
|
+
(0, react.useLayoutEffect)(() => {
|
|
1779
|
+
const root = rootRef.current;
|
|
1780
|
+
if (root === null) return;
|
|
1781
|
+
const sep = root.querySelector(".mtc-row .mtc-sep");
|
|
1782
|
+
if (sep === null) return;
|
|
1783
|
+
const measure = () => {
|
|
1784
|
+
setSepLeft(Math.round(sep.getBoundingClientRect().left - root.getBoundingClientRect().left));
|
|
1785
|
+
};
|
|
1786
|
+
measure();
|
|
1787
|
+
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(measure);
|
|
1788
|
+
observer?.observe(root);
|
|
1789
|
+
return () => {
|
|
1790
|
+
observer?.disconnect();
|
|
1791
|
+
};
|
|
1792
|
+
}, [run === null ? null : run.blocks[0]?.callId ?? null]);
|
|
1793
|
+
if (run === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
|
|
1794
|
+
toolName,
|
|
1795
|
+
block,
|
|
1796
|
+
cwd,
|
|
1797
|
+
home,
|
|
1798
|
+
openFile,
|
|
1799
|
+
inspect,
|
|
1800
|
+
t,
|
|
1801
|
+
mergedCount: 0
|
|
1802
|
+
});
|
|
1803
|
+
if (!run.isFirst) return null;
|
|
1804
|
+
const hasChildren = run.blocks.length > 1;
|
|
1805
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1806
|
+
className: "mtc-root",
|
|
1807
|
+
"data-tool": toolName,
|
|
1808
|
+
ref: rootRef,
|
|
1809
|
+
style: sepLeft === null ? void 0 : { ["--mtc-sep-left"]: `${sepLeft}px` },
|
|
1810
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
|
|
1811
|
+
toolName,
|
|
1812
|
+
block: run.blocks[0] ?? block,
|
|
1813
|
+
cwd,
|
|
1814
|
+
home,
|
|
1815
|
+
openFile,
|
|
1816
|
+
inspect,
|
|
1817
|
+
t,
|
|
1818
|
+
mergedCount: run.blocks.length - 1,
|
|
1819
|
+
children: hasChildren && run.blocks.map((child) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChildRow, {
|
|
1820
|
+
toolName,
|
|
1821
|
+
block: child,
|
|
1822
|
+
cwd,
|
|
1823
|
+
home,
|
|
1824
|
+
openFile,
|
|
1825
|
+
t
|
|
1826
|
+
}, child.callId))
|
|
1827
|
+
})
|
|
1828
|
+
});
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
//#endregion
|
|
1832
|
+
//#region src/client/styles.ts
|
|
1833
|
+
/**
|
|
1834
|
+
* One scoped stylesheet injected for the lifetime of the client activation.
|
|
1835
|
+
*
|
|
1836
|
+
* Two jobs:
|
|
1837
|
+
* 1. The empty-seat collapse rule: the shadowed toolview renders `null` for
|
|
1838
|
+
* every non-first call of a merged run. The built-in `ToolCallTree` still
|
|
1839
|
+
* wraps that null in its `.callRow` div, and the renderer wraps every
|
|
1840
|
+
* toolview in an empty `<div data-slot="tool.call.toolview">` (display:
|
|
1841
|
+
* contents), so the seat's `.flowItem` is never `:empty` itself and the
|
|
1842
|
+
* built-in `.flowItem:empty { display:none }` rule does not fire. This
|
|
1843
|
+
* rule extends the same intent ("a renderer may decline its row") to a
|
|
1844
|
+
* tool seat whose toolview rendered nothing.
|
|
1845
|
+
* 2. The plugin's own `.mtc-*` chrome for the merged card and its child rows.
|
|
1846
|
+
*
|
|
1847
|
+
* All colors come from the shared `--dsw-*` tokens (never literals).
|
|
1848
|
+
*/
|
|
1849
|
+
const CSS = `
|
|
1850
|
+
/* A tool-call seat whose toolview declined to render (merged-run continuation
|
|
1851
|
+
calls) must not consume the flow column's gap. The empty toolview slot
|
|
1852
|
+
wrapper is the decline signal; the callRow around it always exists. */
|
|
1853
|
+
[data-chat-flow-kind="tool-call"]:has([data-slot="tool.call.toolview"]:empty) { display: none; }
|
|
1854
|
+
|
|
1855
|
+
.mtc-root { display: flex; flex-direction: column; min-width: 0; }
|
|
1856
|
+
.mtc-row { display: flex; flex-direction: column; min-width: 0; }
|
|
1857
|
+
.mtc-row[data-state='running'] .mtc-title-row { position: relative; overflow: hidden; }
|
|
1858
|
+
.mtc-row[data-state='running'] .mtc-title-row::after {
|
|
1859
|
+
content: '';
|
|
1860
|
+
position: absolute;
|
|
1861
|
+
top: 0; bottom: 0; left: 0;
|
|
1862
|
+
width: 300px;
|
|
1863
|
+
background: linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--dsw-alias-bg-base) 60%, transparent) 55%, transparent 100%);
|
|
1864
|
+
animation: dsh-mtc-sweep 2.6s ease-out infinite;
|
|
1865
|
+
pointer-events: none;
|
|
1866
|
+
}
|
|
1867
|
+
@keyframes dsh-mtc-sweep {
|
|
1868
|
+
0% { left: -300px; }
|
|
1869
|
+
90%, 100% { left: 100%; }
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
.mtc-title { font-weight: 400; }
|
|
1873
|
+
.mtc-sep { flex: none; width: 2px; height: 2px; border-radius: 1px; margin: 0 8px; background: var(--dsw-alias-label-caption); }
|
|
1874
|
+
.mtc-summary {
|
|
1875
|
+
flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
1876
|
+
font-size: 14px; line-height: 24px; color: var(--dsw-alias-label-tertiary);
|
|
1877
|
+
}
|
|
1878
|
+
.mtc-summary-link {
|
|
1879
|
+
flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
1880
|
+
margin: 0; padding: 0; border: none; background: none; font: inherit; text-align: left;
|
|
1881
|
+
font-size: 14px; line-height: 24px; color: var(--dsw-alias-label-secondary);
|
|
1882
|
+
text-decoration: underline; text-decoration-color: var(--dsw-alias-label-quaternary);
|
|
1883
|
+
text-underline-offset: 3px; cursor: pointer;
|
|
1884
|
+
}
|
|
1885
|
+
.mtc-summary-link:hover { color: var(--dsw-alias-label-primary); text-decoration-color: currentColor; }
|
|
1886
|
+
.mtc-summary-error { color: var(--dsw-alias-state-error-primary); }
|
|
1887
|
+
.mtc-summary-suffix { flex: none; margin-left: 4px; white-space: nowrap; font-size: 14px; line-height: 24px; color: var(--dsw-alias-label-tertiary); }
|
|
1888
|
+
|
|
1889
|
+
.mtc-card-body { margin: 4px 0 4px 4px; min-width: 0; }
|
|
1890
|
+
.mtc-recovery { margin: 4px 0 4px 4px; white-space: pre-wrap; overflow-wrap: anywhere; font: var(--dsw-font-xs-13); color: var(--dsw-alias-label-tertiary); }
|
|
1891
|
+
/* IN/OUT text card for calls without a card primitive (mirrors ToolRow). */
|
|
1892
|
+
.mtc-io-card {
|
|
1893
|
+
display: flex; flex-direction: column; min-width: 0;
|
|
1894
|
+
border: 1px solid var(--dsw-alias-border-l2); border-radius: 12px;
|
|
1895
|
+
background: var(--dsw-alias-bg-base);
|
|
1896
|
+
}
|
|
1897
|
+
.mtc-io-section { display: flex; gap: 10px; padding: 8px 12px; min-width: 0; }
|
|
1898
|
+
.mtc-io-label {
|
|
1899
|
+
flex: none; font-size: 11px; line-height: 16px; font-weight: 600;
|
|
1900
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1901
|
+
}
|
|
1902
|
+
.mtc-io-text {
|
|
1903
|
+
flex: 1 1 auto; min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere;
|
|
1904
|
+
font-size: 13px; line-height: 20px; color: var(--dsw-alias-label-secondary);
|
|
1905
|
+
}
|
|
1906
|
+
.mtc-io-text[data-error] { color: var(--dsw-alias-state-error-primary); }
|
|
1907
|
+
.mtc-io-divider { height: 1px; background: var(--dsw-alias-border-l2); }
|
|
1908
|
+
.mtc-inspect {
|
|
1909
|
+
display: inline-flex; align-self: flex-start; align-items: center; gap: 4px;
|
|
1910
|
+
margin: 4px 0 2px 4px; padding: 2px 8px;
|
|
1911
|
+
border: 1px solid var(--dsw-alias-border-l2); border-radius: 999px;
|
|
1912
|
+
background: var(--dsw-alias-bg-base); color: var(--dsw-alias-label-secondary);
|
|
1913
|
+
font-size: 11px; line-height: 16px; cursor: pointer;
|
|
1914
|
+
opacity: 0; transition: opacity 100ms ease;
|
|
1915
|
+
}
|
|
1916
|
+
.mtc-root:hover .mtc-inspect, .mtc-inspect:focus-visible { opacity: 1; }
|
|
1917
|
+
.mtc-inspect:hover { background: var(--dsw-alias-interactive-bg-hover-solid); color: var(--dsw-alias-label-primary); }
|
|
1918
|
+
|
|
1919
|
+
/* Compact child rows: each is the main row's tail structure — [sep dot][path].
|
|
1920
|
+
The dot/path column is set at runtime by the component (it measures the
|
|
1921
|
+
main row's sep offset and sets the --mtc-sep-left custom property on the
|
|
1922
|
+
root); this is only the pre-measure fallback.
|
|
1923
|
+
|
|
1924
|
+
The .mtc-children-collapse wrapper animates the block's height with a
|
|
1925
|
+
grid-template-rows 0fr↔1fr transition (children stay in the DOM while
|
|
1926
|
+
collapsing, so the slide is smooth instead of popping out). The vertical
|
|
1927
|
+
margin lives on the wrapper (not .mtc-children) so it doesn't leak past the
|
|
1928
|
+
0fr row when collapsed.
|
|
1929
|
+
|
|
1930
|
+
The sep-left indent lives on .mtc-child-row (not .mtc-children) so the
|
|
1931
|
+
expanded .mtc-child-body can align back to the root's left edge via a plain
|
|
1932
|
+
4px margin. When the indent was on .mtc-children + a negative-margin
|
|
1933
|
+
pull-back on .mtc-child-body, the body's left portion was clipped by
|
|
1934
|
+
.mtc-children's overflow:hidden (which is required for the grid collapse
|
|
1935
|
+
animation). */
|
|
1936
|
+
.mtc-children-collapse {
|
|
1937
|
+
display: grid;
|
|
1938
|
+
grid-template-rows: 0fr;
|
|
1939
|
+
margin: 0;
|
|
1940
|
+
transition: grid-template-rows 200ms ease-out, margin 200ms ease-out;
|
|
1941
|
+
}
|
|
1942
|
+
.mtc-children-collapse[data-open] {
|
|
1943
|
+
grid-template-rows: 1fr;
|
|
1944
|
+
margin: 2px 0;
|
|
1945
|
+
}
|
|
1946
|
+
.mtc-children {
|
|
1947
|
+
display: flex; flex-direction: column; gap: 1px;
|
|
1948
|
+
margin: 0;
|
|
1949
|
+
min-width: 0; min-height: 0; overflow: hidden;
|
|
1950
|
+
opacity: 0;
|
|
1951
|
+
transition: opacity 150ms ease-out;
|
|
1952
|
+
}
|
|
1953
|
+
.mtc-children-collapse[data-open] .mtc-children {
|
|
1954
|
+
opacity: 1;
|
|
1955
|
+
transition: opacity 150ms ease-out 50ms;
|
|
1956
|
+
}
|
|
1957
|
+
.mtc-child { display: flex; flex-direction: column; min-width: 0; }
|
|
1958
|
+
.mtc-child-row {
|
|
1959
|
+
display: flex; align-items: center; gap: 0; min-width: 0; height: 20px;
|
|
1960
|
+
margin: 0 0 0 var(--mtc-sep-left, 61px); padding: 0; border: 0; border-radius: 4px; background: none;
|
|
1961
|
+
font: inherit; text-align: left; color: var(--dsw-alias-label-secondary); cursor: pointer;
|
|
1962
|
+
}
|
|
1963
|
+
.mtc-child-row:hover { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }
|
|
1964
|
+
.mtc-child-row[data-static] { cursor: default; }
|
|
1965
|
+
.mtc-child-row[data-static]:hover { background: none; color: var(--dsw-alias-label-secondary); }
|
|
1966
|
+
.mtc-child-row .mtc-sep { margin: 0 8px 0 0; }
|
|
1967
|
+
.mtc-child-path {
|
|
1968
|
+
flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
1969
|
+
font-size: 14px; line-height: 20px;
|
|
1970
|
+
}
|
|
1971
|
+
/* Read-family child paths are open-file links (sidebar preview), same affordance
|
|
1972
|
+
as the main row's summary link. */
|
|
1973
|
+
.mtc-child-path-link {
|
|
1974
|
+
flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
1975
|
+
margin: 0; padding: 0; border: none; background: none; font: inherit; text-align: left;
|
|
1976
|
+
font-size: 14px; line-height: 20px; color: var(--dsw-alias-label-secondary);
|
|
1977
|
+
text-decoration: underline; text-decoration-color: var(--dsw-alias-label-quaternary);
|
|
1978
|
+
text-underline-offset: 3px; cursor: pointer;
|
|
1979
|
+
}
|
|
1980
|
+
.mtc-child-path-link:hover { color: var(--dsw-alias-label-primary); text-decoration-color: currentColor; }
|
|
1981
|
+
.mtc-child-state { flex: none; font-size: 11px; line-height: 16px; color: var(--dsw-alias-label-tertiary); }
|
|
1982
|
+
.mtc-child-state[data-error] { color: var(--dsw-alias-state-error-primary); }
|
|
1983
|
+
/* The expanded child card aligns to the main card body's column (root + 4px).
|
|
1984
|
+
No negative-margin pull-back is needed because .mtc-children no longer
|
|
1985
|
+
carries the sep-left indent — only .mtc-child-row does. */
|
|
1986
|
+
.mtc-child-body { margin: 2px 0 2px 4px; min-width: 0; }
|
|
1987
|
+
|
|
1988
|
+
.mtc-visually-hidden {
|
|
1989
|
+
position: absolute; width: 1px; height: 1px; overflow: hidden;
|
|
1990
|
+
clip: rect(0 0 0 0); white-space: nowrap;
|
|
1991
|
+
}
|
|
1992
|
+
`;
|
|
1993
|
+
/** Install the stylesheet and return its disposer. */
|
|
1994
|
+
function installStyles() {
|
|
1995
|
+
const style = document.createElement("style");
|
|
1996
|
+
style.setAttribute("data-merge-tool-calls-style", "");
|
|
1997
|
+
style.textContent = CSS;
|
|
1998
|
+
document.head.appendChild(style);
|
|
1999
|
+
return () => {
|
|
2000
|
+
style.remove();
|
|
2001
|
+
};
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
//#endregion
|
|
2005
|
+
//#region src/client/index.ts
|
|
2006
|
+
/** Required services: the slot registry (toolview shadowing) and locale. */
|
|
2007
|
+
const inject = ["slots", "locale"];
|
|
2008
|
+
/**
|
|
2009
|
+
* Register one shadowed toolview per grouped tool.
|
|
2010
|
+
* @param ctx - client root context.
|
|
2011
|
+
* @param config - row config; defaults apply when the loader passes none.
|
|
2012
|
+
*/
|
|
2013
|
+
function apply(ctx, config = {}) {
|
|
2014
|
+
const cfg = {
|
|
2015
|
+
...DEFAULT_MERGE_CONFIG,
|
|
2016
|
+
...config
|
|
2017
|
+
};
|
|
2018
|
+
ctx.effect(() => ctx.locale.register(NS, {
|
|
2019
|
+
zh,
|
|
2020
|
+
en
|
|
2021
|
+
}), "merge-tool-calls: dictionaries");
|
|
2022
|
+
ctx.effect(installStyles, "merge-tool-calls: styles");
|
|
2023
|
+
ctx.effect(() => {
|
|
2024
|
+
let dispose;
|
|
2025
|
+
const sync = () => {
|
|
2026
|
+
dispose?.();
|
|
2027
|
+
dispose = void 0;
|
|
2028
|
+
const store = ctx.get("betterLocale");
|
|
2029
|
+
if (store !== void 0) dispose = store.register(NS, dicts);
|
|
2030
|
+
};
|
|
2031
|
+
sync();
|
|
2032
|
+
const unsubscribe = ctx.locale.subscribe(sync);
|
|
2033
|
+
return () => {
|
|
2034
|
+
unsubscribe();
|
|
2035
|
+
dispose?.();
|
|
2036
|
+
};
|
|
2037
|
+
}, "merge-tool-calls: better-locale override dicts");
|
|
2038
|
+
const toolNames = cfg.tools.length === 0 ? ALL_TOOL_NAMES : [...new Set(cfg.tools)];
|
|
2039
|
+
for (const tool of toolNames) ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
|
|
2040
|
+
name: "tool.call.toolview",
|
|
2041
|
+
key: tool,
|
|
2042
|
+
priority: -1,
|
|
2043
|
+
locale: NS,
|
|
2044
|
+
inject: () => ({ cfg })
|
|
2045
|
+
}, MergedToolRow));
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
//#endregion
|
|
2049
|
+
exports.apply = apply;
|
|
2050
|
+
exports.inject = inject;
|
|
2051
|
+
return module.exports; } });
|
|
1638
2052
|
//# sourceMappingURL=client.js.map
|